4242
4343struct repo_state {
4444 int lockfd ;
45+ bool changed ;
4546 const char * repodir ;
4647 const char * arch ;
4748 struct xbps_repo * repo ;
4849 xbps_dictionary_t index ;
4950 xbps_dictionary_t stage ;
5051 xbps_dictionary_t meta ;
52+ xbps_array_t added ;
5153};
5254
5355struct shared_state {
@@ -326,6 +328,12 @@ index_add_pkg(struct repo_state *state, const char *file, bool force)
326328 goto err ;
327329 }
328330
331+ state -> changed = true;
332+ if (!xbps_array_add_cstring (state -> added , pkgname )) {
333+ r = xbps_error_oom ();
334+ goto err ;
335+ }
336+
329337 r = 0 ;
330338err :
331339 xbps_object_release (binpkgd );
@@ -371,26 +379,44 @@ repo_add_package(
371379static int
372380repo_state_open (struct xbps_handle * xhp , struct repo_state * state , const char * repodir , const char * arch )
373381{
382+ state -> changed = false;
374383 state -> repodir = repodir ;
375384 state -> arch = arch ;
376385 state -> lockfd = xbps_repo_lock (state -> repodir , arch );
377386 if (state -> lockfd < 0 ) {
378387 xbps_error_printf (
379388 "failed to lock repository: %s: %s\n" ,
380389 state -> repodir , strerror (- state -> lockfd ));
381- return EXIT_FAILURE ;
390+ return - state -> lockfd ;
382391 }
392+
393+ state -> added = xbps_array_create ();
394+ if (!state -> added )
395+ return xbps_error_oom ();
396+
383397 state -> repo = xbps_repo_open (xhp , repodir );
384398 if (!state -> repo ) {
385399 if (errno != ENOENT )
386- return EXIT_FAILURE ;
400+ return - errno ;
387401 state -> index = xbps_dictionary_create ();
402+ if (!state -> index )
403+ return xbps_error_oom ();
388404 state -> stage = xbps_dictionary_create ();
405+ if (!state -> stage )
406+ return xbps_error_oom ();
389407 state -> meta = NULL ;
390408 } else {
391409 state -> index = xbps_dictionary_copy_mutable (state -> repo -> index );
410+ if (!state -> index )
411+ return xbps_error_oom ();
392412 state -> stage = xbps_dictionary_copy_mutable (state -> repo -> stage );
393- state -> meta = xbps_dictionary_copy_mutable (state -> repo -> idxmeta );
413+ if (!state -> stage )
414+ return xbps_error_oom ();
415+ if (state -> repo -> idxmeta ) {
416+ state -> meta = xbps_dictionary_copy_mutable (state -> repo -> idxmeta );
417+ if (!state -> meta )
418+ return xbps_error_oom ();
419+ }
394420 }
395421 return 0 ;
396422}
@@ -445,27 +471,22 @@ print_inconsistent_shlibs(struct shared_state *shared)
445471static int
446472print_staged_packages (struct repo_state * states , unsigned nstates )
447473{
448- xbps_object_iterator_t iter ;
449- xbps_object_t keysym ;
450-
451- // XXX: should this really print all staged packages every time?
452-
453474 for (unsigned int i = 0 ; i < nstates ; i ++ ) {
454475 const struct repo_state * state = & states [i ];
455476
456- iter = xbps_dictionary_iterator (state -> stage );
457- if (!iter )
458- return xbps_error_oom ();
459-
460- while ((keysym = xbps_object_iterator_next (iter ))) {
461- xbps_dictionary_t pkg = xbps_dictionary_get_keysym (state -> stage , keysym );
462- const char * pkgver = NULL , * arch = NULL ;
463- xbps_dictionary_get_cstring_nocopy (pkg , "pkgver" , & pkgver );
464- xbps_dictionary_get_cstring_nocopy (pkg , "architecture" , & arch );
477+ for (unsigned int j = 0 ; j < xbps_array_count (state -> added ); j ++ ) {
478+ xbps_dictionary_t pkg ;
479+ const char * pkgname = NULL , * pkgver = NULL , * arch = NULL ;
480+ if (!xbps_array_get_cstring_nocopy (state -> added , j , & pkgname ))
481+ abort ();
482+ if (!xbps_dictionary_get_dict (state -> stage , pkgname , & pkg ))
483+ abort ();
484+ if (!xbps_dictionary_get_cstring_nocopy (pkg , "pkgver" , & pkgver ))
485+ abort ();
486+ if (!xbps_dictionary_get_cstring_nocopy (pkg , "architecture" , & arch ))
487+ abort ();
465488 printf ("%s: stage: added `%s' (%s)\n" , state -> repodir , pkgver , arch );
466489 }
467-
468- xbps_object_iterator_release (iter );
469490 }
470491
471492 return 0 ;
@@ -477,6 +498,9 @@ unstage(struct repo_state *state)
477498 xbps_object_iterator_t iter ;
478499 xbps_object_t keysym ;
479500
501+ if (xbps_dictionary_count (state -> stage ) == 0 )
502+ return 0 ;
503+
480504 iter = xbps_dictionary_iterator (state -> stage );
481505 if (!iter )
482506 return xbps_error_oom ();
@@ -503,6 +527,7 @@ unstage(struct repo_state *state)
503527
504528 xbps_object_release (state -> stage );
505529 state -> stage = NULL ;
530+ state -> changed = true;
506531
507532 return 0 ;
508533}
@@ -561,6 +586,8 @@ commit(struct repo_state *states, unsigned nstates)
561586
562587 for (unsigned i = 0 ; i < nstates ; i ++ ) {
563588 struct repo_state * state = & states [i ];
589+ if (!state -> changed )
590+ continue ;
564591 printf ("%s: index: %u packages registered.\n" ,
565592 state -> repodir , xbps_dictionary_count (state -> index ));
566593 if (xbps_dictionary_count (state -> stage ) != 0 ) {
0 commit comments