@@ -758,30 +758,44 @@ lys_parse_localfile(struct ly_ctx *ctx, const char *name, const char *revision,
758758 * @return LY_ERR on error.
759759 */
760760static LY_ERR
761- lys_parse_load_from_clb_or_file (struct ly_ctx * ctx , const char * name , const char * revision ,
761+ lys_load_mod_from_clb_or_file (struct ly_ctx * ctx , const char * name , const char * revision ,
762762 struct lys_module * mod_latest , struct ly_set * new_mods , struct lys_module * * mod )
763763{
764764 LY_ERR r ;
765765 const char * module_data = NULL ;
766766 LYS_INFORMAT format = LYS_IN_UNKNOWN ;
767+ ly_bool clb_used , searchdirs_used ;
767768
768769 void (* module_data_free )(void * module_data , void * user_data ) = NULL ;
769770 struct lysp_load_module_data mod_data = {0 };
770771 struct ly_in * in ;
771772
772773 * mod = NULL ;
773774
774- if (mod_latest && (!ctx -> imp_clb || (mod_latest -> latest_revision & LYS_MOD_LATEST_IMPCLB )) &&
775- ((ctx -> flags & LY_CTX_DISABLE_SEARCHDIRS ) || (mod_latest -> latest_revision & LYS_MOD_LATEST_SEARCHDIRS ))) {
776- /* we are not able to find a newer revision */
777- return LY_SUCCESS ;
775+ if (!ctx -> imp_clb ) {
776+ /* no callback to call */
777+ clb_used = 1 ;
778+ } else if (mod_latest && (mod_latest -> latest_revision & LYS_MOD_LATEST_IMPCLB )) {
779+ /* already have the latest revision returned by the callback */
780+ clb_used = 1 ;
781+ } else {
782+ clb_used = 0 ;
783+ }
784+
785+ if (ctx -> flags & LY_CTX_DISABLE_SEARCHDIRS ) {
786+ /* searchdirs disabled */
787+ searchdirs_used = 1 ;
788+ } else if (mod_latest && (mod_latest -> latest_revision & LYS_MOD_LATEST_SEARCHDIRS )) {
789+ /* already have the latest revision found in the searchdirs */
790+ searchdirs_used = 1 ;
791+ } else {
792+ searchdirs_used = 0 ;
778793 }
779794
780- if (!(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS )) {
781- search_clb :
782- /* check there is a callback and should be called */
783- if (ctx -> imp_clb && (!mod_latest || !(mod_latest -> latest_revision & LYS_MOD_LATEST_IMPCLB ))) {
795+ while (!* mod && (!clb_used || !searchdirs_used )) {
796+ if ((!(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS ) || searchdirs_used ) && !clb_used ) {
784797 if (!ctx -> imp_clb (name , revision , NULL , NULL , ctx -> imp_clb_data , & format , & module_data , & module_data_free )) {
798+ /* parse the module returned by the callback */
785799 LY_CHECK_RET (ly_in_new_memory (module_data , & in ));
786800 mod_data .name = name ;
787801 mod_data .revision = revision ;
@@ -792,25 +806,20 @@ lys_parse_load_from_clb_or_file(struct ly_ctx *ctx, const char *name, const char
792806 }
793807 LY_CHECK_RET (r );
794808 }
795- }
796- if (* mod && !revision ) {
797- /* we got the latest revision module from the callback */
798- (* mod )-> latest_revision |= LYS_MOD_LATEST_IMPCLB ;
799- } else if (!* mod && !(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS )) {
800- goto search_file ;
801- }
802- } else {
803- search_file :
804- /* check we can use searchdirs and that we should */
805- if (!(ctx -> flags & LY_CTX_DISABLE_SEARCHDIRS ) &&
806- (!mod_latest || !(mod_latest -> latest_revision & LYS_MOD_LATEST_SEARCHDIRS ))) {
809+ clb_used = 1 ;
810+
811+ if (* mod && !revision ) {
812+ /* we got the latest revision module from the callback */
813+ (* mod )-> latest_revision |= LYS_MOD_LATEST_IMPCLB ;
814+ }
815+ } else if (!searchdirs_used ) {
807816 LY_CHECK_RET (lys_parse_localfile (ctx , name , revision , NULL , NULL , new_mods , (void * * )mod ));
808- }
809- if ( * mod && ! revision ) {
810- /* we got the latest revision module in the searchdirs */
811- ( * mod ) -> latest_revision |= LYS_MOD_LATEST_IMPCLB ;
812- } else if (! * mod && ( ctx -> flags & LY_CTX_PREFER_SEARCHDIRS )) {
813- goto search_clb ;
817+ searchdirs_used = 1 ;
818+
819+ if ( * mod && ! revision ) {
820+ /* we got the latest revision module in the searchdirs */
821+ ( * mod ) -> latest_revision |= LYS_MOD_LATEST_SEARCHDIRS ;
822+ }
814823 }
815824 }
816825
@@ -912,7 +921,7 @@ lys_parse_load(struct ly_ctx *ctx, const char *name, const char *revision, struc
912921
913922 if (!* mod ) {
914923 /* No suitable module in the context, try to load it. */
915- LY_CHECK_RET (lys_parse_load_from_clb_or_file (ctx , name , revision , mod_latest , new_mods , mod ));
924+ LY_CHECK_RET (lys_load_mod_from_clb_or_file (ctx , name , revision , mod_latest , new_mods , mod ));
916925
917926 /* Update the latest_revision flag - here we have selected the latest available schema,
918927 * consider that even the callback provides correct latest revision.
@@ -1105,11 +1114,91 @@ lysp_inject_submodule(struct lysp_ctx *pctx, struct lysp_include *inc)
11051114 return LY_SUCCESS ;
11061115}
11071116
1117+ /**
1118+ * @brief Load submodule from searchdirs or from callback.
1119+ *
1120+ * @param[in] pctx Parser context to use.
1121+ * @param[in] name Name of submodule to load.
1122+ * @param[in] revision Revision of submodule to load.
1123+ * @param[in,out] new_mods Set of all the new mods added to the context. Includes this submodule and all of its imports.
1124+ * @param[out] submod Loaded submodule.
1125+ * @return LY_SUCCESS on success.
1126+ * @return LY_ERR on error.
1127+ */
1128+ static LY_ERR
1129+ lysp_load_submod_from_clb_or_file (struct lysp_ctx * pctx , const char * name , const char * revision ,
1130+ struct ly_set * new_mods , struct lysp_submodule * * submod )
1131+ {
1132+ LY_ERR r ;
1133+ struct ly_ctx * ctx = PARSER_CTX (pctx );
1134+ ly_bool clb_used , searchdirs_used ;
1135+ const char * submodule_data = NULL ;
1136+ LYS_INFORMAT format = LYS_IN_UNKNOWN ;
1137+
1138+ void (* submodule_data_free )(void * module_data , void * user_data ) = NULL ;
1139+ struct lysp_load_module_data mod_data = {0 };
1140+ struct ly_in * in ;
1141+
1142+ * submod = NULL ;
1143+
1144+ if (!ctx -> imp_clb ) {
1145+ /* no callback to call */
1146+ clb_used = 1 ;
1147+ } else {
1148+ clb_used = 0 ;
1149+ }
1150+
1151+ if (ctx -> flags & LY_CTX_DISABLE_SEARCHDIRS ) {
1152+ /* searchdirs disabled */
1153+ searchdirs_used = 1 ;
1154+ } else {
1155+ searchdirs_used = 0 ;
1156+ }
1157+
1158+ while (!* submod && (!clb_used || !searchdirs_used )) {
1159+ if ((!(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS ) || searchdirs_used ) && !clb_used ) {
1160+ if (!ctx -> imp_clb (PARSER_CUR_PMOD (pctx )-> mod -> name , NULL , name , revision , ctx -> imp_clb_data , & format ,
1161+ & submodule_data , & submodule_data_free )) {
1162+ /* parse the submodule returned by the callback */
1163+ LY_CHECK_RET (ly_in_new_memory (submodule_data , & in ));
1164+ mod_data .name = name ;
1165+ mod_data .revision = revision ;
1166+ mod_data .submoduleof = PARSER_CUR_PMOD (pctx )-> mod -> name ;
1167+ r = lys_parse_submodule (ctx , in , format , pctx -> main_ctx , & mod_data , new_mods , submod );
1168+ ly_in_free (in , 0 );
1169+ if (submodule_data_free ) {
1170+ submodule_data_free ((void * )submodule_data , ctx -> imp_clb_data );
1171+ }
1172+ LY_CHECK_RET (r );
1173+ }
1174+ clb_used = 1 ;
1175+ } else if (!searchdirs_used ) {
1176+ LY_CHECK_RET (lys_parse_localfile (ctx , name , revision , pctx -> main_ctx ,
1177+ PARSER_CUR_PMOD (pctx -> main_ctx )-> mod -> name , new_mods , (void * * )submod ));
1178+ searchdirs_used = 1 ;
1179+ }
1180+ }
1181+
1182+ if (!* submod ) {
1183+ LOGVAL (ctx , LYVE_REFERENCE , "Including \"%s\" submodule into \"%s\" failed, not found." , name ,
1184+ PARSER_CUR_PMOD (pctx )-> is_submod ? ((struct lysp_submodule * )PARSER_CUR_PMOD (pctx ))-> name :
1185+ PARSER_CUR_PMOD (pctx )-> mod -> name );
1186+ return LY_ENOTFOUND ;
1187+ }
1188+
1189+ if (!revision && ((* submod )-> latest_revision == 1 )) {
1190+ /* update the latest_revision flag - here we have selected the latest available schema,
1191+ * consider that even the callback provides correct latest revision */
1192+ (* submod )-> latest_revision = 2 ;
1193+ }
1194+
1195+ return LY_SUCCESS ;
1196+ }
1197+
11081198LY_ERR
11091199lysp_load_submodules (struct lysp_ctx * pctx , struct lysp_module * pmod , struct ly_set * new_mods )
11101200{
11111201 LY_ERR r ;
1112- struct ly_ctx * ctx = PARSER_CTX (pctx );
11131202 struct lysp_submodule * submod ;
11141203 struct lysp_include * inc ;
11151204 LY_ARRAY_COUNT_TYPE u ;
@@ -1137,71 +1226,17 @@ lysp_load_submodules(struct lysp_ctx *pctx, struct lysp_module *pmod, struct ly_
11371226 r = lysp_parsed_mods_get_submodule (pctx , inc );
11381227 LY_CHECK_RET (r != LY_ENOT , r );
11391228
1140- /* submodule not present in the main module, get the input data and parse it */
1141- if (!(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS )) {
1142- search_clb :
1143- if (ctx -> imp_clb ) {
1144- const char * submodule_data = NULL ;
1145- LYS_INFORMAT format = LYS_IN_UNKNOWN ;
1146-
1147- void (* submodule_data_free )(void * module_data , void * user_data ) = NULL ;
1148- struct lysp_load_module_data mod_data = {0 };
1149- struct ly_in * in ;
1150-
1151- if (ctx -> imp_clb (PARSER_CUR_PMOD (pctx )-> mod -> name , NULL , inc -> name , inc -> rev [0 ] ? inc -> rev : NULL ,
1152- ctx -> imp_clb_data , & format , & submodule_data , & submodule_data_free ) == LY_SUCCESS ) {
1153- LY_CHECK_RET (ly_in_new_memory (submodule_data , & in ));
1154- mod_data .name = inc -> name ;
1155- mod_data .revision = inc -> rev [0 ] ? inc -> rev : NULL ;
1156- mod_data .submoduleof = PARSER_CUR_PMOD (pctx )-> mod -> name ;
1157- r = lys_parse_submodule (ctx , in , format , pctx -> main_ctx , & mod_data , new_mods , & submod );
1158- ly_in_free (in , 0 );
1159- if (submodule_data_free ) {
1160- submodule_data_free ((void * )submodule_data , ctx -> imp_clb_data );
1161- }
1162- LY_CHECK_RET (r );
1229+ /* try to load the submodule */
1230+ LY_CHECK_RET (lysp_load_submod_from_clb_or_file (pctx , inc -> name , inc -> rev [0 ] ? inc -> rev : NULL , new_mods , & submod ));
11631231
1164- /* update inc pointer - parsing another (YANG 1.0) submodule can cause injecting
1165- * submodule's include into main module, where it is missing */
1166- inc = & pmod -> includes [u ];
1167- }
1168- }
1169- if (!submod && !(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS )) {
1170- goto search_file ;
1171- }
1172- } else {
1173- search_file :
1174- if (!(ctx -> flags & LY_CTX_DISABLE_SEARCHDIRS )) {
1175- /* submodule was not received from the callback or there is no callback set */
1176- LY_CHECK_RET (lys_parse_localfile (ctx , inc -> name , inc -> rev [0 ] ? inc -> rev : NULL , pctx -> main_ctx ,
1177- PARSER_CUR_PMOD (pctx -> main_ctx )-> mod -> name , new_mods , (void * * )& submod ));
1178-
1179- /* update inc pointer - parsing another (YANG 1.0) submodule can cause injecting
1180- * submodule's include into main module, where it is missing */
1181- inc = & pmod -> includes [u ];
1182- }
1183- if (!submod && (ctx -> flags & LY_CTX_PREFER_SEARCHDIRS )) {
1184- goto search_clb ;
1185- }
1186- }
1187- if (submod ) {
1188- if (!inc -> rev [0 ] && (submod -> latest_revision == 1 )) {
1189- /* update the latest_revision flag - here we have selected the latest available schema,
1190- * consider that even the callback provides correct latest revision */
1191- submod -> latest_revision = 2 ;
1192- }
1232+ /* update inc pointer - parsing another (YANG 1.0) submodule can cause injecting
1233+ * submodule's include into main module, where it is missing */
1234+ inc = & pmod -> includes [u ];
1235+ inc -> submodule = submod ;
11931236
1194- inc -> submodule = submod ;
1195- if (!submod_included ) {
1196- /* the submodule include is not present in YANG 1.0 main module - add it there */
1197- LY_CHECK_RET (lysp_inject_submodule (pctx , & pmod -> includes [u ]));
1198- }
1199- }
1200- if (!inc -> submodule ) {
1201- LOGVAL (ctx , LYVE_REFERENCE , "Including \"%s\" submodule into \"%s\" failed." , inc -> name ,
1202- PARSER_CUR_PMOD (pctx )-> is_submod ? ((struct lysp_submodule * )PARSER_CUR_PMOD (pctx ))-> name :
1203- PARSER_CUR_PMOD (pctx )-> mod -> name );
1204- return LY_EVALID ;
1237+ if (!submod_included ) {
1238+ /* the submodule include is not present in YANG 1.0 main module - add it there */
1239+ LY_CHECK_RET (lysp_inject_submodule (pctx , & pmod -> includes [u ]));
12051240 }
12061241 }
12071242
0 commit comments