schema tree CHANGE keep compiled identities on a single place
Instead of moving identities between lys_module and lysc_module, keep them
in lys_module structure and save some work and confusion which member is
used.
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 5953bbe..ed2981a 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -1236,11 +1236,8 @@
rc = asprintf(&errmsg, "Invalid identityref \"%.*s\" value - unable to map prefix to YANG schema.", (int)value_len, value);
goto error;
}
- if (mod->compiled) {
- identities = mod->compiled->identities;
- } else {
- identities = mod->dis_identities;
- }
+
+ identities = mod->identities;
LY_ARRAY_FOR(identities, u) {
ident = &identities[u]; /* shortcut */
if (!ly_strncmp(ident->name, id_name, id_len)) {
diff --git a/src/printer_yang.c b/src/printer_yang.c
index 1067250..a173084 100644
--- a/src/printer_yang.c
+++ b/src/printer_yang.c
@@ -2355,8 +2355,8 @@
yprc_feature(ctx, &module->features[u]);
}
- LY_ARRAY_FOR(modc->identities, u) {
- yprc_identity(ctx, &modc->identities[u]);
+ LY_ARRAY_FOR(module->identities, u) {
+ yprc_identity(ctx, &module->identities[u]);
}
if (!(ctx->options & LYS_PRINT_NO_SUBSTMT)) {
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 8151787..fb77d58 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1121,7 +1121,7 @@
if (!mod->implemented) {
/* pre-compile features and identities of the module */
LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, mod->parsed->features, &mod->features), error);
- LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->identities, &mod->dis_identities), error);
+ LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->identities, &mod->identities), error);
}
if (latest) {
@@ -1143,7 +1143,7 @@
LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, mod->parsed->includes[u].submodule->features,
&mod->features), error);
LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->includes[u].submodule->identities,
- &mod->dis_identities), error);
+ &mod->identities), error);
}
}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 134ab30..3884129 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -1644,7 +1644,6 @@
struct lysc_module {
struct lys_module *mod; /**< covering module structure */
- struct lysc_ident *identities; /**< list of identities ([sized array](@ref sizedarrays)) */
struct lysc_node *data; /**< list of module's top-level data nodes (linked list) */
struct lysc_action *rpcs; /**< list of RPCs ([sized array](@ref sizedarrays)) */
struct lysc_notif *notifs; /**< list of notifications ([sized array](@ref sizedarrays)) */
@@ -1834,10 +1833,12 @@
from if-feature statements of the compiled schemas and their proper use in case
the module became implemented in future (no matter if implicitly via augment/deviate
or explicitly via ::lys_set_implemented()). */
- struct lysc_ident *dis_identities;/**< List of pre-compiled identities in a non-implemented module ([sized array](@ref sizedarrays))
- These identities cannot be instantiated in data (in identityrefs) until
- the module is implemented but can be linked by identities in implemented
- modules. */
+ struct lysc_ident *identities; /**< List of compiled identities of the module ([sized array](@ref sizedarrays))
+ Identities are outside the compiled tree to allow their linkage to the identities from
+ the implemented modules. This avoids problems when the module became implemented in
+ future (no matter if implicitly via augment/deviate or explicitly via
+ ::lys_set_implemented()). Note that if the module is not implemented (compiled), the
+ identities cannot be instantiated in data (in identityrefs). */
uint8_t implemented; /**< flag if the module is implemented, not just imported. The module is implemented if
the flag has non-zero value. Specific values are used internally:
1 - implemented module
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 9ee36b9..61edac2 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -1119,7 +1119,7 @@
LY_ARRAY_COUNT_TYPE u, v;
const char *s, *name;
struct lys_module *mod;
- struct lysc_ident **idref, *identities;
+ struct lysc_ident **idref;
assert(ident || bases);
@@ -1151,27 +1151,22 @@
}
idref = NULL;
- if (mod->compiled) {
- identities = mod->compiled->identities;
- } else {
- identities = mod->dis_identities;
- }
- LY_ARRAY_FOR(identities, v) {
- if (!strcmp(name, identities[v].name)) {
+ LY_ARRAY_FOR(mod->identities, v) {
+ if (!strcmp(name, mod->identities[v].name)) {
if (ident) {
- if (ident == &identities[v]) {
+ if (ident == &mod->identities[v]) {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
"Identity \"%s\" is derived from itself.", ident->name);
return LY_EVALID;
}
- LY_CHECK_RET(lys_compile_identity_circular_check(ctx, &identities[v], ident->derived));
+ LY_CHECK_RET(lys_compile_identity_circular_check(ctx, &mod->identities[v], ident->derived));
/* we have match! store the backlink */
- LY_ARRAY_NEW_RET(ctx->ctx, identities[v].derived, idref, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, mod->identities[v].derived, idref, LY_EMEM);
*idref = ident;
} else {
/* we have match! store the found identity */
LY_ARRAY_NEW_RET(ctx->ctx, *bases, idref, LY_EMEM);
- *idref = &identities[v];
+ *idref = &mod->identities[v];
}
break;
}
@@ -6621,10 +6616,8 @@
ret = lys_feature_precompile(ctx, NULL, NULL, submod->features, &mainmod->mod->features);
LY_CHECK_GOTO(ret, error);
- if (!mainmod->mod->dis_identities) {
- ret = lys_identity_precompile(ctx, NULL, NULL, submod->identities, &mainmod->identities);
- LY_CHECK_GOTO(ret, error);
- }
+ ret = lys_identity_precompile(ctx, NULL, NULL, submod->identities, &mainmod->mod->identities);
+ LY_CHECK_GOTO(ret, error);
/* data nodes */
LY_LIST_FOR(submod->data, node_p) {
@@ -7348,11 +7341,8 @@
} /* else the features are already precompiled */
/* similarly, identities precompilation */
- if (mod->dis_identities) {
- mod_c->identities = mod->dis_identities;
- mod->dis_identities = NULL;
- } else {
- ret = lys_identity_precompile(&ctx, NULL, NULL, sp->identities, &mod_c->identities);
+ if (!mod->identities && sp->identities) {
+ ret = lys_identity_precompile(&ctx, NULL, NULL, sp->identities, &mod->identities);
LY_CHECK_GOTO(ret, error);
}
@@ -7383,13 +7373,13 @@
/* identities, work similarly to features with the precompilation */
if (sp->identities) {
- LY_CHECK_GOTO(ret = lys_compile_identities_derived(&ctx, sp->identities, mod_c->identities), error);
+ LY_CHECK_GOTO(ret = lys_compile_identities_derived(&ctx, sp->identities, mod->identities), error);
}
lysc_update_path(&ctx, NULL, "{submodule}");
LY_ARRAY_FOR(sp->includes, v) {
if (sp->includes[v].submodule->identities) {
lysc_update_path(&ctx, NULL, sp->includes[v].name);
- ret = lys_compile_identities_derived(&ctx, sp->includes[v].submodule->identities, mod_c->identities);
+ ret = lys_compile_identities_derived(&ctx, sp->includes[v].submodule->identities, mod->identities);
LY_CHECK_GOTO(ret, error);
lysc_update_path(&ctx, NULL, NULL);
}
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 2dadee5..1542fb0 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -830,8 +830,6 @@
LY_CHECK_ARG_RET(NULL, module, );
ctx = module->mod->ctx;
- FREE_ARRAY(ctx, module->identities, lysc_ident_free);
-
LY_LIST_FOR_SAFE(module->data, node_next, node) {
lysc_node_free(ctx, node);
}
@@ -864,7 +862,7 @@
lysc_module_free(module->compiled, private_destructor);
FREE_ARRAY(module->ctx, module->features, lysc_feature_free);
- FREE_ARRAY(module->ctx, module->dis_identities, lysc_ident_free);
+ FREE_ARRAY(module->ctx, module->identities, lysc_ident_free);
lysp_module_free(module->parsed);
FREE_STRING(module->ctx, module->name);
diff --git a/tests/utests/schema/test_schema_stmts.c b/tests/utests/schema/test_schema_stmts.c
index fbd9443..eeb0673 100644
--- a/tests/utests/schema/test_schema_stmts.c
+++ b/tests/utests/schema/test_schema_stmts.c
@@ -96,26 +96,25 @@
"identity b1; identity b2; identity b3 {base b1; base b:b2; base a:a1;}"
"identity b4 {base b:b1; base b3;}", mod);
assert_non_null(mod_imp->compiled);
- assert_non_null(mod_imp->compiled->identities);
- assert_non_null(mod->compiled);
- assert_non_null(mod->compiled->identities);
- assert_non_null(mod_imp->compiled->identities[0].derived);
- assert_int_equal(1, LY_ARRAY_COUNT(mod_imp->compiled->identities[0].derived));
- assert_ptr_equal(mod_imp->compiled->identities[0].derived[0], &mod->compiled->identities[2]);
- assert_non_null(mod->compiled->identities[0].derived);
- assert_int_equal(2, LY_ARRAY_COUNT(mod->compiled->identities[0].derived));
- assert_ptr_equal(mod->compiled->identities[0].derived[0], &mod->compiled->identities[2]);
- assert_ptr_equal(mod->compiled->identities[0].derived[1], &mod->compiled->identities[3]);
- assert_non_null(mod->compiled->identities[1].derived);
- assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->identities[1].derived));
- assert_ptr_equal(mod->compiled->identities[1].derived[0], &mod->compiled->identities[2]);
- assert_non_null(mod->compiled->identities[2].derived);
- assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->identities[2].derived));
- assert_ptr_equal(mod->compiled->identities[2].derived[0], &mod->compiled->identities[3]);
+ assert_non_null(mod_imp->identities);
+ assert_non_null(mod->identities);
+ assert_non_null(mod_imp->identities[0].derived);
+ assert_int_equal(1, LY_ARRAY_COUNT(mod_imp->identities[0].derived));
+ assert_ptr_equal(mod_imp->identities[0].derived[0], &mod->identities[2]);
+ assert_non_null(mod->identities[0].derived);
+ assert_int_equal(2, LY_ARRAY_COUNT(mod->identities[0].derived));
+ assert_ptr_equal(mod->identities[0].derived[0], &mod->identities[2]);
+ assert_ptr_equal(mod->identities[0].derived[1], &mod->identities[3]);
+ assert_non_null(mod->identities[1].derived);
+ assert_int_equal(1, LY_ARRAY_COUNT(mod->identities[1].derived));
+ assert_ptr_equal(mod->identities[1].derived[0], &mod->identities[2]);
+ assert_non_null(mod->identities[2].derived);
+ assert_int_equal(1, LY_ARRAY_COUNT(mod->identities[2].derived));
+ assert_ptr_equal(mod->identities[2].derived[0], &mod->identities[3]);
TEST_SCHEMA_OK(ctx, 1, 0, "c", "identity c2 {base c1;} identity c1;", mod);
- assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->identities[1].derived));
- assert_ptr_equal(mod->compiled->identities[1].derived[0], &mod->compiled->identities[0]);
+ assert_int_equal(1, LY_ARRAY_COUNT(mod->identities[1].derived));
+ assert_ptr_equal(mod->identities[1].derived[0], &mod->identities[0]);
TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "identity i1;identity i1;", "Duplicate identifier \"i1\" of identity statement. /inv:{identity='i1'}");