schema compile UPDATE improve duplicate identifier err message
Refs #2208
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index c7724ec..4187575 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -2342,11 +2342,13 @@
lys_compile_node_uniqness(struct lysc_ctx *ctx, const struct lysc_node *parent, const char *name,
const struct lysc_node *exclude)
{
- const struct lysc_node *iter, *iter2;
+ const struct lysc_node *iter, *iter2, *dup = NULL;
const struct lysc_node_action *actions;
const struct lysc_node_notif *notifs;
uint32_t getnext_flags;
struct ly_set parent_choices = {0};
+ const char *node_type_str = "data definition/RPC/action/notification";
+ char *spath;
#define CHECK_NODE(iter, exclude, name) (iter != (void *)exclude && (iter)->module == exclude->module && !strcmp(name, (iter)->name))
@@ -2355,8 +2357,9 @@
assert(parent->nodetype == LYS_CHOICE);
LY_LIST_FOR(lysc_node_child(parent), iter) {
if (CHECK_NODE(iter, exclude, name)) {
- LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, name, "case");
- return LY_EEXIST;
+ node_type_str = "case";
+ dup = iter;
+ goto cleanup;
}
}
@@ -2394,7 +2397,8 @@
if (!parent && ctx->ext) {
while ((iter = lys_getnext_ext(iter, parent, ctx->ext, getnext_flags))) {
if (!ly_set_contains(&parent_choices, (void *)iter, NULL) && CHECK_NODE(iter, exclude, name)) {
- goto error;
+ dup = iter;
+ goto cleanup;
}
/* we must compare with both the choice and all its nested data-definiition nodes (but not recursively) */
@@ -2402,7 +2406,8 @@
iter2 = NULL;
while ((iter2 = lys_getnext_ext(iter2, iter, NULL, 0))) {
if (CHECK_NODE(iter2, exclude, name)) {
- goto error;
+ dup = iter2;
+ goto cleanup;
}
}
}
@@ -2410,7 +2415,8 @@
} else {
while ((iter = lys_getnext(iter, parent, ctx->cur_mod->compiled, getnext_flags))) {
if (!ly_set_contains(&parent_choices, (void *)iter, NULL) && CHECK_NODE(iter, exclude, name)) {
- goto error;
+ dup = iter;
+ goto cleanup;
}
/* we must compare with both the choice and all its nested data-definiition nodes (but not recursively) */
@@ -2418,7 +2424,8 @@
iter2 = NULL;
while ((iter2 = lys_getnext(iter2, iter, NULL, 0))) {
if (CHECK_NODE(iter2, exclude, name)) {
- goto error;
+ dup = iter2;
+ goto cleanup;
}
}
}
@@ -2427,24 +2434,29 @@
actions = parent ? lysc_node_actions(parent) : ctx->cur_mod->compiled->rpcs;
LY_LIST_FOR((struct lysc_node *)actions, iter) {
if (CHECK_NODE(iter, exclude, name)) {
- goto error;
+ dup = iter;
+ goto cleanup;
}
}
notifs = parent ? lysc_node_notifs(parent) : ctx->cur_mod->compiled->notifs;
LY_LIST_FOR((struct lysc_node *)notifs, iter) {
if (CHECK_NODE(iter, exclude, name)) {
- goto error;
+ dup = iter;
+ goto cleanup;
}
}
}
- ly_set_erase(&parent_choices, NULL);
- return LY_SUCCESS;
-error:
+cleanup:
ly_set_erase(&parent_choices, NULL);
- LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, name, "data definition/RPC/action/notification");
- return LY_EEXIST;
+ if (dup) {
+ spath = lysc_path(dup, LYSC_PATH_LOG, NULL, 0);
+ LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, spath, node_type_str);
+ free(spath);
+ return LY_EEXIST;
+ }
+ return LY_SUCCESS;
#undef CHECK_NODE
}
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index c2a13cd..f626360 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -114,7 +114,7 @@
assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
assert_int_equal(LY_EEXIST, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod));
ly_in_free(in, 0);
- CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/aa:a", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/aa:a\" of data definition/RPC/action/notification statement.", "/aa:a", 0);
}
static void
@@ -146,7 +146,7 @@
" leaf c {type empty;}"
"}";
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
yang_data = "module a {namespace urn:a;prefix a;"
" container c;"
@@ -154,7 +154,7 @@
" notification c;"
"}";
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
yang_data = "module a {namespace urn:a;prefix a;"
" container c;"
@@ -162,7 +162,7 @@
" rpc c;"
"}";
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
yang_data = "module a {namespace urn:a;prefix a;"
" container c;"
@@ -175,7 +175,7 @@
" }"
"}";
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:ch/c/c", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:ch/c/c", 0);
/* nested */
yang_data = "module a {namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}"
@@ -183,21 +183,21 @@
"container a;"
"}}}";
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/a:c/l/a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
yang_data = "module a {yang-version 1.1;namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}"
"leaf-list a {type string;}"
"notification a;"
"}}}";
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/a:c/l/a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
yang_data = "module a {yang-version 1.1;namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}"
"leaf-list a {type string;}"
"action a;"
"}}}";
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/a:c/l/a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
/* grouping */
}
@@ -502,16 +502,16 @@
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;"
"choice ch {case a {leaf x {type string;}}leaf x {type string;}}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/aa:ch/x/x", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/aa:ch/a/x\" of data definition/RPC/action/notification statement.", "/aa:ch/x/x", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module aa2 {namespace urn:aa2;prefix aa;"
"choice ch {case a {leaf y {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/aa2:ch/b/y", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/aa2:ch/a/y\" of data definition/RPC/action/notification statement.", "/aa2:ch/b/y", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;"
"choice ch {case a {leaf x {type string;}}leaf a {type string;}}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"a\" of case statement.", "/bb:ch/a", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/bb:ch/a\" of case statement.", "/bb:ch/a", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb2 {namespace urn:bb2;prefix bb;"
"choice ch {case b {leaf x {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"b\" of case statement.", "/bb2:ch/b", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/bb2:ch/b\" of case statement.", "/bb2:ch/b", 0);
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ca {namespace urn:ca;prefix ca;"
"choice ch {default c;case a {leaf x {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL));
@@ -589,14 +589,14 @@
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;leaf x{type string;} rpc x;}",
LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/bb:x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module cc {yang-version 1.1; namespace urn:cc;prefix cc;container c {leaf y {type string;} action y;}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/cc:c/y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {yang-version 1.1; namespace urn:dd;prefix dd;container c {action z; action z;}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/dd:c/z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule eesub {belongs-to ee {prefix ee;} notification w;}");
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ee {yang-version 1.1; namespace urn:ee;prefix ee;include eesub; rpc w;}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/ee:w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {yang-version 1.1; namespace urn:ff;prefix ff; rpc test {input {container a {leaf b {type string;}}}}"
"augment /test/input/a {action invalid {input {leaf x {type string;}}}}}", LYS_IN_YANG, NULL));
@@ -660,14 +660,14 @@
NULL, 1);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;leaf x{type string;} notification x;}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/bb:x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module cc {yang-version 1.1; namespace urn:cc;prefix cc;container c {leaf y {type string;} notification y;}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/cc:c/y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {yang-version 1.1; namespace urn:dd;prefix dd;container c {notification z; notification z;}}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/dd:c/z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule eesub {belongs-to ee {prefix ee;} rpc w;}");
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ee {yang-version 1.1; namespace urn:ee;prefix ee;include eesub; notification w;}", LYS_IN_YANG, NULL));
- CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/ee:w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {yang-version 1.1; namespace urn:ff;prefix ff; rpc test {input {container a {leaf b {type string;}}}}"
"augment /test/input/a {notification invalid {leaf x {type string;}}}}", LYS_IN_YANG, NULL));
@@ -2633,7 +2633,7 @@
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd;grouping grp{leaf a{type string;}}"
"leaf a {type string;}uses grp;}", LYS_IN_YANG, &mod));
- CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.",
+ CHECK_LOG_CTX("Duplicate identifier \"/dd:a\" of data definition/RPC/action/notification statement.",
"/dd:{uses='grp'}/dd:a", 0);
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;grouping grp {leaf l {type string; status deprecated;}}"
@@ -2643,11 +2643,11 @@
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;grouping grp {leaf l {type string;}}"
"leaf l {type int8;}uses grp;}", LYS_IN_YANG, &mod));
- CHECK_LOG_CTX("Duplicate identifier \"l\" of data definition/RPC/action/notification statement.",
+ CHECK_LOG_CTX("Duplicate identifier \"/ff:l\" of data definition/RPC/action/notification statement.",
"/ff:{uses='grp'}/ff:l", 0);
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module fg {namespace urn:fg;prefix fg;grouping grp {leaf m {type string;}}"
"uses grp;leaf m {type int8;}}", LYS_IN_YANG, &mod));
- CHECK_LOG_CTX("Duplicate identifier \"m\" of data definition/RPC/action/notification statement.", "/fg:m", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/fg:m\" of data definition/RPC/action/notification statement.", "/fg:m", 0);
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg; grouping grp {container g;}"
"leaf g {type string;}"
@@ -2984,7 +2984,7 @@
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb; container c {leaf a {type string;}}"
"augment /c {leaf a {type int8;}}}", LYS_IN_YANG, &mod));
- CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/bb:{augment='/c'}/a", 0);
+ CHECK_LOG_CTX("Duplicate identifier \"/bb:c/a\" of data definition/RPC/action/notification statement.", "/bb:{augment='/c'}/a", 0);
assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc; container c {leaf a {type string;}}"
"augment /c/a {leaf a {type int8;}}}", LYS_IN_YANG, &mod));