Skip to content

Commit 63495df

Browse files
committed
schema parsers BUGFIX creating implicit cases when augmenting choice
In the case of an implicit case (data node in the choice is specified without the case statement), libyang is supposed to add the case node to avoid problems with addressing that implicit case or anything inside it by another augments or anything else. This fixes the bug that the implicit case was not added for the data nodes added to a choice by augment. Fixes #889
1 parent aeb1bde commit 63495df

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

src/resolve.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4752,10 +4752,11 @@ static int
47524752
resolve_augment(struct lys_node_augment *aug, struct lys_node *uses, struct unres_schema *unres)
47534753
{
47544754
int rc;
4755-
struct lys_node *sub;
4755+
struct lys_node *sub, *next;
47564756
struct lys_module *mod;
47574757
struct ly_set *set;
47584758
struct ly_ctx *ctx;
4759+
struct lys_node_case *c;
47594760

47604761
assert(aug);
47614762
mod = lys_main_module(aug->module);
@@ -4840,6 +4841,41 @@ resolve_augment(struct lys_node_augment *aug, struct lys_node *uses, struct unre
48404841
}
48414842
}
48424843

4844+
if (aug->target->nodetype == LYS_CHOICE) {
4845+
/* in the case of implicit cases, we have to create the nodes representing them
4846+
* to serve as a target of the augments, they won't be printed, but they are expected in the tree */
4847+
LY_TREE_FOR_SAFE(aug->child, next, sub) {
4848+
if (sub->nodetype == LYS_CASE) {
4849+
/* explicit case */
4850+
continue;
4851+
}
4852+
4853+
c = calloc(1, sizeof *c);
4854+
LY_CHECK_ERR_RETURN(!c, LOGMEM(ctx), EXIT_FAILURE);
4855+
c->name = lydict_insert(ctx, sub->name, 0);
4856+
c->flags = LYS_IMPLICIT | (sub->flags & LYS_CONFIG_MASK);
4857+
c->module = sub->module;
4858+
c->nodetype = LYS_CASE;
4859+
c->parent = sub->parent;
4860+
c->prev = sub->prev != sub ? sub->prev : (struct lys_node*)c;
4861+
if (c->prev->next) {
4862+
c->prev->next = (struct lys_node*)c;
4863+
} else {
4864+
c->parent->child = (struct lys_node*)c;
4865+
}
4866+
c->next = sub->next;
4867+
if (c->next) {
4868+
c->next->prev = (struct lys_node*)c;
4869+
} else {
4870+
c->parent->child->prev = (struct lys_node*)c;
4871+
}
4872+
c->child = sub;
4873+
sub->prev = sub;
4874+
sub->next = NULL;
4875+
sub->parent = (struct lys_node*)c;
4876+
}
4877+
}
4878+
48434879
if (!aug->child) {
48444880
/* empty augment, nothing to connect, but it is techincally applied */
48454881
LOGWRN(ctx, "Augment \"%s\" without children.", aug->target_name);

tests/data/files/defaults2.yang

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ module defaults2 {
22
namespace "urn:defaults2";
33
prefix d;
44

5+
augment /d:oper/d:input/d:ch {
6+
container c1 {
7+
container c2 {
8+
leaf l {type string;}
9+
}
10+
}
11+
}
12+
513
list l1 {
614
key "k";
715
leaf k {
@@ -23,4 +31,10 @@ module defaults2 {
2331
when "/l1[k='when-true']";
2432
default "I exist!";
2533
}
34+
35+
rpc oper {
36+
input {
37+
choice ch;
38+
}
39+
}
2640
}

tests/data/test_defaults.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,18 @@ test_rpc_output_default(void **state)
456456
assert_string_equal(st->xml, xml2);
457457
}
458458

459+
static void
460+
test_rpc_augment(void **state)
461+
{
462+
struct state *st = (*state);
463+
const char *xml = "<oper xmlns=\"urn:defaults2\">"
464+
"<c1><c2><l>hi</l></c2></c1>"
465+
"</oper>";
466+
467+
st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_RPC, NULL);
468+
assert_ptr_not_equal(st->dt, NULL);
469+
}
470+
459471
static void
460472
test_notif_default(void **state)
461473
{
@@ -675,6 +687,7 @@ int main(void)
675687
cmocka_unit_test_setup_teardown(test_df4, setup_f, teardown_f),
676688
cmocka_unit_test_setup_teardown(test_rpc_input_default, setup_f, teardown_f),
677689
cmocka_unit_test_setup_teardown(test_rpc_output_default, setup_f, teardown_f),
690+
cmocka_unit_test_setup_teardown(test_rpc_augment, setup_f, teardown_f),
678691
cmocka_unit_test_setup_teardown(test_notif_default, setup_f, teardown_f),
679692
cmocka_unit_test_setup_teardown(test_val_diff, setup_f, teardown_f),
680693
cmocka_unit_test_setup_teardown(test_feature, setup_f, teardown_f),

0 commit comments

Comments
 (0)