schema tree FEATURE tree dfs makro no longer skips inout nodes
diff --git a/src/plugins_exts_nacm.c b/src/plugins_exts_nacm.c
index b98fc03..7012e66 100644
--- a/src/plugins_exts_nacm.c
+++ b/src/plugins_exts_nacm.c
@@ -86,7 +86,8 @@
/* inherit the extension instance to all the children nodes */
LYSC_TREE_DFS_BEGIN(parent, iter) {
- if (iter != parent) { /* ignore the parent from which we inherit */
+ /* ignore the parent from which we inherit and input/output nodes */
+ if ((iter != parent) && !(iter->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
/* check that the node does not have its own NACM extension instance */
LY_ARRAY_FOR(iter->exts, u) {
if (iter->exts[u].def == c_ext->def) {
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 7ef044b..80f479c 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -1478,7 +1478,7 @@
/* compare with the module of the node */
if ((*node)->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
- node_mod = lysc_node_parent_all(*node)->module;
+ node_mod = lysc_node_parent_full(*node)->module;
} else {
node_mod = (*node)->module;
}
@@ -1499,7 +1499,7 @@
}
/* move to next parent */
- *node = lysc_node_parent_all(*node);
+ *node = lysc_node_parent_full(*node);
return 1;
}
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index df9496f..0996dcc 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -2077,7 +2077,6 @@
DUP_STRING_GOTO(ctx->ctx, action_p->dsc, action->dsc, ret, cleanup);
DUP_STRING_GOTO(ctx->ctx, action_p->ref, action->ref, ret, cleanup);
COMPILE_ARRAY_GOTO(ctx, action_p->iffeatures, action->iffeatures, u, lys_compile_iffeature, ret, cleanup);
- COMPILE_EXTS_GOTO(ctx, action_p->exts, action->exts, action, LYEXT_PAR_NODE, ret, cleanup);
/* connect any action augments */
LY_CHECK_RET(lys_compile_node_augments(ctx, (struct lysc_node *)action));
@@ -2144,6 +2143,9 @@
lysc_update_path(ctx, NULL, NULL);
+ /* wait with extensions compilation until all the children are compiled */
+ COMPILE_EXTS_GOTO(ctx, action_p->exts, action->exts, action, LYEXT_PAR_NODE, ret, cleanup);
+
if ((action->input.musts || action->output.musts) && !(ctx->options & LYS_COMPILE_GROUPING)) {
/* do not check "must" semantics in a grouping */
ret = ly_set_add(&ctx->xpath, action, 0, NULL);
@@ -2213,7 +2215,6 @@
ret = ly_set_add(&ctx->xpath, notif, 0, NULL);
LY_CHECK_GOTO(ret, cleanup);
}
- COMPILE_EXTS_GOTO(ctx, notif_p->exts, notif->exts, notif, LYEXT_PAR_NODE, ret, cleanup);
ctx->options |= LYS_COMPILE_NOTIFICATION;
@@ -2225,6 +2226,9 @@
LY_CHECK_GOTO(ret, cleanup);
}
+ /* wait with extension compilation until all the children are compiled */
+ COMPILE_EXTS_GOTO(ctx, notif_p->exts, notif->exts, notif, LYEXT_PAR_NODE, ret, cleanup);
+
lysc_update_path(ctx, NULL, NULL);
cleanup:
diff --git a/src/tree_schema.h b/src/tree_schema.h
index f65f985..8872ad3 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -101,8 +101,8 @@
* - ::lysc_set_private()
*
* - ::lysc_node_children()
- * - ::lysc_node_children_all()
- * - ::lysc_node_parent_all()
+ * - ::lysc_node_children_full()
+ * - ::lysc_node_parent_full()
* - ::lysc_node_actions()
* - ::lysc_node_notifs()
*
@@ -163,8 +163,11 @@
/* *INDENT-OFF* */
/**
- * @brief Macro to iterate via all elements in a schema tree which can be instantiated in data tree
- * (skips cases, input, output). This is the opening part to the #LYSC_TREE_DFS_END - they always have to be used together.
+ * @brief Macro to iterate via all elements in a schema (sub)tree including input and output.
+ * Note that __actions__ and __notifications__ of traversed nodes __are ignored__! To traverse
+ * on all the nodes including those, use ::lysc_tree_dfs_full() instead.
+ *
+ * This is the opening part to the #LYSC_TREE_DFS_END - they always have to be used together.
*
* The function follows deep-first search algorithm:
* <pre>
@@ -206,51 +209,40 @@
* @param START Pointer to the starting element processed first.
* @param ELEM Iterator intended for use in the block.
*/
-
#define LYSC_TREE_DFS_END(START, ELEM) \
/* select element for the next run - children first */ \
if (LYSC_TREE_DFS_continue) { \
(LYSC_TREE_DFS_next) = NULL; \
} else { \
- (LYSC_TREE_DFS_next) = (struct lysc_node *)lysc_node_children(ELEM, 0); \
- }\
+ (LYSC_TREE_DFS_next) = (struct lysc_node *)lysc_node_children_full(ELEM, 0); \
+ } \
if (!(LYSC_TREE_DFS_next)) { \
- /* in case of RPC/action, get also the output children */ \
- if (!LYSC_TREE_DFS_continue && (ELEM)->nodetype & (LYS_RPC | LYS_ACTION)) { \
- (LYSC_TREE_DFS_next) = (struct lysc_node *)lysc_node_children(ELEM, LYS_CONFIG_R); \
- } \
- if (!(LYSC_TREE_DFS_next)) { \
- /* no children */ \
- if ((ELEM) == (struct lysc_node *)(START)) { \
- /* we are done, (START) has no children */ \
- break; \
- } \
- /* try siblings */ \
- (LYSC_TREE_DFS_next) = (ELEM)->next; \
- } \
+ /* no children, try siblings */ \
+ _LYSC_TREE_DFS_NEXT(START, ELEM, LYSC_TREE_DFS_next); \
} \
while (!(LYSC_TREE_DFS_next)) { \
/* parent is already processed, go to its sibling */ \
- if ((ELEM)->nodetype == LYS_INPUT) { \
- (ELEM) = (struct lysc_node *)(((char *)(ELEM)) - offsetof(struct lysc_action, input)); \
- } else if ((ELEM)->nodetype == LYS_OUTPUT) { \
- (ELEM) = (struct lysc_node *)(((char *)(ELEM)) - offsetof(struct lysc_action, output)); \
- } else { \
- (ELEM) = (ELEM)->parent; \
- } \
- /* no siblings, go back through parents */ \
- if ((ELEM) == (struct lysc_node *)(START)) { \
- /* we are done, no next element to process */ \
- break; \
- } \
- if ((ELEM)->nodetype & (LYS_RPC | LYS_ACTION)) { \
- /* there is actually next node as a child of action's output */ \
- (LYSC_TREE_DFS_next) = (struct lysc_node *)lysc_node_children(ELEM, LYS_CONFIG_R); \
- } \
- if (!(LYSC_TREE_DFS_next)) { \
- (LYSC_TREE_DFS_next) = (ELEM)->next; \
- } \
- } } \
+ (ELEM) = (struct lysc_node *)lysc_node_parent_full(ELEM); \
+ _LYSC_TREE_DFS_NEXT(START, ELEM, LYSC_TREE_DFS_next); \
+ } }
+
+/**
+ * @brief Helper macro for #LYSC_TREE_DFS_END, should not be used directly!
+ */
+#define _LYSC_TREE_DFS_NEXT(START, ELEM, NEXT) \
+ if ((ELEM) == (struct lysc_node *)(START)) { \
+ /* we are done, no next element to process */ \
+ break; \
+ } \
+ if ((ELEM)->nodetype == LYS_INPUT) { \
+ /* after input, get output */ \
+ (NEXT) = (struct lysc_node *)lysc_node_children_full(lysc_node_parent_full(ELEM), LYS_CONFIG_R); \
+ } else if ((ELEM)->nodetype == LYS_OUTPUT) { \
+ /* no sibling of output */ \
+ (NEXT) = NULL; \
+ } else { \
+ (NEXT) = (ELEM)->next; \
+ }
/* *INDENT-ON* */
@@ -1859,7 +1851,7 @@
/**
* @brief Get the children linked list of the given (compiled) schema node.
- * Skips over input and output nodes.
+ * Skips over input and output nodes. To return them, use ::lysc_node_children_full().
*
* @param[in] node Node to examine.
* @param[in] flags Config flag to distinguish input (LYS_CONFIG_W) and output (LYS_CONFIG_R) data in case of RPC/action node.
@@ -1869,24 +1861,25 @@
/**
* @brief Get the children linked list of the given (compiled) schema node.
- * Returns all children node types including input and output.
+ * Returns all children node types including input and output. To skip them, use ::lysc_node_children().
*
* @param[in] node Node to examine.
* @param[in] flags Config flag to distinguish input (LYS_CONFIG_W) and output (LYS_CONFIG_R) child in case of RPC/action node.
* @return Children linked list if any,
* @return NULL otherwise.
*/
-const struct lysc_node *lysc_node_children_all(const struct lysc_node *node, uint16_t flags);
+const struct lysc_node *lysc_node_children_full(const struct lysc_node *node, uint16_t flags);
/**
* @brief Get the parent pointer from any type of (compiled) schema node.
- * Returns input or output for direct descendants of these nodes.
+ * Returns input or output for direct descendants of RPC/action nodes.
+ * To skip them, use ::lysc_node.parent pointer directly.
*
* @param[in] node Node whose parent to get.
* @return Node parent.
* @return NULL is there is none.
*/
-const struct lysc_node *lysc_node_parent_all(const struct lysc_node *node);
+const struct lysc_node *lysc_node_parent_full(const struct lysc_node *node);
/**
* @brief Examine whether a node is user-ordered list or leaf-list.
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 19ad8e2..ea8643d 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -1239,7 +1239,7 @@
}
API const struct lysc_node *
-lysc_node_children_all(const struct lysc_node *node, uint16_t flags)
+lysc_node_children_full(const struct lysc_node *node, uint16_t flags)
{
switch (node->nodetype) {
case LYS_CONTAINER:
@@ -1269,7 +1269,7 @@
}
API const struct lysc_node *
-lysc_node_parent_all(const struct lysc_node *node)
+lysc_node_parent_full(const struct lysc_node *node)
{
if (!node) {
return NULL;