tree schema FEATURE functions for schema iteration including inout
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 2edc493..7ef044b 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -1477,10 +1477,8 @@
const char *node_name;
/* compare with the module of the node */
- if ((*node)->nodetype == LYS_INPUT) {
- node_mod = ((struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, input)))->module;
- } else if ((*node)->nodetype == LYS_OUTPUT) {
- node_mod = ((struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, output)))->module;
+ if ((*node)->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
+ node_mod = lysc_node_parent_all(*node)->module;
} else {
node_mod = (*node)->module;
}
@@ -1500,24 +1498,8 @@
return 0;
}
- if ((*node)->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
- /* move up from input/output */
- if ((*node)->nodetype == LYS_INPUT) {
- (*node) = (struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, input));
- } else {
- (*node) = (struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, output));
- }
- } else if ((*node)->parent && ((*node)->parent->nodetype & (LYS_RPC | LYS_ACTION))) {
- /* move to the input/output */
- if ((*node)->flags & LYS_CONFIG_W) {
- *node = (struct lysc_node *)&((struct lysc_action *)(*node)->parent)->input;
- } else {
- *node = (struct lysc_node *)&((struct lysc_action *)(*node)->parent)->output;
- }
- } else {
- /* move to next parent */
- *node = (*node)->parent;
- }
+ /* move to next parent */
+ *node = lysc_node_parent_all(*node);
return 1;
}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 32fb073..f65f985 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -101,6 +101,8 @@
* - ::lysc_set_private()
*
* - ::lysc_node_children()
+ * - ::lysc_node_children_all()
+ * - ::lysc_node_parent_all()
* - ::lysc_node_actions()
* - ::lysc_node_notifs()
*
@@ -1857,7 +1859,8 @@
/**
* @brief Get the children linked list of the given (compiled) schema node.
- * Decides the node's type and in case it has a children list, returns it.
+ * Skips over input and output nodes.
+ *
* @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.
* @return The node's children linked list if any, NULL otherwise.
@@ -1865,6 +1868,27 @@
const struct lysc_node *lysc_node_children(const struct lysc_node *node, uint16_t flags);
/**
+ * @brief Get the children linked list of the given (compiled) schema node.
+ * Returns all children node types including input and output.
+ *
+ * @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);
+
+/**
+ * @brief Get the parent pointer from any type of (compiled) schema node.
+ * Returns input or output for direct descendants of these nodes.
+ *
+ * @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);
+
+/**
* @brief Examine whether a node is user-ordered list or leaf-list.
*
* @param[in] schema Schema node to examine.
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 3ea2659..19ad8e2 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -1238,6 +1238,56 @@
}
}
+API const struct lysc_node *
+lysc_node_children_all(const struct lysc_node *node, uint16_t flags)
+{
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return ((struct lysc_node_container *)node)->child;
+ case LYS_CHOICE:
+ return (struct lysc_node *)((struct lysc_node_choice *)node)->cases;
+ case LYS_CASE:
+ return ((struct lysc_node_case *)node)->child;
+ case LYS_LIST:
+ return ((struct lysc_node_list *)node)->child;
+ case LYS_RPC:
+ case LYS_ACTION:
+ if (flags & LYS_CONFIG_R) {
+ return (struct lysc_node *)&((struct lysc_action *)node)->output;
+ } else {
+ /* LYS_CONFIG_W, but also the default case */
+ return (struct lysc_node *)&((struct lysc_action *)node)->input;
+ }
+ case LYS_INPUT:
+ case LYS_OUTPUT:
+ return ((struct lysc_action_inout *)node)->data;
+ case LYS_NOTIF:
+ return ((struct lysc_notif *)node)->data;
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysc_node *
+lysc_node_parent_all(const struct lysc_node *node)
+{
+ if (!node) {
+ return NULL;
+ } else if (node->nodetype == LYS_INPUT) {
+ return (struct lysc_node *)(((char *)node) - offsetof(struct lysc_action, input));
+ } else if (node->nodetype == LYS_OUTPUT) {
+ return (struct lysc_node *)(((char *)node) - offsetof(struct lysc_action, output));
+ } else if (node->parent && (node->parent->nodetype & (LYS_RPC | LYS_ACTION))) {
+ if (node->flags & LYS_CONFIG_W) {
+ return (struct lysc_node *)&((struct lysc_action *)node->parent)->input;
+ } else {
+ return (struct lysc_node *)&((struct lysc_action *)node->parent)->output;
+ }
+ } else {
+ return node->parent;
+ }
+}
+
struct lys_module *
lysp_find_module(struct ly_ctx *ctx, const struct lysp_module *mod)
{