Skip to content

Commit bc196fc

Browse files
committed
schema compile UPDATE improve duplicate identifier err message
Refs #2208
1 parent f4ba2ff commit bc196fc

File tree

2 files changed

+50
-38
lines changed

2 files changed

+50
-38
lines changed

src/schema_compile_node.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,11 +2342,13 @@ static LY_ERR
23422342
lys_compile_node_uniqness(struct lysc_ctx *ctx, const struct lysc_node *parent, const char *name,
23432343
const struct lysc_node *exclude)
23442344
{
2345-
const struct lysc_node *iter, *iter2;
2345+
const struct lysc_node *iter, *iter2, *dup = NULL;
23462346
const struct lysc_node_action *actions;
23472347
const struct lysc_node_notif *notifs;
23482348
uint32_t getnext_flags;
23492349
struct ly_set parent_choices = {0};
2350+
const char *node_type_str = "data definition/RPC/action/notification";
2351+
char *spath;
23502352

23512353
#define CHECK_NODE(iter, exclude, name) (iter != (void *)exclude && (iter)->module == exclude->module && !strcmp(name, (iter)->name))
23522354

@@ -2355,8 +2357,9 @@ lys_compile_node_uniqness(struct lysc_ctx *ctx, const struct lysc_node *parent,
23552357
assert(parent->nodetype == LYS_CHOICE);
23562358
LY_LIST_FOR(lysc_node_child(parent), iter) {
23572359
if (CHECK_NODE(iter, exclude, name)) {
2358-
LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, name, "case");
2359-
return LY_EEXIST;
2360+
node_type_str = "case";
2361+
dup = iter;
2362+
goto cleanup;
23602363
}
23612364
}
23622365

@@ -2394,31 +2397,35 @@ lys_compile_node_uniqness(struct lysc_ctx *ctx, const struct lysc_node *parent,
23942397
if (!parent && ctx->ext) {
23952398
while ((iter = lys_getnext_ext(iter, parent, ctx->ext, getnext_flags))) {
23962399
if (!ly_set_contains(&parent_choices, (void *)iter, NULL) && CHECK_NODE(iter, exclude, name)) {
2397-
goto error;
2400+
dup = iter;
2401+
goto cleanup;
23982402
}
23992403

24002404
/* we must compare with both the choice and all its nested data-definiition nodes (but not recursively) */
24012405
if (iter->nodetype == LYS_CHOICE) {
24022406
iter2 = NULL;
24032407
while ((iter2 = lys_getnext_ext(iter2, iter, NULL, 0))) {
24042408
if (CHECK_NODE(iter2, exclude, name)) {
2405-
goto error;
2409+
dup = iter2;
2410+
goto cleanup;
24062411
}
24072412
}
24082413
}
24092414
}
24102415
} else {
24112416
while ((iter = lys_getnext(iter, parent, ctx->cur_mod->compiled, getnext_flags))) {
24122417
if (!ly_set_contains(&parent_choices, (void *)iter, NULL) && CHECK_NODE(iter, exclude, name)) {
2413-
goto error;
2418+
dup = iter;
2419+
goto cleanup;
24142420
}
24152421

24162422
/* we must compare with both the choice and all its nested data-definiition nodes (but not recursively) */
24172423
if (iter->nodetype == LYS_CHOICE) {
24182424
iter2 = NULL;
24192425
while ((iter2 = lys_getnext(iter2, iter, NULL, 0))) {
24202426
if (CHECK_NODE(iter2, exclude, name)) {
2421-
goto error;
2427+
dup = iter2;
2428+
goto cleanup;
24222429
}
24232430
}
24242431
}
@@ -2427,24 +2434,29 @@ lys_compile_node_uniqness(struct lysc_ctx *ctx, const struct lysc_node *parent,
24272434
actions = parent ? lysc_node_actions(parent) : ctx->cur_mod->compiled->rpcs;
24282435
LY_LIST_FOR((struct lysc_node *)actions, iter) {
24292436
if (CHECK_NODE(iter, exclude, name)) {
2430-
goto error;
2437+
dup = iter;
2438+
goto cleanup;
24312439
}
24322440
}
24332441

24342442
notifs = parent ? lysc_node_notifs(parent) : ctx->cur_mod->compiled->notifs;
24352443
LY_LIST_FOR((struct lysc_node *)notifs, iter) {
24362444
if (CHECK_NODE(iter, exclude, name)) {
2437-
goto error;
2445+
dup = iter;
2446+
goto cleanup;
24382447
}
24392448
}
24402449
}
2441-
ly_set_erase(&parent_choices, NULL);
2442-
return LY_SUCCESS;
24432450

2444-
error:
2451+
cleanup:
24452452
ly_set_erase(&parent_choices, NULL);
2446-
LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, name, "data definition/RPC/action/notification");
2447-
return LY_EEXIST;
2453+
if (dup) {
2454+
spath = lysc_path(dup, LYSC_PATH_LOG, NULL, 0);
2455+
LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, spath, node_type_str);
2456+
free(spath);
2457+
return LY_EEXIST;
2458+
}
2459+
return LY_SUCCESS;
24482460

24492461
#undef CHECK_NODE
24502462
}

tests/utests/schema/test_tree_schema_compile.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ test_module(void **state)
114114
assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
115115
assert_int_equal(LY_EEXIST, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod));
116116
ly_in_free(in, 0);
117-
CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/aa:a", 0);
117+
CHECK_LOG_CTX("Duplicate identifier \"/aa:a\" of data definition/RPC/action/notification statement.", "/aa:a", 0);
118118
}
119119

