tree data BUGFIX lyd_owner_module behavior now consistent
It is meant to return the owner module for both
data and opaque nodes. For node modules there
is a new function now.
diff --git a/src/log.c b/src/log.c
index a0d997f..6f38e17 100644
--- a/src/log.c
+++ b/src/log.c
@@ -764,7 +764,7 @@
/* get module to print, if any */
mod = snode->module;
- prev_mod = (parent->schema) ? parent->schema->module : lyd_owner_module(parent);
+ prev_mod = lyd_node_module(parent);
if (prev_mod == mod) {
mod = NULL;
}
diff --git a/src/parser_common.c b/src/parser_common.c
index 040318e..bdc8529 100644
--- a/src/parser_common.c
+++ b/src/parser_common.c
@@ -197,7 +197,7 @@
assert(!iter->schema);
/* get module */
- mod = lyd_owner_module(iter);
+ mod = lyd_node_module(iter);
if (!mod) {
/* unknown module, no schema node */
schema = NULL;
diff --git a/src/parser_json.c b/src/parser_json.c
index 1eaa160..af04a36 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -2056,7 +2056,7 @@
assert(parent);
/* parse "input" */
- rc = lydjson_envelope(lydctx->jsonctx, "input", lyd_owner_module(parent)->name, 0, envp);
+ rc = lydjson_envelope(lydctx->jsonctx, "input", lyd_node_module(parent)->name, 0, envp);
LY_CHECK_GOTO(rc, cleanup);
int_opts = LYD_INTOPT_WITH_SIBLINGS | LYD_INTOPT_RPC | LYD_INTOPT_ACTION;
@@ -2071,7 +2071,7 @@
assert(parent);
/* parse "output" */
- rc = lydjson_envelope(lydctx->jsonctx, "output", lyd_owner_module(parent)->name, 0, envp);
+ rc = lydjson_envelope(lydctx->jsonctx, "output", lyd_node_module(parent)->name, 0, envp);
LY_CHECK_GOTO(rc, cleanup);
int_opts = LYD_INTOPT_WITH_SIBLINGS | LYD_INTOPT_REPLY;
diff --git a/src/parser_xml.c b/src/parser_xml.c
index a117825..d6de91d 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -1944,7 +1944,7 @@
assert(parent);
/* parse "input" */
- rc = lydxml_envelope(lydctx->xmlctx, "input", lyd_owner_module(parent)->ns, 0, envp);
+ rc = lydxml_envelope(lydctx->xmlctx, "input", lyd_node_module(parent)->ns, 0, envp);
if (rc == LY_ENOT) {
LOGVAL(ctx, LYVE_DATA, "Missing RESTCONF \"input\" object or in incorrect namespace.");
}
@@ -1957,7 +1957,7 @@
assert(parent);
/* parse "output" */
- rc = lydxml_envelope(lydctx->xmlctx, "output", lyd_owner_module(parent)->ns, 0, envp);
+ rc = lydxml_envelope(lydctx->xmlctx, "output", lyd_node_module(parent)->ns, 0, envp);
if (rc == LY_ENOT) {
LOGVAL(ctx, LYVE_DATA, "Missing RESTCONF \"output\" object or in incorrect namespace.");
}
diff --git a/src/tree_data.c b/src/tree_data.c
index bbb58be..0da855e 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -2418,9 +2418,9 @@
for (iter = node, i = 1; i < depth; iter = lyd_parent(iter), ++i) {}
iter_print:
/* get the module */
- mod = iter->schema ? iter->schema->module : lyd_owner_module(iter);
+ mod = lyd_node_module(iter);
parent = lyd_parent(iter);
- prev_mod = (parent && parent->schema) ? parent->schema->module : lyd_owner_module(parent);
+ prev_mod = lyd_node_module(parent);
if (prev_mod == mod) {
mod = NULL;
}
@@ -2490,7 +2490,7 @@
for (depth = 1; depth <= dnodes->count; ++depth) {
/* current node */
iter = dnodes->dnodes[depth - 1];
- mod = iter->schema ? iter->schema->module : lyd_owner_module(iter);
+ mod = lyd_node_module(iter);
/* parent */
parent = (depth > 1) ? dnodes->dnodes[depth - 2] : NULL;
@@ -2499,7 +2499,7 @@
(!lysc_data_parent(iter->schema) && (LYD_CTX(iter) != LYD_CTX(parent))));
/* get module to print, if any */
- prev_mod = (parent && parent->schema) ? parent->schema->module : lyd_owner_module(parent);
+ prev_mod = lyd_node_module(parent);
if (prev_mod == mod) {
mod = NULL;
}
diff --git a/src/tree_data.h b/src/tree_data.h
index 124c784..3249e84 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -1072,6 +1072,14 @@
LIBYANG_API_DECL const struct lys_module *lyd_owner_module(const struct lyd_node *node);
/**
+ * @brief Get the module of a node. Useful mainly for opaque nodes.
+ *
+ * @param[in] node Node to examine.
+ * @return Module of the node.
+ */
+LIBYANG_API_DECL const struct lys_module *lyd_node_module(const struct lyd_node *node);
+
+/**
* @brief Check whether a node value equals to its default one.
*
* @param[in] node Term node to test.
diff --git a/src/tree_data_common.c b/src/tree_data_common.c
index f2a37a2..d0d3602 100644
--- a/src/tree_data_common.c
+++ b/src/tree_data_common.c
@@ -300,7 +300,12 @@
return NULL;
}
+ while (!node->schema && node->parent) {
+ node = lyd_parent(node);
+ }
+
if (!node->schema) {
+ /* top-level opaque node */
opaq = (struct lyd_node_opaq *)node;
switch (opaq->format) {
case LY_VALUE_XML:
@@ -317,13 +322,46 @@
return NULL;
}
- /* try a parent */
- return lyd_owner_module(lyd_parent(node));
+ return NULL;
}
return lysc_owner_module(node->schema);
}
+LIBYANG_API_DEF const struct lys_module *
+lyd_node_module(const struct lyd_node *node)
+{
+ const struct lyd_node_opaq *opaq;
+
+ while (node) {
+ /* data node */
+ if (node->schema) {
+ return node->schema->module;
+ }
+
+ /* opaque node */
+ opaq = (struct lyd_node_opaq *)node;
+ switch (opaq->format) {
+ case LY_VALUE_XML:
+ if (opaq->name.module_ns) {
+ return ly_ctx_get_module_implemented_ns(LYD_CTX(node), opaq->name.module_ns);
+ }
+ break;
+ case LY_VALUE_JSON:
+ if (opaq->name.module_name) {
+ return ly_ctx_get_module_implemented(LYD_CTX(node), opaq->name.module_name);
+ }
+ break;
+ default:
+ break;
+ }
+
+ node = lyd_parent(node);
+ }
+
+ return NULL;
+}
+
void
lyd_first_module_sibling(struct lyd_node **node, const struct lys_module *mod)
{
@@ -1072,7 +1110,7 @@
for (iter = node; lyd_parent(iter) != prev_iter; iter = lyd_parent(iter)) {}
/* get module */
- mod = lyd_owner_module(iter);
+ mod = lyd_node_module(iter);
if (!mod) {
/* unknown module, no schema node */
schema = NULL;
diff --git a/src/xpath.c b/src/xpath.c
index 4f5bffb..1c1056b 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -4502,7 +4502,7 @@
xpath_name(struct lyxp_set **args, uint32_t arg_count, struct lyxp_set *set, uint32_t options)
{
struct lyxp_set_node *item;
- struct lys_module *mod = NULL;
+ const struct lys_module *mod = NULL;
char *str;
const char *name = NULL;
@@ -4548,8 +4548,8 @@
/* keep NULL */
break;
case LYXP_NODE_ELEM:
- mod = item->node->schema->module;
- name = item->node->schema->name;
+ mod = lyd_node_module(item->node);
+ name = LYD_NAME(item->node);
break;
case LYXP_NODE_META:
mod = ((struct lyd_meta *)item->node)->annotation->module;
@@ -4584,7 +4584,7 @@
xpath_namespace_uri(struct lyxp_set **args, uint32_t arg_count, struct lyxp_set *set, uint32_t options)
{
struct lyxp_set_node *item;
- struct lys_module *mod;
+ const struct lys_module *mod;
/* suppress unused variable warning */
(void)options;
@@ -4634,7 +4634,7 @@
case LYXP_NODE_ELEM:
case LYXP_NODE_META:
if (item->type == LYXP_NODE_ELEM) {
- mod = item->node->schema->module;
+ mod = lyd_node_module(item->node);
} else { /* LYXP_NODE_META */
/* annotations */
mod = ((struct lyd_meta *)item->node)->annotation->module;