diff options
| author | vdhingra <vdhingra@vmware.com> | 2020-04-24 05:36:14 -0700 |
|---|---|---|
| committer | vdhingra <vdhingra@vmware.com> | 2020-07-16 08:33:00 -0700 |
| commit | 27802d3feedc70d69a8986cdbf10fea57f1b2be4 (patch) | |
| tree | 2c23c14be5c4284fa92e1d2a3872daebb2f4f56d /lib/yang.c | |
| parent | 565f463e30955fc398c3dec168f5d276f975a516 (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.c | 144 |
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; +} |