120120
static void
@@ -146,23 +146,23 @@ test_name_collisions(void **state)
146146
" leaf c {type empty;}"
147147
"}";
148148
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
149-
CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
149+
CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
150150

151151
yang_data = "module a {namespace urn:a;prefix a;"
152152
" container c;"
153153
" leaf a {type empty;}"
154154
" notification c;"
155155
"}";
156156
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
157-
CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
157+
CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
158158

159159
yang_data = "module a {namespace urn:a;prefix a;"
160160
" container c;"
161161
" leaf a {type empty;}"
162162
" rpc c;"
163163
"}";
164164
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
165-
CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
165+
CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:c", 0);
166166

167167
yang_data = "module a {namespace urn:a;prefix a;"
168168
" container c;"
@@ -175,29 +175,29 @@ test_name_collisions(void **state)
175175
" }"
176176
"}";
177177
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
178-
CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:ch/c/c", 0);
178+
CHECK_LOG_CTX("Duplicate identifier \"/a:c\" of data definition/RPC/action/notification statement.", "/a:ch/c/c", 0);
179179

180180
/* nested */
181181
yang_data = "module a {namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}"
182182
"leaf-list a {type string;}"
183183
"container a;"
184184
"}}}";
185185
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
186-
CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
186+
CHECK_LOG_CTX("Duplicate identifier \"/a:c/l/a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
187187

188188
yang_data = "module a {yang-version 1.1;namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}"
189189
"leaf-list a {type string;}"
190190
"notification a;"
191191
"}}}";
192192
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
193-
CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
193+
CHECK_LOG_CTX("Duplicate identifier \"/a:c/l/a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
194194

195195
yang_data = "module a {yang-version 1.1;namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}"
196196
"leaf-list a {type string;}"
197197
"action a;"
198198
"}}}";
199199
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL));
200-
CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
200+
CHECK_LOG_CTX("Duplicate identifier \"/a:c/l/a\" of data definition/RPC/action/notification statement.", "/a:c/l/a", 0);
201201

202202
/* grouping */
203203
}
@@ -502,16 +502,16 @@ test_node_choice(void **state)
502502

503503
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;"
504504
"choice ch {case a {leaf x {type string;}}leaf x {type string;}}}", LYS_IN_YANG, NULL));
505-
CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/aa:ch/x/x", 0);
505+
CHECK_LOG_CTX("Duplicate identifier \"/aa:ch/a/x\" of data definition/RPC/action/notification statement.", "/aa:ch/x/x", 0);
506506
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module aa2 {namespace urn:aa2;prefix aa;"
507507
"choice ch {case a {leaf y {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL));
508-
CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/aa2:ch/b/y", 0);
508+
CHECK_LOG_CTX("Duplicate identifier \"/aa2:ch/a/y\" of data definition/RPC/action/notification statement.", "/aa2:ch/b/y", 0);
509509
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;"
510510
"choice ch {case a {leaf x {type string;}}leaf a {type string;}}}", LYS_IN_YANG, NULL));
511-
CHECK_LOG_CTX("Duplicate identifier \"a\" of case statement.", "/bb:ch/a", 0);
511+
CHECK_LOG_CTX("Duplicate identifier \"/bb:ch/a\" of case statement.", "/bb:ch/a", 0);
512512
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb2 {namespace urn:bb2;prefix bb;"
513513
"choice ch {case b {leaf x {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL));
514-
CHECK_LOG_CTX("Duplicate identifier \"b\" of case statement.", "/bb2:ch/b", 0);
514+
CHECK_LOG_CTX("Duplicate identifier \"/bb2:ch/b\" of case statement.", "/bb2:ch/b", 0);
515515

516516
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ca {namespace urn:ca;prefix ca;"
517517
"choice ch {default c;case a {leaf x {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL));
@@ -589,14 +589,14 @@ test_action(void **state)
589589

590590
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;leaf x{type string;} rpc x;}",
591591
LYS_IN_YANG, NULL));
592-
CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
592+
CHECK_LOG_CTX("Duplicate identifier \"/bb:x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
593593
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));
594-
CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
594+
CHECK_LOG_CTX("Duplicate identifier \"/cc:c/y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
595595
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));
596-
CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
596+
CHECK_LOG_CTX("Duplicate identifier \"/dd:c/z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
597597
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule eesub {belongs-to ee {prefix ee;} notification w;}");
598598
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));
599-
CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
599+
CHECK_LOG_CTX("Duplicate identifier \"/ee:w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
600600

601601
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;}}}}"
602602
"augment /test/input/a {action invalid {input {leaf x {type string;}}}}}", LYS_IN_YANG, NULL));
@@ -660,14 +660,14 @@ test_notification(void **state)
660660
NULL, 1);
661661

