compiled schema CHANGE must schema checking
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 0848805..59ab14d 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -3649,8 +3649,13 @@
LY_CHECK_RET(lys_compile_node(ctx, child_p, (struct lysc_node*)action, uses_status));
}
lysc_update_path(ctx, NULL, NULL);
-
lysc_update_path(ctx, NULL, NULL);
+
+ if ((action_p->input.musts || action_p->output.musts) && !(ctx->options & LYSC_OPT_GROUPING)) {
+ /* do not check "must" semantics in a grouping */
+ ly_set_add(&ctx->unres, action, 0);
+ }
+
cleanup:
ctx->options = opt_prev;
return ret;
@@ -3708,6 +3713,10 @@
DUP_STRING(ctx->ctx, notif_p->ref, notif->ref);
COMPILE_ARRAY_GOTO(ctx, notif_p->iffeatures, notif->iffeatures, u, lys_compile_iffeature, ret, cleanup);
COMPILE_ARRAY_GOTO(ctx, notif_p->musts, notif->musts, u, lys_compile_must, ret, cleanup);
+ if (notif_p->musts && !(ctx->options & LYSC_OPT_GROUPING)) {
+ /* do not check "must" semantics in a grouping */
+ ly_set_add(&ctx->unres, notif, 0);
+ }
COMPILE_EXTS_GOTO(ctx, notif_p->exts, notif->exts, notif, LYEXT_PAR_NODE, ret, cleanup);
ctx->options |= LYSC_OPT_NOTIFICATION;
@@ -3747,6 +3756,10 @@
}
COMPILE_ARRAY_GOTO(ctx, cont_p->musts, cont->musts, u, lys_compile_must, ret, done);
+ if (cont_p->musts && !(ctx->options & LYSC_OPT_GROUPING)) {
+ /* do not check "must" semantics in a grouping */
+ ly_set_add(&ctx->unres, cont, 0);
+ }
COMPILE_ARRAY1_GOTO(ctx, cont_p->actions, cont->actions, node, u, lys_compile_action, 0, ret, done);
COMPILE_ARRAY1_GOTO(ctx, cont_p->notifs, cont->notifs, node, u, lys_compile_notif, 0, ret, done);
@@ -3828,6 +3841,10 @@
LY_ERR ret = LY_SUCCESS;
COMPILE_ARRAY_GOTO(ctx, leaf_p->musts, leaf->musts, u, lys_compile_must, ret, done);
+ if (leaf_p->musts && !(ctx->options & LYSC_OPT_GROUPING)) {
+ /* do not check "must" semantics in a grouping */
+ ly_set_add(&ctx->unres, leaf, 0);
+ }
if (leaf_p->units) {
leaf->units = lydict_insert(ctx->ctx, leaf_p->units, 0);
leaf->flags |= LYS_SET_UNITS;
@@ -3889,6 +3906,10 @@
LY_ERR ret = LY_SUCCESS;
COMPILE_ARRAY_GOTO(ctx, llist_p->musts, llist->musts, u, lys_compile_must, ret, done);
+ if (llist_p->musts && !(ctx->options & LYSC_OPT_GROUPING)) {
+ /* do not check "must" semantics in a grouping */
+ ly_set_add(&ctx->unres, llist, 0);
+ }
if (llist_p->units) {
llist->units = lydict_insert(ctx->ctx, llist_p->units, 0);
llist->flags |= LYS_SET_UNITS;
@@ -4070,6 +4091,10 @@
}
COMPILE_ARRAY_GOTO(ctx, list_p->musts, list->musts, u, lys_compile_must, ret, done);
+ if (list_p->musts && !(ctx->options & LYSC_OPT_GROUPING)) {
+ /* do not check "must" semantics in a grouping */
+ ly_set_add(&ctx->unres, list, 0);
+ }
/* keys */
if ((list->flags & LYS_CONFIG_W) && (!list_p->key || !list_p->key[0])) {
@@ -4369,6 +4394,10 @@
LY_ERR ret = LY_SUCCESS;
COMPILE_ARRAY_GOTO(ctx, any_p->musts, any->musts, u, lys_compile_must, ret, done);
+ if (any_p->musts && !(ctx->options & LYSC_OPT_GROUPING)) {
+ /* do not check "must" semantics in a grouping */
+ ly_set_add(&ctx->unres, any, 0);
+ }
if (any->flags & LYS_CONFIG_W) {
LOGWRN(ctx->ctx, "Use of %s to define configuration data is not recommended.",
@@ -5294,6 +5323,7 @@
lys_nodetype2str(node->nodetype));
goto cleanup;
}
+ ly_set_add(&ctx->unres, node, 0);
}
/* min/max-elements */
@@ -6107,6 +6137,7 @@
lys_nodetype2str(devs[u]->target->nodetype), "add", "must");
goto cleanup;
}
+ ly_set_add(&ctx->unres, devs[u]->target, 0);
}
/* *unique-stmt */
@@ -6970,20 +7001,13 @@
struct lysc_node *parent, *elem;
struct lyxp_set tmp_set;
uint32_t i, j;
- int opts;
+ int opts, input_done = 0;
struct lysc_when **when = NULL;
struct lysc_must *musts = NULL;
LY_ERR ret = LY_SUCCESS;
memset(&tmp_set, 0, sizeof tmp_set);
-
- /* check if we will be traversing RPC output */
- for (parent = (struct lysc_node *)node; parent && (parent->nodetype != LYS_ACTION); parent = parent->parent);
- if (parent && (node->flags & LYS_CONFIG_R)) {
- opts = LYXP_SCNODE_OUTPUT;
- } else {
- opts = LYXP_SCNODE_SCHEMA;
- }
+ opts = LYXP_SCNODE_SCHEMA;
switch (node->nodetype) {
case LYS_CONTAINER:
@@ -7016,6 +7040,10 @@
case LYS_NOTIF:
musts = ((struct lysc_notif *)node)->musts;
break;
+ case LYS_ACTION:
+ /* first process input musts */
+ musts = ((struct lysc_action *)node)->input.musts;
+ break;
default:
/* nothing to check */
break;
@@ -7061,6 +7089,7 @@
lyxp_set_cast(&tmp_set, LYXP_SET_EMPTY);
}
+check_musts:
/* check "must" */
LY_ARRAY_FOR(musts, i) {
lyxp_set_cast(&tmp_set, LYXP_SET_EMPTY);
@@ -7076,7 +7105,7 @@
/* skip roots'n'stuff */
if (tmp_set.val.scnodes[j].type == LYXP_NODE_ELEM) {
/* XPath expression cannot reference "lower" status than the node that has the definition */
- ret = lysc_check_status(ctx, musts[i].flags, musts[i].module, node->name, tmp_set.val.scnodes[j].scnode->flags,
+ ret = lysc_check_status(ctx, node->flags, musts[i].module, node->name, tmp_set.val.scnodes[j].scnode->flags,
tmp_set.val.scnodes[j].scnode->module, tmp_set.val.scnodes[j].scnode->name);
LY_CHECK_GOTO(ret, cleanup);
@@ -7094,6 +7123,14 @@
lyxp_set_cast(&tmp_set, LYXP_SET_EMPTY);
}
+ if ((node->nodetype == LYS_ACTION) && !input_done) {
+ /* now check output musts */
+ input_done = 1;
+ musts = ((struct lysc_action *)node)->output.musts;
+ opts = LYXP_SCNODE_OUTPUT;
+ goto check_musts;
+ }
+
cleanup:
lyxp_set_cast(&tmp_set, LYXP_SET_EMPTY);
return ret;