schema compile FEATURE support for glob unres reset
That preserves creating and implementing module sets.
diff --git a/src/context.c b/src/context.c
index 89cb767..2296090 100644
--- a/src/context.c
+++ b/src/context.c
@@ -20,6 +20,7 @@
#include "context.h"
+#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdarg.h>
@@ -205,10 +206,10 @@
cleanup:
if (ret) {
lys_compile_unres_glob_revert(ctx, &unres);
- result = NULL;
+ mod = NULL;
}
- lys_compile_unres_glob_erase(ctx, &unres);
- return result;
+ lys_compile_unres_glob_erase(ctx, &unres, 0);
+ return mod;
}
API LY_ERR
@@ -298,14 +299,12 @@
}
ly_in_free(in, 0);
- lys_compile_unres_glob_erase(ctx, &unres);
- *new_ctx = ctx;
- return rc;
-
-error:
- ly_in_free(in, 0);
- lys_compile_unres_glob_erase(ctx, &unres);
- ly_ctx_destroy(ctx);
+ lys_compile_unres_glob_erase(ctx, &unres, 0);
+ if (rc) {
+ ly_ctx_destroy(ctx);
+ } else {
+ *new_ctx = ctx;
+ }
return rc;
}
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 89db6db..5ae837a 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -1371,12 +1371,14 @@
}
void
-lys_compile_unres_glob_erase(const struct ly_ctx *ctx, struct lys_glob_unres *unres)
+lys_compile_unres_glob_erase(const struct ly_ctx *ctx, struct lys_glob_unres *unres, ly_bool recompiled)
{
uint32_t i;
- ly_set_erase(&unres->implementing, NULL);
- ly_set_erase(&unres->creating, NULL);
+ if (!recompiled) {
+ ly_set_erase(&unres->implementing, NULL);
+ ly_set_erase(&unres->creating, NULL);
+ }
for (i = 0; i < unres->dflts.count; ++i) {
lysc_unres_dflt_free(ctx, unres->dflts.objs[i]);
}
diff --git a/src/schema_compile.h b/src/schema_compile.h
index 992c34d..d186fb0 100644
--- a/src/schema_compile.h
+++ b/src/schema_compile.h
@@ -257,12 +257,13 @@
void lys_compile_unres_glob_revert(struct ly_ctx *ctx, struct lys_glob_unres *unres);
/**
- * @brief Erase all the global unres sets.
+ * @brief Erase the global unres.
*
* @param[in] ctx libyang context.
* @param[in] unres Global unres structure with the sets.
+ * @param[in] recompiled Whether to keep the set of new parsed and implemented modules.
*/
-void lys_compile_unres_glob_erase(const struct ly_ctx *ctx, struct lys_glob_unres *unres);
+void lys_compile_unres_glob_erase(const struct ly_ctx *ctx, struct lys_glob_unres *unres, ly_bool recompiled);
/**
* @brief Recompile the whole context based on the current flags.
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 519df21..02257f5 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1457,7 +1457,7 @@
} else if (module) {
*module = mod;
}
- lys_compile_unres_glob_erase(ctx, &unres);
+ lys_compile_unres_glob_erase(ctx, &unres, 0);
return ret;
}
diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c
index 9f7961b..a1c9e3b 100644
--- a/tests/utests/basic/test_context.c
+++ b/tests/utests/basic/test_context.c
@@ -215,8 +215,8 @@
assert_int_equal(UTEST_LYCTX->change_count, ly_ctx_get_change_count(UTEST_LYCTX));
assert_int_equal(LY_SUCCESS, ly_in_new_memory("module x {namespace urn:x;prefix x;}", &in));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in, 4, NULL, NULL, &unres.creating, &mod1));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
CHECK_LOG_CTX("Invalid schema input format.", NULL);
@@ -234,8 +234,8 @@
/* name collision of module and submodule */
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-30;}");
assert_int_equal(LY_SUCCESS, ly_in_new_memory("module y {namespace urn:y;prefix y;include y;}", &in));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1.");
@@ -243,11 +243,11 @@
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
assert_int_equal(LY_SUCCESS, lys_implement(mod1, NULL, &unres));
assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory("module y {namespace urn:y;prefix y;}", &in));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1.");
@@ -255,7 +255,7 @@
assert_int_equal(LY_SUCCESS, ly_in_new_memory("module b {namespace urn:b;prefix b;include y;}", &in));
assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
lys_compile_unres_glob_revert(UTEST_LYCTX, &unres);
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
CHECK_LOG_CTX("Including \"y\" submodule into \"b\" failed.", NULL,
"Name collision between submodules of name \"y\".", "Line number 1.");
@@ -264,8 +264,8 @@
ly_ctx_reset_latests(UTEST_LYCTX);
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-31;}");
assert_int_equal(LY_SUCCESS, ly_in_new_memory("module a {namespace urn:a;prefix a;include y; revision 2018-10-31;}", &in));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod2));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
assert_string_equal("2018-10-31", mod2->parsed->includes[0].submodule->revs[0].date);
@@ -275,7 +275,7 @@
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, lys_implement(mod1, NULL, &unres));
assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
assert_non_null(mod1->compiled);
assert_non_null(mod1->parsed);
@@ -297,7 +297,7 @@
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod2));
assert_int_equal(LY_SUCCESS, _lys_set_implemented(mod2, NULL, &unres));
assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
assert_non_null(mod2);
assert_non_null(mod1->parsed);
@@ -394,20 +394,20 @@
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod));
assert_int_equal(LY_SUCCESS, lys_implement(mod, NULL, &unres));
assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
/* invalid attempts - implementing module of the same name and inserting the same module */
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in2, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod2));
assert_int_equal(LY_EDENIED, lys_implement(mod2, NULL, &unres));
CHECK_LOG_CTX("Module \"a@2018-10-24\" is present in the context in other implemented revision (2018-10-23).", NULL);
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_reset(in1);
/* it is already there, fine */
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres.creating, NULL));
/* insert the second module only as imported, not implemented */
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_reset(in2);
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in2, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod2));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
assert_non_null(mod2);
assert_ptr_not_equal(mod, mod2);
mod = ly_ctx_get_module_latest(UTEST_LYCTX, "a");
@@ -415,8 +415,8 @@
mod2 = ly_ctx_get_module_latest_ns(UTEST_LYCTX, mod->ns);
assert_ptr_equal(mod, mod2);
/* work with module with no revision */
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in0, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
assert_ptr_equal(mod, ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
assert_ptr_not_equal(mod, ly_ctx_get_module_latest(UTEST_LYCTX, "a"));
@@ -425,7 +425,7 @@
assert_int_equal(LY_SUCCESS, ly_in_new_memory(str1, &in1));
assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod));
CHECK_LOG_CTX("Input data contains submodule which cannot be parsed directly without its main module.", NULL);
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
while ((mod = (struct lys_module *)ly_ctx_get_module_iter(UTEST_LYCTX, &index))) {
assert_string_equal(names[index - 1], mod->name);
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index b8c70cc..4992cc8 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -79,13 +79,13 @@
assert_int_equal(LY_EINVAL, lys_compile(NULL, 0, NULL));
CHECK_LOG("Invalid argument mod (lys_compile()).", NULL);
assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
assert_int_equal(0, mod->implemented);
assert_int_equal(LY_SUCCESS, lys_implement(mod, NULL, &unres));
assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
assert_non_null(mod->compiled);
assert_string_equal("test", mod->name);
assert_string_equal("urn:test", mod->ns);
@@ -105,8 +105,8 @@
/* submodules cannot be compiled directly */
str = "submodule test {belongs-to xxx {prefix x;}}";
assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, NULL));
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
CHECK_LOG_CTX("Input data contains submodule which cannot be parsed directly without its main module.", NULL);
@@ -116,7 +116,7 @@
assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod));
assert_int_equal(LY_EEXIST, lys_implement(mod, NULL, &unres));
CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/aa:a");
- lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
+ lys_compile_unres_glob_erase(UTEST_LYCTX, &unres, 0);
ly_in_free(in, 0);
}