@@ -751,38 +751,77 @@ ly_ctx_get_modules_hash(const struct ly_ctx *ctx)
751751 return ctx -> mod_hash ;
752752}
753753
754+ /**
755+ * @brief qsort() alphabetical compare of modules.
756+ */
757+ static int
758+ ly_ctx_mod_cmp_cb (const void * ptr1 , const void * ptr2 )
759+ {
760+ const struct lys_module * mod1 , * mod2 ;
761+ int r ;
762+
763+ mod1 = * (struct lys_module * * )ptr1 ;
764+ mod2 = * (struct lys_module * * )ptr2 ;
765+
766+ /* module name */
767+ r = strcmp (mod1 -> name , mod2 -> name );
768+ if (!r ) {
769+ /* revision */
770+ if (mod1 -> revision && !mod2 -> revision ) {
771+ r = 1 ;
772+ } else if (!mod1 -> revision && mod2 -> revision ) {
773+ r = -1 ;
774+ } else if (mod1 -> revision && mod2 -> revision ) {
775+ r = strcmp (mod1 -> revision , mod2 -> revision );
776+ }
777+ }
778+
779+ return r ;
780+ }
781+
754782void
755783ly_ctx_new_change (struct ly_ctx * ctx )
756784{
757- const struct lys_module * mod ;
758- uint32_t i = ly_ctx_internal_modules_count ( ctx ), hash = 0 ;
785+ uint32_t i , hash = 0 ;
786+ const struct lys_module * * mods = NULL ;
759787 LY_ARRAY_COUNT_TYPE u ;
760788
761789 /* change counter */
762790 ctx -> change_count ++ ;
763791
764- /* module hash */
765- while ((mod = ly_ctx_get_module_iter (ctx , & i ))) {
792+ /* collect modules into an array */
793+ mods = malloc (ctx -> modules .count * sizeof * mods );
794+ LY_CHECK_ERR_GOTO (!mods , LOGMEM (ctx ), cleanup );
795+ memcpy (mods , ctx -> modules .objs , ctx -> modules .count * sizeof * mods );
796+
797+ /* sort modules alphabetically */
798+ qsort (mods , ctx -> modules .count , sizeof * mods , ly_ctx_mod_cmp_cb );
799+
800+ /* calculate module hash */
801+ for (i = 0 ; i < ctx -> modules .count ; ++ i ) {
766802 /* name */
767- hash = lyht_hash_multi (hash , mod -> name , strlen (mod -> name ));
803+ hash = lyht_hash_multi (hash , mods [ i ] -> name , strlen (mods [ i ] -> name ));
768804
769805 /* revision */
770- if (mod -> revision ) {
771- hash = lyht_hash_multi (hash , mod -> revision , strlen (mod -> revision ));
806+ if (mods [ i ] -> revision ) {
807+ hash = lyht_hash_multi (hash , mods [ i ] -> revision , strlen (mods [ i ] -> revision ));
772808 }
773809
774810 /* enabled features */
775- if (mod -> implemented ) {
776- LY_ARRAY_FOR (mod -> compiled -> features , u ) {
777- hash = lyht_hash_multi (hash , mod -> compiled -> features [u ], strlen (mod -> compiled -> features [u ]));
811+ if (mods [ i ] -> implemented ) {
812+ LY_ARRAY_FOR (mods [ i ] -> compiled -> features , u ) {
813+ hash = lyht_hash_multi (hash , mods [ i ] -> compiled -> features [u ], strlen (mods [ i ] -> compiled -> features [u ]));
778814 }
779815 }
780816
781817 /* imported/implemented */
782- hash = lyht_hash_multi (hash , (char * )& mod -> implemented , sizeof mod -> implemented );
818+ hash = lyht_hash_multi (hash , (char * )& mods [ i ] -> implemented , sizeof mods [ i ] -> implemented );
783819 }
784820
785821 ctx -> mod_hash = lyht_hash_multi (hash , NULL , 0 );
822+
823+ cleanup :
824+ free (mods );
786825}
787826
788827LIBYANG_API_DEF ly_module_imp_clb
0 commit comments