data tree FEATURE new utility function for getting data schema parent
diff --git a/src/tree_data.c b/src/tree_data.c
index b35befc..b7d21b7 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1075,14 +1075,10 @@
const struct lysc_node *par2;
assert(schema);
-
- /* adjust parent first */
- while (parent && (parent->nodetype & (LYS_CASE | LYS_CHOICE))) {
- parent = parent->parent;
- }
+ assert(!parent || !(parent->nodetype & (LYS_CASE | LYS_CHOICE)));
/* find schema parent */
- for (par2 = schema->parent; par2 && (par2->nodetype & (LYS_CASE | LYS_CHOICE)); par2 = par2->parent);
+ par2 = lysc_data_parent(schema);
if (parent) {
/* inner node */
@@ -1135,7 +1131,7 @@
LY_CHECK_ARG_RET(NULL, sibling, node, LY_EINVAL);
- LY_CHECK_RET(lyd_insert_check_schema(sibling->schema->parent, node->schema));
+ LY_CHECK_RET(lyd_insert_check_schema(lysc_data_parent(sibling->schema), node->schema));
if (node->schema->flags & LYS_KEY) {
LOGERR(sibling->schema->module->ctx, LY_EINVAL, "Cannot insert key \"%s\".", node->schema->name);
@@ -1210,7 +1206,7 @@
LY_CHECK_ARG_RET(NULL, sibling, node, LY_EINVAL);
- LY_CHECK_RET(lyd_insert_check_schema(sibling->schema->parent, node->schema));
+ LY_CHECK_RET(lyd_insert_check_schema(lysc_data_parent(sibling->schema), node->schema));
if (node->schema->flags & LYS_KEY) {
LOGERR(sibling->schema->module->ctx, LY_EINVAL, "Cannot insert key \"%s\".", node->schema->name);
@@ -1248,7 +1244,7 @@
LY_CHECK_ARG_RET(NULL, sibling, node, LY_EINVAL);
- LY_CHECK_RET(lyd_insert_check_schema(sibling->schema->parent, node->schema));
+ LY_CHECK_RET(lyd_insert_check_schema(lysc_data_parent(sibling->schema), node->schema));
if (node->schema->flags & LYS_KEY) {
LOGERR(sibling->schema->module->ctx, LY_EINVAL, "Cannot insert key \"%s\".", node->schema->name);
@@ -2311,8 +2307,8 @@
LY_CHECK_ARG_RET(NULL, target, LY_EINVAL);
- if (!siblings) {
- /* no data */
+ if (!siblings || (lysc_data_parent(siblings->schema) != lysc_data_parent(target->schema))) {
+ /* no data or schema mismatch */
if (match) {
*match = NULL;
}
@@ -2371,8 +2367,8 @@
LY_CHECK_ARG_RET(NULL, target, set, LY_EINVAL);
- if (!siblings) {
- /* no data */
+ if (!siblings || (lysc_data_parent(siblings->schema) != lysc_data_parent(target->schema))) {
+ /* no data or schema mismatch */
return LY_ENOTFOUND;
}
@@ -2526,7 +2522,7 @@
struct lyd_node *target = NULL;
LY_CHECK_ARG_RET(NULL, schema, LY_EINVAL);
- if ((schema->nodetype == LYS_LIST) && schema->flags & LYS_KEYLESS) {
+ if ((schema->nodetype == LYS_LIST) && (schema->flags & LYS_KEYLESS)) {
LOGERR(schema->module->ctx, LY_EINVAL, "Invalid arguments - key-less list (%s()).", __func__);
return LY_EINVAL;
} else if ((schema->nodetype & (LYS_LEAFLIST | LYS_LIST)) && !key_or_value) {
@@ -2538,8 +2534,8 @@
return LY_EINVAL;
}
- if (!siblings) {
- /* no data */
+ if (!siblings || (lysc_data_parent(siblings->schema) != lysc_data_parent(schema))) {
+ /* no data or schema mismatch */
if (match) {
*match = NULL;
}
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 437d639..a96ad4d 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -1689,3 +1689,13 @@
{
return lys_module_find_prefix((const struct lys_module*)private, prefix, prefix_len);
}
+
+const struct lysc_node *
+lysc_data_parent(const struct lysc_node *schema)
+{
+ const struct lysc_node *parent;
+
+ for (parent = schema->parent; parent && (parent->nodetype & (LYS_CHOICE | LYS_CASE)); parent = parent->parent);
+
+ return parent;
+}
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 9f291f3..5d10992 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -898,4 +898,12 @@
char *lysc_path_until(const struct lysc_node *node, const struct lysc_node *parent, LYSC_PATH_TYPE pathtype, char *buffer,
size_t buflen);
+/**
+ * @brief Get schema parent that can be instantiated in data. In other words, skip any choice or case nodes.
+ *
+ * @param[in] schema Schema node to get the parent for.
+ * @return Parent, NULL if top-level (in data).
+ */
+const struct lysc_node *lysc_data_parent(const struct lysc_node *schema);
+
#endif /* LY_TREE_SCHEMA_INTERNAL_H_ */
diff --git a/src/validation.c b/src/validation.c
index 69a2639..4124f22 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -498,19 +498,15 @@
size_t depth = 0, i;
/* get leaf depth */
- for (iter = (struct lysc_node *)uniq_leaf; iter && (iter != list->schema); iter = iter->parent) {
- if (!(iter->nodetype & (LYS_CHOICE | LYS_CASE))) {
- ++depth;
- }
+ for (iter = (struct lysc_node *)uniq_leaf; iter && (iter != list->schema); iter = lysc_data_parent(iter)) {
+ ++depth;
}
node = list;
while (node && depth) {
/* find schema node with this depth */
- for (i = depth - 1, iter = (struct lysc_node *)uniq_leaf; i; iter = iter->parent) {
- if (!(iter->nodetype & (LYS_CHOICE | LYS_CASE))) {
- --i;
- }
+ for (i = depth - 1, iter = (struct lysc_node *)uniq_leaf; i; iter = lysc_data_parent(iter)) {
+ --i;
}
/* find iter instance in children */