summaryrefslogtreecommitdiff
path: root/lib/yang.c
diff options
context:
space:
mode:
authorvdhingra <vdhingra@vmware.com>2020-04-24 05:36:14 -0700
committervdhingra <vdhingra@vmware.com>2020-07-16 08:33:00 -0700
commit27802d3feedc70d69a8986cdbf10fea57f1b2be4 (patch)
tree2c23c14be5c4284fa92e1d2a3872daebb2f4f56d /lib/yang.c
parent565f463e30955fc398c3dec168f5d276f975a516 (diff)
lib : Yang wrappers
1. To get the parent node 2. To auto delete the parent when last node in list gets deleted Signed-off-by: VishalDhingra <vdhingra@vmware.com>
Diffstat (limited to 'lib/yang.c')
-rw-r--r--lib/yang.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/yang.c b/lib/yang.c
index 0714ddf7bb..db99c0339e 100644
--- a/lib/yang.c
+++ b/lib/yang.c
@@ -749,3 +749,147 @@ void yang_terminate(void)
ly_ctx_destroy(ly_native_ctx, NULL);
}
+
+const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
+ const char *name)
+{
+ const struct lyd_node *orig_dnode = dnode;
+
+ while (orig_dnode) {
+ switch (orig_dnode->schema->nodetype) {
+ case LYS_LIST:
+ case LYS_CONTAINER:
+ if (!strcmp(orig_dnode->schema->name, name))
+ return orig_dnode;
+ break;
+ default:
+ break;
+ }
+
+ orig_dnode = orig_dnode->parent;
+ }
+
+ return NULL;
+}
+
+/* API to check if the given node is last node in the list */
+static bool yang_is_last_list_dnode(const struct lyd_node *dnode)
+{
+ return (((dnode->next == NULL)
+ || (dnode->next
+ && (strcmp(dnode->next->schema->name, dnode->schema->name)
+ != 0)))
+ && dnode->prev
+ && ((dnode->prev == dnode)
+ || (strcmp(dnode->prev->schema->name, dnode->schema->name)
+ != 0)));
+}
+
+/* API to check if the given node is last node in the data tree level */
+static bool yang_is_last_level_dnode(const struct lyd_node *dnode)
+{
+ const struct lyd_node *parent;
+ const struct lys_node_list *snode;
+ const struct lyd_node *key_leaf;
+ uint8_t keys_size;
+
+ switch (dnode->schema->nodetype) {
+ case LYS_LIST:
+ assert(dnode->parent);
+ parent = dnode->parent;
+ snode = (struct lys_node_list *)parent->schema;
+ key_leaf = dnode->prev;
+ for (keys_size = 1; keys_size < snode->keys_size; keys_size++)
+ key_leaf = key_leaf->prev;
+ if (key_leaf->prev == dnode)
+ return true;
+ break;
+ case LYS_CONTAINER:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+
+const struct lyd_node *
+yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
+{
+ bool parent = true;
+ const struct lyd_node *node;
+ const struct lys_node_container *snode;
+
+ node = dnode;
+ if (node->schema->nodetype != LYS_LIST)
+ return node;
+
+ while (parent) {
+ switch (node->schema->nodetype) {
+ case LYS_CONTAINER:
+ snode = (struct lys_node_container *)node->schema;
+ if ((!snode->presence)
+ && yang_is_last_level_dnode(node)) {
+ if (node->parent
+ && (node->parent->schema->module
+ == dnode->schema->module))
+ node = node->parent;
+ else
+ parent = false;
+ } else
+ parent = false;
+ break;
+ case LYS_LIST:
+ if (yang_is_last_list_dnode(node)
+ && yang_is_last_level_dnode(node)) {
+ if (node->parent
+ && (node->parent->schema->module
+ == dnode->schema->module))
+ node = node->parent;
+ else
+ parent = false;
+ } else
+ parent = false;
+ break;
+ default:
+ parent = false;
+ break;
+ }
+ }
+ return node;
+}
+
+uint32_t yang_get_list_pos(const struct lyd_node *node)
+{
+ return lyd_list_pos(node);
+}
+
+uint32_t yang_get_list_elements_count(const struct lyd_node *node)
+{
+ unsigned int count;
+ struct lys_node *schema;
+
+ if (!node
+ || ((node->schema->nodetype != LYS_LIST)
+ && (node->schema->nodetype != LYS_LEAFLIST))) {
+ return 0;
+ }
+
+ schema = node->schema;
+ count = 0;
+ do {
+ if (node->schema == schema)
+ ++count;
+ node = node->next;
+ } while (node);
+ return count;
+}
+
+
+const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode)
+{
+ if (dnode)
+ return dnode->child;
+ return NULL;
+}