662662
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));
663-
CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
663+
CHECK_LOG_CTX("Duplicate identifier \"/bb:x\" of data definition/RPC/action/notification statement.", "/bb:x", 0);
664664
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));
665-
CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
665+
CHECK_LOG_CTX("Duplicate identifier \"/cc:c/y\" of data definition/RPC/action/notification statement.", "/cc:c/y", 0);
666666
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));
667-
CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
667+
CHECK_LOG_CTX("Duplicate identifier \"/dd:c/z\" of data definition/RPC/action/notification statement.", "/dd:c/z", 0);
668668
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule eesub {belongs-to ee {prefix ee;} rpc w;}");
669669
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));
670-
CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
670+
CHECK_LOG_CTX("Duplicate identifier \"/ee:w\" of data definition/RPC/action/notification statement.", "/ee:w", 0);
671671

672672
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;}}}}"
673673
"augment /test/input/a {notification invalid {leaf x {type string;}}}}", LYS_IN_YANG, NULL));
@@ -2633,7 +2633,7 @@ test_uses(void **state)
26332633

26342634
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd;grouping grp{leaf a{type string;}}"
26352635
"leaf a {type string;}uses grp;}", LYS_IN_YANG, &mod));
2636-
CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.",
2636+
CHECK_LOG_CTX("Duplicate identifier \"/dd:a\" of data definition/RPC/action/notification statement.",
26372637
"/dd:{uses='grp'}/dd:a", 0);
26382638

26392639
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 @@ test_uses(void **state)
26432643

26442644
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;grouping grp {leaf l {type string;}}"
26452645
"leaf l {type int8;}uses grp;}", LYS_IN_YANG, &mod));
2646-
CHECK_LOG_CTX("Duplicate identifier \"l\" of data definition/RPC/action/notification statement.",
2646+
CHECK_LOG_CTX("Duplicate identifier \"/ff:l\" of data definition/RPC/action/notification statement.",
26472647
"/ff:{uses='grp'}/ff:l", 0);
26482648
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module fg {namespace urn:fg;prefix fg;grouping grp {leaf m {type string;}}"
26492649
"uses grp;leaf m {type int8;}}", LYS_IN_YANG, &mod));
2650-
CHECK_LOG_CTX("Duplicate identifier \"m\" of data definition/RPC/action/notification statement.", "/fg:m", 0);
2650+
CHECK_LOG_CTX("Duplicate identifier \"/fg:m\" of data definition/RPC/action/notification statement.", "/fg:m", 0);
26512651

26522652
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg; grouping grp {container g;}"
26532653
"leaf g {type string;}"
@@ -2984,7 +2984,7 @@ test_augment(void **state)
29842984

29852985
assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb; container c {leaf a {type string;}}"
29862986
"augment /c {leaf a {type int8;}}}", LYS_IN_YANG, &mod));
2987-
CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/bb:{augment='/c'}/a", 0);
2987+
CHECK_LOG_CTX("Duplicate identifier \"/bb:c/a\" of data definition/RPC/action/notification statement.", "/bb:{augment='/c'}/a", 0);
29882988

29892989
assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc; container c {leaf a {type string;}}"
29902990
"augment /c/a {leaf a {type int8;}}}", LYS_IN_YANG, &mod));

0 commit comments

Comments
 (0)