diff options
Diffstat (limited to 'lib/yang.c')
| -rw-r--r-- | lib/yang.c | 172 |
1 files changed, 162 insertions, 10 deletions
diff --git a/lib/yang.c b/lib/yang.c index 0714ddf7bb..6ab9492d52 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -53,22 +53,30 @@ static const char *yang_module_imp_clb(const char *mod_name, { struct yang_module_embed *e; - if (submod_name || submod_rev) - return NULL; - for (e = embeds; e; e = e->next) { - if (strcmp(e->mod_name, mod_name)) - continue; - if (mod_rev && strcmp(e->mod_rev, mod_rev)) - continue; + if (e->sub_mod_name && submod_name) { + if (strcmp(e->sub_mod_name, submod_name)) + continue; + + if (submod_rev && strcmp(e->sub_mod_rev, submod_rev)) + continue; + } else { + if (strcmp(e->mod_name, mod_name)) + continue; + + if (mod_rev && strcmp(e->mod_rev, mod_rev)) + continue; + } *format = e->format; return e->data; } - flog_warn(EC_LIB_YANG_MODULE_LOAD, - "YANG model \"%s@%s\" not embedded, trying external file", - mod_name, mod_rev ? mod_rev : "*"); + flog_warn( + EC_LIB_YANG_MODULE_LOAD, + "YANG model \"%s@%s\" \"%s@%s\"not embedded, trying external file", + mod_name, mod_rev ? mod_rev : "*", + submod_name ? submod_name : "*", submod_rev ? submod_rev : "*"); return NULL; } @@ -749,3 +757,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; +} |
