Skip to content

Commit 77bfef8

Browse files
committed
tree schema REFACTOR avoid goto usage
1 parent 3bbd13c commit 77bfef8

File tree

1 file changed

+127
-92
lines changed

1 file changed

+127
-92
lines changed

src/tree_schema_common.c

Lines changed: 127 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -758,30 +758,44 @@ lys_parse_localfile(struct ly_ctx *ctx, const char *name, const char *revision,
758758
* @return LY_ERR on error.
759759
*/
760760
static 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+
11081198
LY_ERR
11091199
lysp_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

Comments
 (0)