Skip to content

Commit 0b96311

Browse files
committed
schema tree CHANGE add xpath_dep flags for specific msut and when also
In addition to the flag being present on the node itself.
1 parent e446b09 commit 0b96311

File tree

7 files changed

+95
-55
lines changed

7 files changed

+95
-55
lines changed

src/resolve.c

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4052,9 +4052,8 @@ resolve_instid_predicate(const struct lys_module *prev_mod, const char *pred, st
40524052
int
40534053
lys_check_xpath(struct lys_node *node, int check_place, int warn_on_fwd_ref)
40544054
{
4055-
struct lys_node *parent, *elem;
4055+
struct lys_node *parent;
40564056
struct lyxp_set set;
4057-
uint32_t i;
40584057
int ret;
40594058

40604059
if (check_place) {
@@ -4077,33 +4076,11 @@ lys_check_xpath(struct lys_node *node, int check_place, int warn_on_fwd_ref)
40774076
}
40784077
}
40794078

4080-
ret = lyxp_node_atomize(node, &set, warn_on_fwd_ref);
4079+
ret = lyxp_node_atomize(node, &set, warn_on_fwd_ref, 1);
40814080
if (ret == -1) {
40824081
return -1;
40834082
}
40844083

4085-
for (parent = node; parent && !(parent->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)); parent = lys_parent(parent));
4086-
4087-
for (i = 0; i < set.used; ++i) {
4088-
/* skip roots'n'stuff */
4089-
if (set.val.snodes[i].type == LYXP_NODE_ELEM) {
4090-
/* XPath expression cannot reference "lower" status than the node that has the definition */
4091-
if (lyp_check_status(node->flags, lys_node_module(node), node->name, set.val.snodes[i].snode->flags,
4092-
lys_node_module(set.val.snodes[i].snode), set.val.snodes[i].snode->name, node)) {
4093-
return -1;
4094-
}
4095-
4096-
if (parent) {
4097-
for (elem = set.val.snodes[i].snode; elem && (elem != parent); elem = lys_parent(elem));
4098-
if (!elem) {
4099-
/* not in node's RPC or notification subtree, set the flag */
4100-
node->flags |= LYS_XPATH_DEP;
4101-
break;
4102-
}
4103-
}
4104-
}
4105-
}
4106-
41074084
free(set.val.snodes);
41084085
return ret;
41094086
}
@@ -5554,7 +5531,6 @@ resolve_list_keys(struct lys_node_list *list, const char *keys_str)
55545531
static int
55555532
resolve_must(struct lyd_node *node, int inout_parent, int ignore_fail)
55565533
{
5557-
int node_flags;
55585534
uint8_t i, must_size;
55595535
struct lys_node *schema;
55605536
struct lys_restr *must;
@@ -5574,8 +5550,6 @@ resolve_must(struct lyd_node *node, int inout_parent, int ignore_fail)
55745550
must_size = ((struct lys_node_inout *)schema)->must_size;
55755551
must = ((struct lys_node_inout *)schema)->must;
55765552

5577-
node_flags = schema->flags;
5578-
55795553
/* context node is the RPC/action */
55805554
node = node->parent;
55815555
if (!(node->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
@@ -5613,8 +5587,6 @@ resolve_must(struct lyd_node *node, int inout_parent, int ignore_fail)
56135587
must_size = 0;
56145588
break;
56155589
}
5616-
5617-
node_flags = node->schema->flags;
56185590
}
56195591

56205592
for (i = 0; i < must_size; ++i) {
@@ -5625,7 +5597,7 @@ resolve_must(struct lyd_node *node, int inout_parent, int ignore_fail)
56255597
lyxp_set_cast(&set, LYXP_SET_BOOLEAN, node, lyd_node_module(node), LYXP_MUST);
56265598

56275599
if (!set.val.bool) {
5628-
if ((ignore_fail == 1) || ((node_flags & LYS_XPATH_DEP) && (ignore_fail == 2))) {
5600+
if ((ignore_fail == 1) || ((must[i].flags & LYS_XPATH_DEP) && (ignore_fail == 2))) {
56295601
LOGVRB("Must condition \"%s\" not satisfied, but it is not required.", must[i].expr);
56305602
} else {
56315603
LOGVAL(LYE_NOMUST, LY_VLOG_LYD, node, must[i].expr);
@@ -5979,12 +5951,12 @@ resolve_applies_when(const struct lys_node *schema, int mode, const struct lys_n
59795951
*
59805952
* @return
59815953
* -1 - error, ly_errno is set
5982-
* 0 - true "when" statement
5983-
* 0, ly_vecode = LYVE_NOWHEN - false "when" statement
5954+
* 0 - all "when" statements true
5955+
* 0, ly_vecode = LYVE_NOWHEN - some "when" statement false, returned in failed_when
59845956
* 1, ly_vecode = LYVE_INWHEN - nodes needed to resolve are conditional and not yet resolved (under another "when")
59855957
*/
59865958
int
5987-
resolve_when(struct lyd_node *node, int ignore_fail)
5959+
resolve_when(struct lyd_node *node, int ignore_fail, struct lys_when **failed_when)
59885960
{
59895961
struct lyd_node *ctx_node = NULL, *unlinked_nodes, *tmp_node;
59905962
struct lys_node *sparent;
@@ -6012,11 +5984,15 @@ resolve_when(struct lyd_node *node, int ignore_fail)
60125984
lyxp_set_cast(&set, LYXP_SET_BOOLEAN, node, lyd_node_module(node), LYXP_WHEN);
60135985
if (!set.val.bool) {
60145986
node->when_status |= LYD_WHEN_FALSE;
6015-
if ((ignore_fail == 1) || ((node->schema->flags & LYS_XPATH_DEP) && (ignore_fail == 2))) {
5987+
if ((ignore_fail == 1)
5988+
|| ((((struct lys_node_container *)node->schema)->when->flags & LYS_XPATH_DEP) && (ignore_fail == 2))) {
60165989
LOGVRB("When condition \"%s\" is not satisfied, but it is not required.",
60175990
((struct lys_node_container *)node->schema)->when->cond);
60185991
} else {
60195992
LOGVAL(LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_container *)node->schema)->when->cond);
5993+
if (failed_when) {
5994+
*failed_when = ((struct lys_node_container *)node->schema)->when;
5995+
}
60205996
goto cleanup;
60215997
}
60225998
}
@@ -6066,12 +6042,16 @@ resolve_when(struct lyd_node *node, int ignore_fail)
60666042

60676043
lyxp_set_cast(&set, LYXP_SET_BOOLEAN, ctx_node, lys_node_module(sparent), LYXP_WHEN);
60686044
if (!set.val.bool) {
6069-
if ((ignore_fail == 1) || ((sparent->flags & LYS_XPATH_DEP) || (ignore_fail == 2))) {
6045+
if ((ignore_fail == 1)
6046+
|| ((((struct lys_node_uses *)sparent)->when->flags & LYS_XPATH_DEP) || (ignore_fail == 2))) {
60706047
LOGVRB("When condition \"%s\" is not satisfied, but it is not required.",
60716048
((struct lys_node_uses *)sparent)->when->cond);
60726049
} else {
60736050
node->when_status |= LYD_WHEN_FALSE;
60746051
LOGVAL(LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_uses *)sparent)->when->cond);
6052+
if (failed_when) {
6053+
*failed_when = ((struct lys_node_uses *)sparent)->when;
6054+
}
60756055
goto cleanup;
60766056
}
60776057
}
@@ -6120,11 +6100,15 @@ resolve_when(struct lyd_node *node, int ignore_fail)
61206100
lyxp_set_cast(&set, LYXP_SET_BOOLEAN, ctx_node, lys_node_module(sparent->parent), LYXP_WHEN);
61216101
if (!set.val.bool) {
61226102
node->when_status |= LYD_WHEN_FALSE;
6123-
if ((ignore_fail == 1) || ((sparent->parent->flags & LYS_XPATH_DEP) && (ignore_fail == 2))) {
6103+
if ((ignore_fail == 1)
6104+
|| ((((struct lys_node_augment *)sparent->parent)->when->flags & LYS_XPATH_DEP) && (ignore_fail == 2))) {
61246105
LOGVRB("When condition \"%s\" is not satisfied, but it is not required.",
61256106
((struct lys_node_augment *)sparent->parent)->when->cond);
61266107
} else {
61276108
LOGVAL(LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_augment *)sparent->parent)->when->cond);
6109+
if (failed_when) {
6110+
*failed_when = ((struct lys_node_augment *)sparent->parent)->when;
6111+
}
61286112
goto cleanup;
61296113
}
61306114
}
@@ -7586,7 +7570,7 @@ resolve_union(struct lyd_node_leaf_list *leaf, struct lys_type *type, int store,
75867570
* @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 on error.
75877571
*/
75887572
int
7589-
resolve_unres_data_item(struct lyd_node *node, enum UNRES_ITEM type, int ignore_fail)
7573+
resolve_unres_data_item(struct lyd_node *node, enum UNRES_ITEM type, int ignore_fail, struct lys_when **failed_when)
75907574
{
75917575
int rc, req_inst, ext_dep;
75927576
struct lyd_node_leaf_list *leaf;
@@ -7661,7 +7645,7 @@ resolve_unres_data_item(struct lyd_node *node, enum UNRES_ITEM type, int ignore_
76617645
return resolve_union(leaf, &sleaf->type, 1, ignore_fail, NULL);
76627646

76637647
case UNRES_WHEN:
7664-
if ((rc = resolve_when(node, ignore_fail))) {
7648+
if ((rc = resolve_when(node, ignore_fail, failed_when))) {
76657649
return rc;
76667650
}
76677651
break;
@@ -7737,6 +7721,7 @@ resolve_unres_data(struct unres_data *unres, struct lyd_node **root, int options
77377721
uint32_t i, j, first, resolved, del_items, stmt_count;
77387722
int rc, progress, ignore_fail;
77397723
struct lyd_node *parent;
7724+
struct lys_when *when;
77407725

77417726
assert(root);
77427727
assert(unres);
@@ -7791,12 +7776,12 @@ resolve_unres_data(struct unres_data *unres, struct lyd_node **root, int options
77917776
continue;
77927777
}
77937778

7794-
rc = resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail);
7779+
rc = resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, &when);
77957780
if (!rc) {
7796-
/* finish with error/delete the node only if when was false, an external dependency was required,
7797-
* and it was not provided (the flag would not be passed down otherwise, checked in upper fucntions) */
7781+
/* finish with error/delete the node only if when was false, an external dependency was not required,
7782+
* or it was not provided (the flag would not be passed down otherwise, checked in upper functions) */
77987783
if ((unres->node[i]->when_status & LYD_WHEN_FALSE)
7799-
&& (!(unres->node[i]->schema->flags & LYS_XPATH_DEP) || !(options & LYD_OPT_NOEXTDEPS))) {
7784+
&& (!(when->flags & LYS_XPATH_DEP) || !(options & LYD_OPT_NOEXTDEPS))) {
78007785
if ((options & LYD_OPT_NOAUTODEL) && !unres->node[i]->dflt) {
78017786
/* false when condition */
78027787
ly_vlog_hide(0);
@@ -7859,7 +7844,7 @@ resolve_unres_data(struct unres_data *unres, struct lyd_node **root, int options
78597844
} else if (rc == -1) {
78607845
ly_vlog_hide(0);
78617846
/* print only this last error */
7862-
resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail);
7847+
resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, NULL);
78637848
return -1;
78647849
} /* else forward reference */
78657850
}
@@ -7905,7 +7890,7 @@ resolve_unres_data(struct unres_data *unres, struct lyd_node **root, int options
79057890
stmt_count++;
79067891
}
79077892

7908-
rc = resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail);
7893+
rc = resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, NULL);
79097894
if (!rc) {
79107895
unres->type[i] = UNRES_RESOLVED;
79117896
ly_err_clean(1);
@@ -7914,7 +7899,7 @@ resolve_unres_data(struct unres_data *unres, struct lyd_node **root, int options
79147899
} else if (rc == -1) {
79157900
ly_vlog_hide(0);
79167901
/* print only this last error */
7917-
resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail);
7902+
resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, NULL);
79187903
return -1;
79197904
} /* else forward reference */
79207905
}
@@ -7937,7 +7922,7 @@ resolve_unres_data(struct unres_data *unres, struct lyd_node **root, int options
79377922
}
79387923
assert(!(options & LYD_OPT_TRUSTED) || ((unres->type[i] != UNRES_MUST) && (unres->type[i] != UNRES_MUST_INOUT)));
79397924

7940-
rc = resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail);
7925+
rc = resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, NULL);
79417926
if (rc) {
79427927
/* since when was already resolved, a forward reference is an error */
79437928
return -1;

src/resolve.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ struct lys_ident *resolve_identref(struct lys_type *type, const char *ident_name
208208

209209
int resolve_unres_schema(struct lys_module *mod, struct unres_schema *unres);
210210

211-
int resolve_when(struct lyd_node *node, int ignore_fail);
211+
int resolve_when(struct lyd_node *node, int ignore_fail, struct lys_when **failed_when);
212212

213213
int unres_schema_add_str(struct lys_module *mod, struct unres_schema *unres, void *item, enum UNRES_ITEM type,
214214
const char *str);
@@ -230,7 +230,7 @@ void unres_schema_free(struct lys_module *module, struct unres_schema **unres, i
230230
int resolve_union(struct lyd_node_leaf_list *leaf, struct lys_type *type, int store, int ignore_fail,
231231
struct lys_type **resolved_type);
232232

233-
int resolve_unres_data_item(struct lyd_node *dnode, enum UNRES_ITEM type, int ignore_fail);
233+
int resolve_unres_data_item(struct lyd_node *dnode, enum UNRES_ITEM type, int ignore_fail, struct lys_when **failed_when);
234234

235235
int unres_data_addonly(struct unres_data *unres, struct lyd_node *node, enum UNRES_ITEM type);
236236
int unres_data_add(struct unres_data *unres, struct lyd_node *node, enum UNRES_ITEM type);

src/tree_data.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ lyd_check_mandatory_data(struct lyd_node *root, struct lyd_node *last_parent,
103103
}
104104
for (current = dummy; current; current = current->child) {
105105
ly_vlog_hide(1);
106-
resolve_when(current, 0);
106+
resolve_when(current, 0, NULL);
107107
ly_vlog_hide(0);
108108
if (current->when_status & LYD_WHEN_FALSE) {
109109
/* when evaluates to false */

src/tree_schema.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3932,7 +3932,7 @@ lys_node_xpath_atomize(const struct lys_node *node, int options)
39323932
goto next_iter;
39333933
}
39343934

3935-
if (lyxp_node_atomize(elem, &set, 0)) {
3935+
if (lyxp_node_atomize(elem, &set, 0, 0)) {
39363936
ly_set_free(ret_set);
39373937
free(set.val.snodes);
39383938
return NULL;

src/tree_schema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,7 @@ struct lys_restr {
19331933
const char *emsg; /**< error-message (optional) */
19341934
struct lys_ext_instance **ext; /**< array of pointers to the extension instances */
19351935
uint8_t ext_size; /**< number of elements in #ext array */
1936+
uint8_t flags; /**< only one flag can be specified, #LYS_XPATH_DEP */
19361937
};
19371938

19381939
/**
@@ -1944,6 +1945,7 @@ struct lys_when {
19441945
const char *ref; /**< reference (optional) */
19451946
struct lys_ext_instance **ext; /**< array of pointers to the extension instances */
19461947
uint8_t ext_size; /**< number of elements in #ext array */
1948+
uint8_t flags; /**< only one flag can be specified, #LYS_XPATH_DEP */
19471949
};
19481950

19491951
/**

src/xpath.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7670,13 +7670,13 @@ lyxp_atomize(const char *expr, const struct lys_node *cur_snode, enum lyxp_node_
76707670
}
76717671

76727672
int
7673-
lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int warn_on_fwd_ref)
7673+
lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int warn_on_fwd_ref, int set_ext_dep_flags)
76747674
{
7675-
struct lys_node *parent;
7675+
struct lys_node *parent, *elem;
76767676
const struct lys_node *ctx_snode;
76777677
struct lyxp_set tmp_set;
76787678
uint8_t must_size = 0;
7679-
uint32_t i;
7679+
uint32_t i, j;
76807680
int opts, ret = EXIT_SUCCESS;
76817681
struct lys_when *when = NULL;
76827682
struct lys_restr *must = NULL;
@@ -7752,6 +7752,13 @@ lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int warn_on
77527752
ly_vlog_hide(1);
77537753
}
77547754

7755+
if (set_ext_dep_flags) {
7756+
/* find operation if in one, used later */
7757+
for (parent = (struct lys_node *)node;
7758+
parent && !(parent->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF));
7759+
parent = lys_parent(parent));
7760+
}
7761+
77557762
/* check "when" */
77567763
if (when) {
77577764
if (lyxp_atomize(when->cond, node, LYXP_NODE_ELEM, &tmp_set, LYXP_SNODE_WHEN | opts, &ctx_snode)) {
@@ -7776,6 +7783,28 @@ lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int warn_on
77767783
ret = EXIT_FAILURE;
77777784
memset(&tmp_set, 0, sizeof tmp_set);
77787785
} else {
7786+
if (set_ext_dep_flags) {
7787+
for (j = 0; j < tmp_set.used; ++j) {
7788+
/* skip roots'n'stuff */
7789+
if (tmp_set.val.snodes[j].type == LYXP_NODE_ELEM) {
7790+
/* XPath expression cannot reference "lower" status than the node that has the definition */
7791+
if (lyp_check_status(node->flags, lys_node_module(node), node->name, tmp_set.val.snodes[j].snode->flags,
7792+
lys_node_module(tmp_set.val.snodes[j].snode), tmp_set.val.snodes[j].snode->name, node)) {
7793+
return -1;
7794+
}
7795+
7796+
if (parent) {
7797+
for (elem = tmp_set.val.snodes[j].snode; elem && (elem != parent); elem = lys_parent(elem));
7798+
if (!elem) {
7799+
/* not in node's RPC or notification subtree, set the flag */
7800+
when->flags |= LYS_XPATH_DEP;
7801+
((struct lys_node *)node)->flags |= LYS_XPATH_DEP;
7802+
break;
7803+
}
7804+
}
7805+
}
7806+
}
7807+
}
77797808
set_snode_merge(set, &tmp_set);
77807809
memset(&tmp_set, 0, sizeof tmp_set);
77817810
}
@@ -7805,6 +7834,28 @@ lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int warn_on
78057834
ret = EXIT_FAILURE;
78067835
memset(&tmp_set, 0, sizeof tmp_set);
78077836
} else {
7837+
if (set_ext_dep_flags) {
7838+
for (j = 0; j < tmp_set.used; ++j) {
7839+
/* skip roots'n'stuff */
7840+
if (tmp_set.val.snodes[j].type == LYXP_NODE_ELEM) {
7841+
/* XPath expression cannot reference "lower" status than the node that has the definition */
7842+
if (lyp_check_status(node->flags, lys_node_module(node), node->name, tmp_set.val.snodes[j].snode->flags,
7843+
lys_node_module(tmp_set.val.snodes[j].snode), tmp_set.val.snodes[j].snode->name, node)) {
7844+
return -1;
7845+
}
7846+
7847+
if (parent) {
7848+
for (elem = tmp_set.val.snodes[j].snode; elem && (elem != parent); elem = lys_parent(elem));
7849+
if (!elem) {
7850+
/* not in node's RPC or notification subtree, set the flag */
7851+
must[i].flags |= LYS_XPATH_DEP;
7852+
((struct lys_node *)node)->flags |= LYS_XPATH_DEP;
7853+
break;
7854+
}
7855+
}
7856+
}
7857+
}
7858+
}
78087859
set_snode_merge(set, &tmp_set);
78097860
memset(&tmp_set, 0, sizeof tmp_set);
78107861
}

src/xpath.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,12 @@ int lyxp_atomize(const char *expr, const struct lys_node *cur_snode, enum lyxp_n
256256
* Will be cleared before use.
257257
* @param[in] warn_on_fwd_ref Setting this flag causes no errors to be printed and
258258
* only warning is printed on forward reference paths (addressing a non-existing node).
259+
* @param[in] set_ext_dep_flags Set #LYS_XPATH_DEP for conditions that require foreign subtree and
260+
* also for the node itself, if it has any such condition.
259261
*
260262
* @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 on error.
261263
*/
262-
int lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int warn_on_fwd_ref);
264+
int lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int warn_on_fwd_ref, int set_ext_dep_flags);
263265

264266
/**
265267
* @brief Check syntax of all the XPath expressions of the node.

0 commit comments

Comments
 (0)