tree schema UPDATE schema mount support for lys_getnext
... which also adds the support for lys_find_xpath_atoms().
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 5c897bf..3ec4574 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -37,6 +37,7 @@
#include "parser_internal.h"
#include "parser_schema.h"
#include "path.h"
+#include "plugins_exts.h"
#include "plugins_internal.h"
#include "schema_compile.h"
#include "schema_compile_amend.h"
@@ -164,7 +165,11 @@
const struct lysc_ext_instance *ext, uint32_t options)
{
const struct lysc_node *next = NULL;
- ly_bool action_flag = 0, notif_flag = 0;
+ ly_bool action_flag = 0, notif_flag = 0, sm_flag = options & LYS_GETNEXT_WITHSCHEMAMOUNT ? 0 : 1;
+ LY_ARRAY_COUNT_TYPE u;
+ struct ly_ctx *sm_ctx = NULL;
+ const struct lys_module *mod;
+ uint32_t idx;
LY_CHECK_ARG_RET(NULL, parent || module || ext, NULL);
@@ -172,7 +177,7 @@
if (!last) {
/* first call */
- /* get know where to start */
+ /* learn where to start */
if (parent) {
/* schema subtree */
next = last = lysc_node_child(parent);
@@ -204,8 +209,29 @@
repeat:
if (!next) {
- /* possibly go back to parent */
- if (last && (last->parent != parent)) {
+ if (last && !sm_flag && parent && (last->module->ctx != parent->module->ctx)) {
+ sm_flag = 1;
+
+ /* find the module of last */
+ sm_ctx = last->module->ctx;
+ idx = 0;
+ while ((mod = ly_ctx_get_module_iter(sm_ctx, &idx))) {
+ if (mod == last->module) {
+ break;
+ }
+ }
+ assert(mod);
+
+ /* get node from the next mounted module */
+ while (!next && (mod = ly_ctx_get_module_iter(sm_ctx, &idx))) {
+ if (!mod->implemented) {
+ continue;
+ }
+
+ next = lys_getnext(NULL, NULL, mod->compiled, options & ~LYS_GETNEXT_WITHSCHEMAMOUNT);
+ }
+ } else if (last && (last->parent != parent)) {
+ /* go back to parent */
last = last->parent;
goto next;
} else if (!action_flag) {
@@ -226,6 +252,35 @@
} else {
next = (struct lysc_node *)module->notifs;
}
+ } else if (!sm_flag) {
+ sm_flag = 1;
+ if (parent) {
+ LY_ARRAY_FOR(parent->exts, u) {
+ if (!strcmp(parent->exts[u].def->name, "mount-point") &&
+ !strcmp(parent->exts[u].def->module->name, "ietf-yang-schema-mount")) {
+ lyplg_ext_schema_mount_create_context(&parent->exts[u], &sm_ctx);
+ if (sm_ctx) {
+ /* some usable context created */
+ break;
+ }
+ }
+ }
+ if (sm_ctx) {
+ /* get the first node from the first usable module */
+ idx = 0;
+ while (!next && (mod = ly_ctx_get_module_iter(sm_ctx, &idx))) {
+ if (!mod->implemented) {
+ continue;
+ }
+
+ next = lys_getnext(NULL, NULL, mod->compiled, options & ~LYS_GETNEXT_WITHSCHEMAMOUNT);
+ }
+ if (!next) {
+ /* no nodes found */
+ ly_ctx_destroy(sm_ctx);
+ }
+ }
+ }
} else {
return NULL;
}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index c57a0fc..8155885 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -1971,6 +1971,8 @@
#define LYS_FIND_XP_OUTPUT 0x10 /**< Search RPC/action output nodes instead of input ones. */
#define LYS_FIND_NO_MATCH_ERROR 0x40 /**< Return error if a path segment matches no nodes, otherwise only warning
is printed. */
+#define LYS_FIND_SCHEMAMOUNT 0x0200 /**< Traverse also nodes from mounted modules. If any such nodes are returned,
+ the caller **must free** their context! */
/** @} findxpathoptions */
/**
@@ -2189,6 +2191,9 @@
#define LYS_GETNEXT_INTONPCONT 0x08 /**< ::lys_getnext() option to look into non-presence container, instead of returning container itself */
#define LYS_GETNEXT_OUTPUT 0x10 /**< ::lys_getnext() option to provide RPC's/action's output schema nodes instead of input schema nodes
provided by default */
+#define LYS_GETNEXT_WITHSCHEMAMOUNT 0x20 /**< ::lys_getnext() option to also traverse top-level nodes of all the mounted modules
+ on the parent mount point but note that if any such nodes are returned,
+ the caller **must free** their context */
/** @} sgetnextflags */
/**
diff --git a/src/xpath.c b/src/xpath.c
index 578324a..b83e1cc 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -6673,6 +6673,9 @@
if (options & LYXP_SCNODE_OUTPUT) {
getnext_opts |= LYS_GETNEXT_OUTPUT;
}
+ if (options & LYXP_SCNODE_SCHEMAMOUNT) {
+ getnext_opts |= LYS_GETNEXT_WITHSCHEMAMOUNT;
+ }
orig_used = set->used;
for (i = 0; i < orig_used; ++i) {
diff --git a/src/xpath.h b/src/xpath.h
index 3e61bb0..c34a0f3 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -381,6 +381,7 @@
warning is printed. */
#define LYXP_ACCESS_TREE_ALL 0x80 /**< Explicit accessible tree of all the nodes. */
#define LYXP_ACCESS_TREE_CONFIG 0x0100 /**< Explicit accessible tree of only configuration data. */
+#define LYXP_SCNODE_SCHEMAMOUNT LYS_FIND_SCHEMAMOUNT /**< Nodes from mounted modules are also accessible. */
/**
* @brief Cast XPath set to another type.