@@ -697,14 +697,15 @@ lysp_check_dup_identities(struct lysp_ctx *ctx, struct lysp_module *mod)
697697 * @param[in] main_ctx Parser context of the main module in case of loading submodule.
698698 * @param[in] main_name Main module name in case of loading submodule.
699699 * @param[in,out] new_mods Set of all the new mods added to the context. Includes this module and all of its imports.
700- * @param[out] result Parsed YANG schema tree of the requested module (struct lys_module*) or submodule (struct lysp_submodule*).
701- * If it is a module, it is already in the context!
700+ * @param[out] found Whether any (sub)module was found.
701+ * @param[out] result Parsed YANG schema tree of the requested module (struct lys_module *) or submodule
702+ * (struct lysp_submodule *). If a module, it has already been inserted into the context.
702703 * @return LY_SUCCESS on success.
703704 * @return LY_ERR on error.
704705 */
705706static LY_ERR
706707lys_parse_localfile (struct ly_ctx * ctx , const char * name , const char * revision , struct lysp_ctx * main_ctx ,
707- const char * main_name , struct ly_set * new_mods , void * * result )
708+ const char * main_name , struct ly_set * new_mods , ly_bool * found , void * * result )
708709{
709710 struct ly_in * in ;
710711 char * filepath = NULL ;
@@ -713,6 +714,7 @@ lys_parse_localfile(struct ly_ctx *ctx, const char *name, const char *revision,
713714 LY_ERR ret = LY_SUCCESS ;
714715 struct lysp_load_module_data mod_data = {0 };
715716
717+ * found = 0 ;
716718 * result = NULL ;
717719
718720 LY_CHECK_RET (lys_search_localfile (ly_ctx_get_searchdirs (ctx ), !(ctx -> flags & LY_CTX_DISABLE_SEARCHDIR_CWD ), name ,
@@ -740,6 +742,7 @@ lys_parse_localfile(struct ly_ctx *ctx, const char *name, const char *revision,
740742 ly_in_free (in , 1 );
741743 LY_CHECK_GOTO (ret , cleanup );
742744
745+ * found = 1 ;
743746 * result = mod ;
744747
745748cleanup :
@@ -766,7 +769,7 @@ lys_load_mod_from_clb_or_file(struct ly_ctx *ctx, const char *name, const char *
766769 LY_ERR r ;
767770 const char * module_data = NULL ;
768771 LYS_INFORMAT format = LYS_IN_UNKNOWN ;
769- ly_bool clb_used , searchdirs_used ;
772+ ly_bool clb_used , searchdirs_used , found = 0 ;
770773
771774 void (* module_data_free )(void * module_data , void * user_data ) = NULL ;
772775 struct lysp_load_module_data mod_data = {0 };
@@ -794,7 +797,7 @@ lys_load_mod_from_clb_or_file(struct ly_ctx *ctx, const char *name, const char *
794797 searchdirs_used = 0 ;
795798 }
796799
797- while (!* mod && (!clb_used || !searchdirs_used )) {
800+ while (!found && (!clb_used || !searchdirs_used )) {
798801 if ((!(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS ) || searchdirs_used ) && !clb_used ) {
799802 if (!ctx -> imp_clb (name , revision , NULL , NULL , ctx -> imp_clb_data , & format , & module_data , & module_data_free )) {
800803 /* parse the module returned by the callback */
@@ -807,6 +810,8 @@ lys_load_mod_from_clb_or_file(struct ly_ctx *ctx, const char *name, const char *
807810 module_data_free ((void * )module_data , ctx -> imp_clb_data );
808811 }
809812 LY_CHECK_RET (r );
813+
814+ found = 1 ;
810815 }
811816 clb_used = 1 ;
812817
@@ -815,7 +820,7 @@ lys_load_mod_from_clb_or_file(struct ly_ctx *ctx, const char *name, const char *
815820 (* mod )-> latest_revision |= LYS_MOD_LATEST_IMPCLB ;
816821 }
817822 } else if (!searchdirs_used ) {
818- LY_CHECK_RET (lys_parse_localfile (ctx , name , revision , NULL , NULL , new_mods , (void * * )mod ));
823+ LY_CHECK_RET (lys_parse_localfile (ctx , name , revision , NULL , NULL , new_mods , & found , (void * * )mod ));
819824 searchdirs_used = 1 ;
820825
821826 if (* mod && !revision ) {
@@ -1119,28 +1124,34 @@ lysp_inject_submodule(struct lysp_ctx *pctx, struct lysp_include *inc)
11191124/**
11201125 * @brief Load submodule from searchdirs or from callback.
11211126 *
1127+ * Parsing another (YANG 1.0) submodule can cause inserting submodule's include into the main module moving
1128+ * existing includes (changing any pointers to includes).
1129+ *
11221130 * @param[in] pctx Parser context to use.
11231131 * @param[in] name Name of submodule to load.
11241132 * @param[in] revision Revision of submodule to load.
1133+ * @param[in] submod_latest Submodule with the latest revision found in context, otherwise set to NULL.
11251134 * @param[in,out] new_mods Set of all the new mods added to the context. Includes this submodule and all of its imports.
1126- * @param[out] submod Loaded submodule.
1135+ * @param[out] submod Parsed submodule, may be NULL if an adequate submodule has already been found before .
11271136 * @return LY_SUCCESS on success.
11281137 * @return LY_ERR on error.
11291138 */
11301139static LY_ERR
11311140lysp_load_submod_from_clb_or_file (struct lysp_ctx * pctx , const char * name , const char * revision ,
1132- struct ly_set * new_mods , struct lysp_submodule * * submod )
1141+ struct lysp_submodule * submod_latest , struct ly_set * new_mods , struct lysp_submodule * * submod )
11331142{
11341143 LY_ERR r ;
11351144 struct ly_ctx * ctx = PARSER_CTX (pctx );
1136- ly_bool clb_used , searchdirs_used ;
1145+ ly_bool clb_used , searchdirs_used , found = 0 ;
11371146 const char * submodule_data = NULL ;
11381147 LYS_INFORMAT format = LYS_IN_UNKNOWN ;
11391148
11401149 void (* submodule_data_free )(void * module_data , void * user_data ) = NULL ;
11411150 struct lysp_load_module_data mod_data = {0 };
11421151 struct ly_in * in ;
11431152
1153+ assert (!submod_latest || (submod_latest -> latest_revision != 2 ));
1154+
11441155 * submod = NULL ;
11451156
11461157 if (!ctx -> imp_clb ) {
@@ -1157,7 +1168,7 @@ lysp_load_submod_from_clb_or_file(struct lysp_ctx *pctx, const char *name, const
11571168 searchdirs_used = 0 ;
11581169 }
11591170
1160- while (!* submod && (!clb_used || !searchdirs_used )) {
1171+ while (!found && (!clb_used || !searchdirs_used )) {
11611172 if ((!(ctx -> flags & LY_CTX_PREFER_SEARCHDIRS ) || searchdirs_used ) && !clb_used ) {
11621173 if (!ctx -> imp_clb (PARSER_CUR_PMOD (pctx )-> mod -> name , NULL , name , revision , ctx -> imp_clb_data , & format ,
11631174 & submodule_data , & submodule_data_free )) {
@@ -1172,16 +1183,18 @@ lysp_load_submod_from_clb_or_file(struct lysp_ctx *pctx, const char *name, const
11721183 submodule_data_free ((void * )submodule_data , ctx -> imp_clb_data );
11731184 }
11741185 LY_CHECK_RET (r );
1186+
1187+ found = 1 ;
11751188 }
11761189 clb_used = 1 ;
11771190 } else if (!searchdirs_used ) {
11781191 LY_CHECK_RET (lys_parse_localfile (ctx , name , revision , pctx -> main_ctx ,
1179- PARSER_CUR_PMOD (pctx -> main_ctx )-> mod -> name , new_mods , (void * * )submod ));
1192+ PARSER_CUR_PMOD (pctx -> main_ctx )-> mod -> name , new_mods , & found , (void * * )submod ));
11801193 searchdirs_used = 1 ;
11811194 }
11821195 }
11831196
1184- if (!* submod ) {
1197+ if (!* submod && ! submod_latest ) {
11851198 LOGVAL (ctx , LYVE_REFERENCE , "Including \"%s\" submodule into \"%s\" failed, not found." , name ,
11861199 PARSER_CUR_PMOD (pctx )-> is_submod ? ((struct lysp_submodule * )PARSER_CUR_PMOD (pctx ))-> name :
11871200 PARSER_CUR_PMOD (pctx )-> mod -> name );
@@ -1231,16 +1244,21 @@ lysp_load_submodules(struct lysp_ctx *pctx, struct lysp_module *pmod, struct ly_
12311244 }
12321245
12331246 /* try to load the submodule */
1234- LY_CHECK_RET (lysp_load_submod_from_clb_or_file (pctx , inc -> name , inc -> rev [0 ] ? inc -> rev : NULL , new_mods , & submod ));
1247+ LY_CHECK_RET (lysp_load_submod_from_clb_or_file (pctx , inc -> name , inc -> rev [0 ] ? inc -> rev : NULL , inc -> submodule ,
1248+ new_mods , & submod ));
12351249
1236- /* update inc pointer - parsing another (YANG 1.0) submodule can cause injecting
1237- * submodule's include into main module, where it is missing */
1238- inc = & pmod -> includes [ u ];
1239- inc -> submodule = submod ;
1250+ if ( submod ) {
1251+ /* update inc pointer - parsing another (YANG 1.0) submodule can cause injecting
1252+ * submodule's include into main module, where it is missing */
1253+ inc = & pmod -> includes [ u ] ;
12401254
1241- if (!submod_included ) {
1242- /* the submodule include is not present in YANG 1.0 main module - add it there */
1243- LY_CHECK_RET (lysp_inject_submodule (pctx , & pmod -> includes [u ]));
1255+ assert (!inc -> submodule );
1256+ inc -> submodule = submod ;
1257+
1258+ if (!submod_included ) {
1259+ /* the submodule include is not present in YANG 1.0 main module - add it there */
1260+ LY_CHECK_RET (lysp_inject_submodule (pctx , inc ));
1261+ }
12441262 }
12451263 }
12461264
0 commit comments