schema parsers CHANGE make lys_parse_mem functions compatible with yin_parser_ctx
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 31a740c..aa58756 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -4490,7 +4490,7 @@
}
LY_ERR
-yang_parse_submodule(struct lys_parser_ctx *context, const char *data, struct lysp_submodule **submod)
+yang_parse_submodule(struct lys_parser_ctx **context, struct ly_ctx *ly_ctx, struct lys_parser_ctx *main_ctx, const char *data, struct lysp_submodule **submod)
{
LY_ERR ret = LY_SUCCESS;
char *word;
@@ -4498,27 +4498,37 @@
enum yang_keyword kw;
struct lysp_submodule *mod_p = NULL;
+ /* create context */
+ *context = calloc(1, sizeof **context);
+ LY_CHECK_ERR_RET(!(*context), LOGMEM(ly_ctx), LY_EMEM);
+ (*context)->ctx = ly_ctx;
+ (*context)->line = 1;
+
+ /* map the typedefs and groupings list from main context to the submodule's context */
+ memcpy(&(*context)->tpdfs_nodes, &main_ctx->tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
+ memcpy(&(*context)->grps_nodes, &main_ctx->grps_nodes, sizeof main_ctx->grps_nodes);
+
/* "module"/"submodule" */
- ret = get_keyword(context, &data, &kw, &word, &word_len);
+ ret = get_keyword(*context, &data, &kw, &word, &word_len);
LY_CHECK_GOTO(ret, cleanup);
if (kw == YANG_MODULE) {
- LOGERR(context->ctx, LY_EDENIED, "Input data contains module in situation when a submodule is expected.");
+ LOGERR((*context)->ctx, LY_EDENIED, "Input data contains module in situation when a submodule is expected.");
ret = LY_EINVAL;
goto cleanup;
} else if (kw != YANG_SUBMODULE) {
- LOGVAL_PARSER(context, LYVE_SYNTAX, "Invalid keyword \"%s\", expected \"module\" or \"submodule\".",
+ LOGVAL_PARSER(*context, LYVE_SYNTAX, "Invalid keyword \"%s\", expected \"module\" or \"submodule\".",
ly_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
}
mod_p = calloc(1, sizeof *mod_p);
- LY_CHECK_ERR_GOTO(!mod_p, LOGMEM(context->ctx), cleanup);
+ LY_CHECK_ERR_GOTO(!mod_p, LOGMEM((*context)->ctx), cleanup);
mod_p->parsing = 1;
/* substatements */
- ret = parse_submodule(context, &data, mod_p);
+ ret = parse_submodule(*context, &data, mod_p);
LY_CHECK_GOTO(ret, cleanup);
/* read some trailing spaces or new lines */
@@ -4526,7 +4536,7 @@
data++;
}
if (*data) {
- LOGVAL_PARSER(context, LYVE_SYNTAX, "Trailing garbage \"%.*s%s\" after submodule, expected end-of-input.",
+ LOGVAL_PARSER(*context, LYVE_SYNTAX, "Trailing garbage \"%.*s%s\" after submodule, expected end-of-input.",
15, data, strlen(data) > 15 ? "..." : "");
ret = LY_EVALID;
goto cleanup;
@@ -4537,14 +4547,16 @@
cleanup:
if (ret) {
- lysp_submodule_free(context->ctx, mod_p);
+ lysp_submodule_free((*context)->ctx, mod_p);
+ lys_parser_ctx_free(*context);
+ *context = NULL;
}
return ret;
}
LY_ERR
-yang_parse_module(struct lys_parser_ctx *context, const char *data, struct lys_module *mod)
+yang_parse_module(struct lys_parser_ctx **context, const char *data, struct lys_module *mod)
{
LY_ERR ret = LY_SUCCESS;
char *word;
@@ -4552,28 +4564,34 @@
enum yang_keyword kw;
struct lysp_module *mod_p = NULL;
+ /* create context */
+ *context = calloc(1, sizeof **context);
+ LY_CHECK_ERR_RET(!(*context), LOGMEM(mod->ctx), LY_EMEM);
+ (*context)->ctx = mod->ctx;
+ (*context)->line = 1;
+
/* "module"/"submodule" */
- ret = get_keyword(context, &data, &kw, &word, &word_len);
+ ret = get_keyword(*context, &data, &kw, &word, &word_len);
LY_CHECK_GOTO(ret, cleanup);
if (kw == YANG_SUBMODULE) {
- LOGERR(context->ctx, LY_EDENIED, "Input data contains submodule which cannot be parsed directly without its main module.");
+ LOGERR((*context)->ctx, LY_EDENIED, "Input data contains submodule which cannot be parsed directly without its main module.");
ret = LY_EINVAL;
goto cleanup;
} else if (kw != YANG_MODULE) {
- LOGVAL_PARSER(context, LYVE_SYNTAX, "Invalid keyword \"%s\", expected \"module\" or \"submodule\".",
+ LOGVAL_PARSER((*context), LYVE_SYNTAX, "Invalid keyword \"%s\", expected \"module\" or \"submodule\".",
ly_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
}
mod_p = calloc(1, sizeof *mod_p);
- LY_CHECK_ERR_GOTO(!mod_p, LOGMEM(context->ctx), cleanup);
+ LY_CHECK_ERR_GOTO(!mod_p, LOGMEM((*context)->ctx), cleanup);
mod_p->mod = mod;
mod_p->parsing = 1;
/* substatements */
- ret = parse_module(context, &data, mod_p);
+ ret = parse_module(*context, &data, mod_p);
LY_CHECK_GOTO(ret, cleanup);
/* read some trailing spaces or new lines */
@@ -4581,7 +4599,7 @@
data++;
}
if (*data) {
- LOGVAL_PARSER(context, LYVE_SYNTAX, "Trailing garbage \"%.*s%s\" after module, expected end-of-input.",
+ LOGVAL_PARSER(*context, LYVE_SYNTAX, "Trailing garbage \"%.*s%s\" after module, expected end-of-input.",
15, data, strlen(data) > 15 ? "..." : "");
ret = LY_EVALID;
goto cleanup;
@@ -4593,6 +4611,8 @@
cleanup:
if (ret) {
lysp_module_free(mod_p);
+ lys_parser_ctx_free(*context);
+ *context = NULL;
}
return ret;
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 7c278a0..ae037b3 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -3119,7 +3119,7 @@
}
LY_ERR
-yin_parse_submodule(struct yin_parser_ctx **yin_ctx, struct ly_ctx *ctx, const char *data, struct lysp_submodule **submod)
+yin_parse_submodule(struct yin_parser_ctx **yin_ctx, struct ly_ctx *ctx, struct lys_parser_ctx *main_ctx, const char *data, struct lysp_submodule **submod)
{
enum yang_keyword kw = YANG_NONE;
LY_ERR ret = LY_SUCCESS;
@@ -3130,10 +3130,14 @@
/* create context */
*yin_ctx = calloc(1, sizeof **yin_ctx);
- LY_CHECK_ERR_RET(!yin_ctx, LOGMEM(ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!(*yin_ctx), LOGMEM(ctx), LY_EMEM);
(*yin_ctx)->xml_ctx.ctx = ctx;
(*yin_ctx)->xml_ctx.line = 1;
+ /* map the typedefs and groupings list from main context to the submodule's context */
+ memcpy(&(*yin_ctx)->tpdfs_nodes, &main_ctx->tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
+ memcpy(&(*yin_ctx)->grps_nodes, &main_ctx->grps_nodes, sizeof main_ctx->grps_nodes);
+
/* check submodule */
ret = lyxml_get_element(&(*yin_ctx)->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
LY_CHECK_GOTO(ret, cleanup);
@@ -3178,6 +3182,8 @@
cleanup:
if (ret) {
lysp_submodule_free(ctx, mod_p);
+ yin_parser_ctx_free(*yin_ctx);
+ *yin_ctx = NULL;
}
FREE_ARRAY(*yin_ctx, attrs, free_arg_rec);
@@ -3196,7 +3202,7 @@
/* create context */
*yin_ctx = calloc(1, sizeof **yin_ctx);
- LY_CHECK_ERR_RET(!yin_ctx, LOGMEM(mod->ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!(*yin_ctx), LOGMEM(mod->ctx), LY_EMEM);
(*yin_ctx)->xml_ctx.ctx = mod->ctx;
(*yin_ctx)->xml_ctx.line = 1;
@@ -3227,6 +3233,7 @@
ret = yin_parse_mod(*yin_ctx, attrs, &data, mod_p);
LY_CHECK_GOTO(ret, cleanup);
+ /* check trailing characters */
if ((*yin_ctx)->xml_ctx.status == LYXML_ELEMENT) {
ret = lyxml_get_element(&(*yin_ctx)->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
}
@@ -3244,6 +3251,8 @@
cleanup:
if (ret != LY_SUCCESS) {
lysp_module_free(mod_p);
+ yin_parser_ctx_free(*yin_ctx);
+ *yin_ctx = NULL;
}
FREE_ARRAY(*yin_ctx, attrs, free_arg_rec);
return ret;
diff --git a/src/tree_schema.c b/src/tree_schema.c
index d828c67..25c4d64 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -595,28 +595,21 @@
{
LY_ERR ret = LY_EINVAL;
struct lysp_submodule *submod = NULL, *latest_sp;
- struct lys_parser_ctx context = {0};
+ struct lys_parser_ctx *context = NULL;
+ struct yin_parser_ctx *yin_context = NULL;
LY_CHECK_ARG_RET(ctx, ctx, data, NULL);
- context.ctx = ctx;
- context.line = 1;
-
- /* map the typedefs and groupings list from main context to the submodule's context */
- memcpy(&context.tpdfs_nodes, &main_ctx->tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
- memcpy(&context.grps_nodes, &main_ctx->grps_nodes, sizeof main_ctx->grps_nodes);
-
switch (format) {
- /* TODO not yet supported
case LYS_IN_YIN:
- mod = yin_read_module();
+ ret = yin_parse_submodule(&yin_context, ctx, main_ctx, data, &submod);
+ context = (struct lys_parser_ctx *)yin_context;
break;
- */
case LYS_IN_YANG:
- ret = yang_parse_submodule(&context, data, &submod);
+ ret = yang_parse_submodule(&context, ctx, main_ctx, data, &submod);
break;
default:
- LOGERR(context.ctx, LY_EINVAL, "Invalid schema input format.");
+ LOGERR((*context).ctx, LY_EINVAL, "Invalid schema input format.");
break;
}
LY_CHECK_RET(ret, NULL);
@@ -625,11 +618,11 @@
lysp_sort_revisions(submod->revs);
if (custom_check) {
- LY_CHECK_GOTO(custom_check(context.ctx, NULL, submod, check_data), error);
+ LY_CHECK_GOTO(custom_check((*context).ctx, NULL, submod, check_data), error);
}
/* decide the latest revision */
- latest_sp = ly_ctx_get_submodule(context.ctx, submod->belongsto, submod->name, NULL);
+ latest_sp = ly_ctx_get_submodule((*context).ctx, submod->belongsto, submod->name, NULL);
if (latest_sp) {
if (submod->revs) {
if (!latest_sp->revs) {
@@ -648,12 +641,23 @@
}
/* remap possibly changed and reallocated typedefs and groupings list back to the main context */
- memcpy(&main_ctx->tpdfs_nodes, &context.tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
- memcpy(&main_ctx->grps_nodes, &context.grps_nodes, sizeof main_ctx->grps_nodes);
+ memcpy(&main_ctx->tpdfs_nodes, &(*context).tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
+ memcpy(&main_ctx->grps_nodes, &(*context).grps_nodes, sizeof main_ctx->grps_nodes);
+ if (format == LYS_IN_YANG) {
+ lys_parser_ctx_free(context);
+ } else {
+ yin_parser_ctx_free(yin_context);
+ }
return submod;
+
error:
lysp_submodule_free(ctx, submod);
+ if (format == LYS_IN_YANG) {
+ lys_parser_ctx_free(context);
+ } else {
+ yin_parser_ctx_free(yin_context);
+ }
return NULL;
}
@@ -667,23 +671,20 @@
struct lysp_include *inc;
LY_ERR ret = LY_EINVAL;
unsigned int u, i;
- struct lys_parser_ctx context = {0};
+ struct lys_parser_ctx *context = NULL;
+ struct yin_parser_ctx *yin_context = NULL;
LY_CHECK_ARG_RET(ctx, ctx, data, NULL);
- context.ctx = ctx;
- context.line = 1;
-
mod = calloc(1, sizeof *mod);
LY_CHECK_ERR_RET(!mod, LOGMEM(ctx), NULL);
mod->ctx = ctx;
switch (format) {
- /* TODO not yet supported
case LYS_IN_YIN:
- mod = yin_read_module();
+ ret = yin_parse_module(&yin_context, data, mod);
+ context = (struct lys_parser_ctx *)yin_context;
break;
- */
case LYS_IN_YANG:
ret = yang_parse_module(&context, data, mod);
break;
@@ -793,7 +794,7 @@
}
LY_ARRAY_FOR(mod->parsed->includes, u) {
inc = &mod->parsed->includes[u];
- if (!inc->submodule && lysp_load_submodule(&context, mod->parsed, inc)) {
+ if (!inc->submodule && lysp_load_submodule(context, mod->parsed, inc)) {
goto error_ctx;
}
if (!mod->implemented) {
@@ -804,15 +805,26 @@
mod->parsed->parsing = 0;
/* check name collisions - typedefs and TODO groupings */
- LY_CHECK_GOTO(lysp_check_typedefs(&context, mod->parsed), error_ctx);
+ LY_CHECK_GOTO(lysp_check_typedefs(context, mod->parsed), error_ctx);
+ if (format == LYS_IN_YANG) {
+ lys_parser_ctx_free(context);
+ } else {
+ yin_parser_ctx_free(yin_context);
+ }
return mod;
error_ctx:
ly_set_rm(&ctx->list, mod, NULL);
error:
lys_module_free(mod, NULL);
- ly_set_erase(&context.tpdfs_nodes, NULL);
+ ly_set_erase(&context->tpdfs_nodes, NULL);
+ if (format == LYS_IN_YANG) {
+ lys_parser_ctx_free(context);
+ } else {
+ yin_parser_ctx_free(yin_context);
+ }
+
return NULL;
}
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 25fdf5f..edb2f10 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -867,8 +867,6 @@
lys_parser_ctx_free(struct lys_parser_ctx *ctx)
{
if (ctx) {
- ly_set_erase(&ctx->tpdfs_nodes, NULL);
- ly_set_erase(&ctx->tpdfs_nodes, NULL);
free(ctx);
}
}
@@ -878,8 +876,6 @@
{
if (ctx) {
lyxml_context_clear(&ctx->xml_ctx);
- ly_set_erase(&ctx->tpdfs_nodes, NULL);
- ly_set_erase(&ctx->tpdfs_nodes, NULL);
free(ctx);
}
}
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index b1da956..ffda7f5 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -787,12 +787,15 @@
/**
* @brief Parse submodule from YANG data.
- * @param[in] ctx Parser context.
+ * @param[in,out] ctx Parser context.
+ * @param[in] ly_ctx Context of YANG schemas.
+ * @param[in] main_ctx Parser context of main module.
* @param[in] data Input data to be parsed.
* @param[out] submod Pointer to the parsed submodule structure.
* @return LY_ERR value - LY_SUCCESS, LY_EINVAL or LY_EVALID.
*/
-LY_ERR yang_parse_submodule(struct lys_parser_ctx *ctx, const char *data, struct lysp_submodule **submod);
+LY_ERR yang_parse_submodule(struct lys_parser_ctx **context, struct ly_ctx *ly_ctx, struct lys_parser_ctx *main_ctx,
+ const char *data, struct lysp_submodule **submod);
/**
* @brief Parse module from YANG data.
@@ -802,7 +805,7 @@
* module structure, will be filled in.
* @return LY_ERR value - LY_SUCCESS, LY_EINVAL or LY_EVALID.
*/
-LY_ERR yang_parse_module(struct lys_parser_ctx *ctx, const char *data, struct lys_module *mod);
+LY_ERR yang_parse_module(struct lys_parser_ctx **context, const char *data, struct lys_module *mod);
/**
* @brief Parse module from YIN data.
@@ -821,14 +824,16 @@
*
* @param[in,out] yin_ctx Context created during parsing, is used to finalize lysp_model after it's completly parsed.
* @param[in] ctx Libyang context.
- * @param[in,out] Data Input data to be parsed.
- * @param[in,out] mod Submodule structure where the parsed information, will be filled in.
+ * @param[in] main_ctx Parser context of main module.
+ * @param[in,out] data Input data to be parsed.
+ * @param[in,out] submod Submodule structure where the parsed information, will be filled in.
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_submodule(struct yin_parser_ctx **yin_ctx, struct ly_ctx *ctx,
+LY_ERR yin_parse_submodule(struct yin_parser_ctx **yin_ctx, struct ly_ctx *ctx, struct lys_parser_ctx *main_ctx,
const char *data, struct lysp_submodule **submod);
+
/**
* @brief Make the specific module implemented, use the provided value as flag.
*
diff --git a/tests/src/test_context.c b/tests/src/test_context.c
index 78deffe..58f52d4 100644
--- a/tests/src/test_context.c
+++ b/tests/src/test_context.c
@@ -283,7 +283,7 @@
assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
assert_int_equal(ctx->module_set_id, ly_ctx_get_module_set_id(ctx));
- assert_null(lys_parse_mem_module(ctx, "module x {namespace urn:x;prefix x;}", 3, 1, NULL, NULL));
+ assert_null(lys_parse_mem_module(ctx, "module x {namespace urn:x;prefix x;}", 4, 1, NULL, NULL));
logbuf_assert("Invalid schema input format.");
/* import callback */
diff --git a/tests/src/test_parser_yang.c b/tests/src/test_parser_yang.c
index 258cba7..e4adfd7 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/src/test_parser_yang.c
@@ -1047,20 +1047,23 @@
assert_int_equal(2, mod->mod->version);
mod = mod_renew(&ctx);
+ struct lys_parser_ctx *ctx_p = NULL;
str = "module " SCHEMA_BEGINNING "} module q {namespace urn:q;prefixq;}";
m = mod->mod;
free(mod);
m->parsed = NULL;
- assert_int_equal(LY_EVALID, yang_parse_module(&ctx, str, m));
- logbuf_assert("Trailing garbage \"module q {names...\" after module, expected end-of-input. Line number 3.");
+ assert_int_equal(LY_EVALID, yang_parse_module(&ctx_p, str, m));
+ logbuf_assert("Trailing garbage \"module q {names...\" after module, expected end-of-input. Line number 1.");
+ lys_parser_ctx_free(ctx_p);
mod = mod_renew(&ctx);
str = "prefix " SCHEMA_BEGINNING "}";
m = mod->mod;
free(mod);
m->parsed = NULL;
- assert_int_equal(LY_EVALID, yang_parse_module(&ctx, str, m));
- logbuf_assert("Invalid keyword \"prefix\", expected \"module\" or \"submodule\". Line number 3.");
+ assert_int_equal(LY_EVALID, yang_parse_module(&ctx_p, str, m));
+ lys_parser_ctx_free(ctx_p);
+ logbuf_assert("Invalid keyword \"prefix\", expected \"module\" or \"submodule\". Line number 1.");
mod = mod_renew(&ctx);
str = "module " SCHEMA_BEGINNING "}";
@@ -1068,8 +1071,9 @@
m = mod->mod;
free(mod);
m->parsed = NULL;
- assert_int_equal(LY_EVALID, yang_parse_module(&ctx, str, m));
- logbuf_assert("Invalid keyword \"position\" as a child of \"enum\". Line number 3.");
+ assert_int_equal(LY_EVALID, yang_parse_module(&ctx_p, str, m));
+ lys_parser_ctx_free(ctx_p);
+ logbuf_assert("Invalid keyword \"position\" as a child of \"enum\". Line number 1.");
mod = mod_renew(&ctx);
/* extensions */
@@ -1123,12 +1127,14 @@
str = "submodule " SCHEMA_BEGINNING "} module q {namespace urn:q;prefixq;}";
lysp_submodule_free(ctx.ctx, submod);
submod = NULL;
- assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx, str, &submod));
- logbuf_assert("Trailing garbage \"module q {names...\" after submodule, expected end-of-input. Line number 3.");
+ assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx_p, ctx.ctx, &ctx, str, &submod));
+ lys_parser_ctx_free(ctx_p);
+ logbuf_assert("Trailing garbage \"module q {names...\" after submodule, expected end-of-input. Line number 1.");
str = "prefix " SCHEMA_BEGINNING "}";
- assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx, str, &submod));
- logbuf_assert("Invalid keyword \"prefix\", expected \"module\" or \"submodule\". Line number 3.");
+ assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx_p, ctx.ctx, &ctx, str, &submod));
+ lys_parser_ctx_free(ctx_p);
+ logbuf_assert("Invalid keyword \"prefix\", expected \"module\" or \"submodule\". Line number 1.");
submod = submod_renew(&ctx, submod);
#undef TEST_GENERIC
diff --git a/tests/src/test_parser_yin.c b/tests/src/test_parser_yin.c
index 773dff3..2f06f45 100644
--- a/tests/src/test_parser_yin.c
+++ b/tests/src/test_parser_yin.c
@@ -3724,6 +3724,7 @@
const char *data;
struct yin_parser_ctx *yin_ctx = NULL;
struct lysp_submodule *submod = NULL;
+ struct lys_parser_ctx main_ctx = {};
data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<submodule name=\"asub\""
@@ -3749,7 +3750,7 @@
"<container name=\"bar-sub2\"/>"
"</augment>"
"</submodule>";
- assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, data, &submod), LY_SUCCESS);
+ assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, &main_ctx, data, &submod), LY_SUCCESS);
lysp_submodule_free(st->ctx, submod);
yin_parser_ctx_free(yin_ctx);
yin_ctx = NULL;
@@ -3762,7 +3763,7 @@
"<prefix value=\"a_pref\"/>"
"</belongs-to>"
"</submodule>";
- assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, data, &submod), LY_SUCCESS);
+ assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, &main_ctx, data, &submod), LY_SUCCESS);
lysp_submodule_free(st->ctx, submod);
yin_parser_ctx_free(yin_ctx);
yin_ctx = NULL;
@@ -3771,7 +3772,7 @@
data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<module name=\"inval\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
"</module>";
- assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, data, &submod), LY_EINVAL);
+ assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, &main_ctx, data, &submod), LY_EINVAL);
logbuf_assert("Input data contains module in situation when a submodule is expected.");
lysp_submodule_free(st->ctx, submod);
yin_parser_ctx_free(yin_ctx);
@@ -3791,7 +3792,7 @@
"<prefix value=\"a_pref\"/>"
"</belongs-to>"
"</submodule>";
- assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, data, &submod), LY_EVALID);
+ assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, &main_ctx, data, &submod), LY_EVALID);
logbuf_assert("Trailing garbage \"<submodule name...\" after submodule, expected end-of-input. Line number 2.");
lysp_submodule_free(st->ctx, submod);
yin_parser_ctx_free(yin_ctx);
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index 08d847b..9063869 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -26,6 +26,7 @@
#include "../../src/plugins_types.h"
void lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat);
+void lys_parser_ctx_free(struct lys_parser_ctx *ctx);
LY_ERR lys_path_token(const char **path, const char **prefix, size_t *prefix_len, const char **name, size_t *name_len,
int *parent_times, int *has_predicate);
@@ -95,20 +96,21 @@
}
static void
-reset_mod(struct ly_ctx *ctx, struct lys_module *module)
+reset_mod(struct lys_module *module)
{
+ struct ly_ctx *ctx = module->ctx;
lysc_module_free(module->compiled, NULL);
lysp_module_free(module->parsed);
- FREE_STRING(module->ctx, module->name);
- FREE_STRING(module->ctx, module->ns);
- FREE_STRING(module->ctx, module->prefix);
- FREE_STRING(module->ctx, module->filepath);
- FREE_STRING(module->ctx, module->org);
- FREE_STRING(module->ctx, module->contact);
- FREE_STRING(module->ctx, module->dsc);
- FREE_STRING(module->ctx, module->ref);
- FREE_ARRAY(module->ctx, module->off_features, lysc_feature_free);
+ FREE_STRING(ctx, module->name);
+ FREE_STRING(ctx, module->ns);
+ FREE_STRING(ctx, module->prefix);
+ FREE_STRING(ctx, module->filepath);
+ FREE_STRING(ctx, module->org);
+ FREE_STRING(ctx, module->contact);
+ FREE_STRING(ctx, module->dsc);
+ FREE_STRING(ctx, module->ref);
+ FREE_ARRAY(ctx, module->off_features, lysc_feature_free);
memset(module, 0, sizeof *module);
module->ctx = ctx;
@@ -121,21 +123,22 @@
*state = test_module;
const char *str;
- struct lys_parser_ctx ctx = {0};
+ struct lys_parser_ctx *ctx = NULL;
struct lys_module mod = {0};
struct lysc_feature *f;
struct lysc_iffeature *iff;
str = "module test {namespace urn:test; prefix t;"
"feature f1;feature f2 {if-feature f1;}}";
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
- reset_mod(ctx.ctx, &mod);
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &mod.ctx));
+ reset_mod(&mod);
assert_int_equal(LY_EINVAL, lys_compile(NULL, 0));
logbuf_assert("Invalid argument mod (lys_compile()).");
assert_int_equal(LY_EINVAL, lys_compile(&mod, 0));
logbuf_assert("Invalid argument mod->parsed (lys_compile()).");
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, str, &mod));
+ lys_parser_ctx_free(ctx);
mod.implemented = 0;
assert_int_equal(LY_SUCCESS, lys_compile(&mod, 0));
assert_null(mod.compiled);
@@ -168,20 +171,22 @@
/* submodules cannot be compiled directly */
str = "submodule test {belongs-to xxx {prefix x;}}";
assert_int_equal(LY_EINVAL, yang_parse_module(&ctx, str, &mod));
+ lys_parser_ctx_free(ctx);
logbuf_assert("Input data contains submodule which cannot be parsed directly without its main module.");
assert_null(mod.parsed);
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
/* data definition name collision in top level */
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module aa {namespace urn:aa;prefix aa;"
"leaf a {type string;} container a{presence x;}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Duplicate identifier \"a\" of data definition/RPC/action/Notification statement. /aa:a");
assert_null(mod.compiled);
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
*state = NULL;
- ly_ctx_destroy(ctx.ctx, NULL);
+ ly_ctx_destroy(mod.ctx, NULL);
}
static void
@@ -189,7 +194,7 @@
{
*state = test_feature;
- struct lys_parser_ctx ctx = {0};
+ struct lys_parser_ctx *ctx = NULL;
struct lys_module mod = {0}, *modp;
const char *str;
struct lysc_feature *f, *f1;
@@ -203,10 +208,11 @@
"feature f8 {if-feature \"f1 or f2 or f3 or orfeature or andfeature\";}\n"
"feature f9 {if-feature \"not not f1\";}}";
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
- reset_mod(ctx.ctx, &mod);
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &mod.ctx));
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, str, &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_SUCCESS, lys_compile(&mod, 0));
assert_non_null(mod.compiled);
assert_non_null(mod.compiled->features);
@@ -283,7 +289,7 @@
assert_int_equal(1, lys_feature_value(&mod, "f1"));
assert_int_equal(0, lys_feature_value(&mod, "f2"));
- assert_non_null(modp = lys_parse_mem(ctx.ctx, "module b {namespace urn:b;prefix b;"
+ assert_non_null(modp = lys_parse_mem(mod.ctx, "module b {namespace urn:b;prefix b;"
"feature f1 {if-feature f2;}feature f2;}", LYS_IN_YANG));
assert_non_null(modp->compiled);
assert_non_null(modp->compiled->features);
@@ -303,83 +309,91 @@
assert_int_equal(LY_EINVAL, lys_feature_enable(&mod, "xxx"));
logbuf_assert("Feature \"xxx\" not found in module \"a\".");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
/* some invalid expressions */
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f{if-feature f1;}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Invalid value \"f1\" of if-feature - unable to find feature \"f1\". /b:{feature='f'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature 'f and';}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Invalid value \"f and\" of if-feature - unexpected end of expression. /b:{feature='f2'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f{if-feature 'or';}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Invalid value \"or\" of if-feature - unexpected end of expression. /b:{feature='f'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature '(f1';}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Invalid value \"(f1\" of if-feature - non-matching opening and closing parentheses. /b:{feature='f2'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature 'f1)';}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Invalid value \"f1)\" of if-feature - non-matching opening and closing parentheses. /b:{feature='f2'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature ---;}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Invalid value \"---\" of if-feature - unable to find feature \"---\". /b:{feature='f2'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{namespace urn:b; prefix b; feature f1; feature f2{if-feature 'not f1';}}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Invalid value \"not f1\" of if-feature - YANG 1.1 expression in YANG 1.0 module. /b:{feature='f2'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{namespace urn:b; prefix b; feature f1; feature f1;}", &mod));
+ lys_parser_ctx_free(ctx);
assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
logbuf_assert("Duplicate identifier \"f1\" of feature statement. /b:{feature='f1'}");
- reset_mod(ctx.ctx, &mod);
+ reset_mod(&mod);
- ly_ctx_set_module_imp_clb(ctx.ctx, test_imp_clb, "submodule sz {belongs-to z {prefix z;} feature f1;}");
- assert_null(lys_parse_mem(ctx.ctx, "module z{namespace urn:z; prefix z; include sz;feature f1;}", LYS_IN_YANG));
+ ly_ctx_set_module_imp_clb(mod.ctx, test_imp_clb, "submodule sz {belongs-to z {prefix z;} feature f1;}");
+ assert_null(lys_parse_mem(mod.ctx, "module z{namespace urn:z; prefix z; include sz;feature f1;}", LYS_IN_YANG));
logbuf_assert("Duplicate identifier \"f1\" of feature statement. /z:{feature='f1'}");
- assert_null(lys_parse_mem(ctx.ctx, "module aa{namespace urn:aa; prefix aa; feature f1 {if-feature f2;} feature f2 {if-feature f1;}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(mod.ctx, "module aa{namespace urn:aa; prefix aa; feature f1 {if-feature f2;} feature f2 {if-feature f1;}}", LYS_IN_YANG));
logbuf_assert("Feature \"f1\" is indirectly referenced from itself. /aa:{feature='f2'}");
- assert_null(lys_parse_mem(ctx.ctx, "module ab{namespace urn:ab; prefix ab; feature f1 {if-feature f1;}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(mod.ctx, "module ab{namespace urn:ab; prefix ab; feature f1 {if-feature f1;}}", LYS_IN_YANG));
logbuf_assert("Feature \"f1\" is referenced from itself. /ab:{feature='f1'}");
- assert_null(lys_parse_mem(ctx.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f {if-feature ();}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f {if-feature ();}}", LYS_IN_YANG));
logbuf_assert("Invalid value \"()\" of if-feature - number of features in expression does not match the required number "
"of operands for the operations. /bb:{feature='f'}");
- assert_null(lys_parse_mem(ctx.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1(';}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1(';}}", LYS_IN_YANG));
logbuf_assert("Invalid value \"f1(\" of if-feature - non-matching opening and closing parentheses. /bb:{feature='f'}");
- assert_null(lys_parse_mem(ctx.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'and f1';}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'and f1';}}", LYS_IN_YANG));
logbuf_assert("Invalid value \"and f1\" of if-feature - missing feature/expression before \"and\" operation. /bb:{feature='f'}");
- assert_null(lys_parse_mem(ctx.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1 not ';}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1 not ';}}", LYS_IN_YANG));
logbuf_assert("Invalid value \"f1 not \" of if-feature - unexpected end of expression. /bb:{feature='f'}");
- assert_null(lys_parse_mem(ctx.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1 not not ';}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1 not not ';}}", LYS_IN_YANG));
logbuf_assert("Invalid value \"f1 not not \" of if-feature - unexpected end of expression. /bb:{feature='f'}");
- assert_null(lys_parse_mem(ctx.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f2; "
+ assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f2; "
"feature f {if-feature 'or f1 f2';}}", LYS_IN_YANG));
logbuf_assert("Invalid value \"or f1 f2\" of if-feature - missing feature/expression before \"or\" operation. /bb:{feature='f'}");
/* import reference */
- assert_non_null(modp = lys_parse_mem(ctx.ctx, str, LYS_IN_YANG));
+ assert_non_null(modp = lys_parse_mem(mod.ctx, str, LYS_IN_YANG));
assert_int_equal(LY_SUCCESS, lys_feature_enable(modp, "f1"));
- assert_non_null(modp = lys_parse_mem(ctx.ctx, "module c{namespace urn:c; prefix c; import a {prefix a;} feature f1; feature f2{if-feature 'a:f1';}}", LYS_IN_YANG));
+ assert_non_null(modp = lys_parse_mem(mod.ctx, "module c{namespace urn:c; prefix c; import a {prefix a;} feature f1; feature f2{if-feature 'a:f1';}}", LYS_IN_YANG));
assert_int_equal(LY_SUCCESS, lys_feature_enable(modp, "f2"));
assert_int_equal(0, lys_feature_value(modp, "f1"));
assert_int_equal(1, lys_feature_value(modp, "f2"));
*state = NULL;
- ly_ctx_destroy(ctx.ctx, NULL);
+ ly_ctx_destroy(mod.ctx, NULL);
}
static void