xpath UPDATE store axis for atomized schema nodes
diff --git a/src/xpath.c b/src/xpath.c
index a8f08bd..5c7f39f 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -42,6 +42,8 @@
#include "tree_schema_internal.h"
#include "xml.h"
+static LY_ERR set_scnode_insert_node(struct lyxp_set *set, const struct lysc_node *node, enum lyxp_node_type node_type,
+ enum lyxp_axis axis, uint32_t *index_p);
static LY_ERR reparse_or_expr(const struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *tok_idx, uint16_t depth);
static LY_ERR eval_expr_select(const struct lyxp_expr *exp, uint16_t *tok_idx, enum lyxp_expr_type etype,
struct lyxp_set *set, uint32_t options);
@@ -885,8 +887,8 @@
if ((set->val.scnodes[i].in_ctx == LYXP_SET_SCNODE_ATOM_CTX) ||
(set->val.scnodes[i].in_ctx == LYXP_SET_SCNODE_START)) {
uint32_t idx;
- LY_CHECK_ERR_RET(lyxp_set_scnode_insert_node(ret, set->val.scnodes[i].scnode, set->val.scnodes[i].type, &idx),
- lyxp_set_free(ret), NULL);
+ LY_CHECK_ERR_RET(set_scnode_insert_node(ret, set->val.scnodes[i].scnode, set->val.scnodes[i].type,
+ set->val.scnodes[i].axis, &idx), lyxp_set_free(ret), NULL);
/* coverity seems to think scnodes can be NULL */
if (!ret->val.scnodes) {
lyxp_set_free(ret);
@@ -1310,9 +1312,20 @@
set_insert_node_hash(set, (struct lyd_node *)node, node_type);
}
-LY_ERR
-lyxp_set_scnode_insert_node(struct lyxp_set *set, const struct lysc_node *node, enum lyxp_node_type node_type,
- uint32_t *index_p)
+/**
+ * @brief Insert schema node into set.
+ *
+ * @param[in] set Set to insert into.
+ * @param[in] node Node to insert.
+ * @param[in] node_type Node type of @p node.
+ * @param[in] axis Axis that @p node was reached on.
+ * @param[out] index_p Optional pointer to store index if the inserted @p node.
+ * @return LY_SUCCESS on success.
+ * @return LY_EMEM on memory allocation failure.
+ */
+static LY_ERR
+set_scnode_insert_node(struct lyxp_set *set, const struct lysc_node *node, enum lyxp_node_type node_type,
+ enum lyxp_axis axis, uint32_t *index_p)
{
uint32_t index;
@@ -1331,6 +1344,7 @@
}
if (lyxp_set_scnode_contains(set, node, node_type, -1, &index)) {
+ /* BUG if axes differs, this new one is thrown away */
set->val.scnodes[index].in_ctx = LYXP_SET_SCNODE_ATOM_CTX;
} else {
if (set->used == set->size) {
@@ -1343,6 +1357,7 @@
set->val.scnodes[index].scnode = (struct lysc_node *)node;
set->val.scnodes[index].type = node_type;
set->val.scnodes[index].in_ctx = LYXP_SET_SCNODE_ATOM_CTX;
+ set->val.scnodes[index].axis = axis;
++set->used;
}
@@ -3927,10 +3942,10 @@
set_scnode_clear_ctx(set, LYXP_SET_SCNODE_ATOM_NODE);
if (set->cur_scnode) {
- LY_CHECK_RET(lyxp_set_scnode_insert_node(set, set->cur_scnode, LYXP_NODE_ELEM, NULL));
+ LY_CHECK_RET(set_scnode_insert_node(set, set->cur_scnode, LYXP_NODE_ELEM, LYXP_AXIS_SELF, NULL));
} else {
/* root node */
- LY_CHECK_RET(lyxp_set_scnode_insert_node(set, NULL, set->root_type, NULL));
+ LY_CHECK_RET(set_scnode_insert_node(set, NULL, set->root_type, LYXP_AXIS_SELF, NULL));
}
} else {
lyxp_set_free_content(set);
@@ -3996,7 +4011,7 @@
target = p[LY_ARRAY_COUNT(p) - 1].node;
ly_path_free(set->ctx, p);
- LY_CHECK_RET(lyxp_set_scnode_insert_node(set, target, LYXP_NODE_ELEM, NULL));
+ LY_CHECK_RET(set_scnode_insert_node(set, target, LYXP_NODE_ELEM, LYXP_AXIS_SELF, NULL));
} /* else the target was found before but is disabled so it was removed */
}
@@ -5633,7 +5648,7 @@
if (options & LYXP_SCNODE_ALL) {
set_scnode_clear_ctx(set, LYXP_SET_SCNODE_ATOM_NODE);
- LY_CHECK_RET(lyxp_set_scnode_insert_node(set, NULL, set->root_type, NULL));
+ LY_CHECK_RET(set_scnode_insert_node(set, NULL, set->root_type, LYXP_AXIS_SELF, NULL));
} else {
set->type = LYXP_SET_NODE_SET;
set->used = 0;
@@ -6682,7 +6697,7 @@
}
/* insert */
- LY_CHECK_RET(lyxp_set_scnode_insert_node(set, iter, iter_type, &idx));
+ LY_CHECK_RET(set_scnode_insert_node(set, iter, iter_type, axis, &idx));
/* we need to prevent these nodes from being considered in this moveto */
if ((idx < orig_used) && (idx > i)) {
@@ -6828,7 +6843,7 @@
goto skip_children;
}
} else {
- LY_CHECK_RET(lyxp_set_scnode_insert_node(set, elem, LYXP_NODE_ELEM, NULL));
+ LY_CHECK_RET(set_scnode_insert_node(set, elem, LYXP_NODE_ELEM, LYXP_AXIS_DESCENDANT, NULL));
}
} else if (rc == LY_EINVAL) {
goto skip_children;
@@ -9806,7 +9821,7 @@
memset(set, 0, sizeof *set);
set->type = LYXP_SET_SCNODE_SET;
set->root_type = lyxp_get_root_type(NULL, ctx_scnode, options);
- LY_CHECK_RET(lyxp_set_scnode_insert_node(set, ctx_scnode, ctx_scnode ? LYXP_NODE_ELEM : set->root_type, NULL));
+ LY_CHECK_RET(set_scnode_insert_node(set, ctx_scnode, ctx_scnode ? LYXP_NODE_ELEM : set->root_type, LYXP_AXIS_SELF, NULL));
set->val.scnodes[0].in_ctx = LYXP_SET_SCNODE_START;
set->ctx = (struct ly_ctx *)ctx;
diff --git a/src/xpath.h b/src/xpath.h
index 8215f8f..a711d94 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -274,6 +274,7 @@
a predicate and this scnode was used/will be used later */
int32_t in_ctx; /**< Flag specifies the state of the node in context. Values are defined
as LYXP_SET_SCNODE_* */
+ enum lyxp_axis axis; /**< Axis defines on what axis was this schema node reached. */
} *scnodes; /**< Set of compiled YANG data nodes. */
struct lyxp_set_meta {
struct lyd_meta *meta; /**< Node that provides information about metadata of a data element. */
@@ -397,19 +398,6 @@
void lyxp_set_free_content(struct lyxp_set *set);
/**
- * @brief Insert schema node into set.
- *
- * @param[in] set Set to insert into.
- * @param[in] node Node to insert.
- * @param[in] node_type Node type of @p node.
- * @param[out] index_p Optional pointer to store index if the inserted @p node.
- * @return LY_SUCCESS on success.
- * @return LY_EMEM on memory allocation failure.
- */
-LY_ERR lyxp_set_scnode_insert_node(struct lyxp_set *set, const struct lysc_node *node, enum lyxp_node_type node_type,
- uint32_t *index_p);
-
-/**
* @brief Check for duplicates in a schema node set.
*
* @param[in] set Set to check.