diff options
Diffstat (limited to 'src/tree_schema.c')
-rw-r--r-- | src/tree_schema.c | 156 |
1 files changed, 100 insertions, 56 deletions
diff --git a/src/tree_schema.c b/src/tree_schema.c index 5c897bf..baf2c46 100644 --- a/src/tree_schema.c +++ b/src/tree_schema.c @@ -37,6 +37,7 @@ #include "parser_internal.h" #include "parser_schema.h" #include "path.h" +#include "plugins_exts.h" #include "plugins_internal.h" #include "schema_compile.h" #include "schema_compile_amend.h" @@ -164,7 +165,11 @@ lys_getnext_(const struct lysc_node *last, const struct lysc_node *parent, const const struct lysc_ext_instance *ext, uint32_t options) { const struct lysc_node *next = NULL; - ly_bool action_flag = 0, notif_flag = 0; + ly_bool action_flag = 0, notif_flag = 0, sm_flag = options & LYS_GETNEXT_WITHSCHEMAMOUNT ? 0 : 1; + LY_ARRAY_COUNT_TYPE u; + struct ly_ctx *sm_ctx = NULL; + const struct lys_module *mod; + uint32_t idx; LY_CHECK_ARG_RET(NULL, parent || module || ext, NULL); @@ -172,7 +177,7 @@ next: if (!last) { /* first call */ - /* get know where to start */ + /* learn where to start */ if (parent) { /* schema subtree */ next = last = lysc_node_child(parent); @@ -204,8 +209,29 @@ next: repeat: if (!next) { - /* possibly go back to parent */ - if (last && (last->parent != parent)) { + if (last && !sm_flag && parent && (last->module->ctx != parent->module->ctx)) { + sm_flag = 1; + + /* find the module of last */ + sm_ctx = last->module->ctx; + idx = 0; + while ((mod = ly_ctx_get_module_iter(sm_ctx, &idx))) { + if (mod == last->module) { + break; + } + } + assert(mod); + + /* get node from the next mounted module */ + while (!next && (mod = ly_ctx_get_module_iter(sm_ctx, &idx))) { + if (!mod->implemented) { + continue; + } + + next = lys_getnext(NULL, NULL, mod->compiled, options & ~LYS_GETNEXT_WITHSCHEMAMOUNT); + } + } else if (last && (last->parent != parent)) { + /* go back to parent */ last = last->parent; goto next; } else if (!action_flag) { @@ -226,6 +252,35 @@ repeat: } else { next = (struct lysc_node *)module->notifs; } + } else if (!sm_flag) { + sm_flag = 1; + if (parent) { + LY_ARRAY_FOR(parent->exts, u) { + if (!strcmp(parent->exts[u].def->name, "mount-point") && + !strcmp(parent->exts[u].def->module->name, "ietf-yang-schema-mount")) { + lyplg_ext_schema_mount_create_context(&parent->exts[u], &sm_ctx); + if (sm_ctx) { + /* some usable context created */ + break; + } + } + } + if (sm_ctx) { + /* get the first node from the first usable module */ + idx = 0; + while (!next && (mod = ly_ctx_get_module_iter(sm_ctx, &idx))) { + if (!mod->implemented) { + continue; + } + + next = lys_getnext(NULL, NULL, mod->compiled, options & ~LYS_GETNEXT_WITHSCHEMAMOUNT); + } + if (!next) { + /* no nodes found */ + ly_ctx_destroy(sm_ctx); + } + } + } } else { return NULL; } @@ -387,7 +442,7 @@ lys_find_xpath_atoms(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, struct ly_set **set) { LY_ERR ret = LY_SUCCESS; - struct lyxp_set xp_set; + struct lyxp_set xp_set = {0}; struct lyxp_expr *exp = NULL; uint32_t i; @@ -400,7 +455,9 @@ lys_find_xpath_atoms(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, ctx = ctx_node->module->ctx; } - memset(&xp_set, 0, sizeof xp_set); + /* allocate return set */ + ret = ly_set_new(set); + LY_CHECK_GOTO(ret, cleanup); /* compile expression */ ret = lyxp_expr_parse(ctx, xpath, 0, 1, &exp); @@ -410,10 +467,6 @@ lys_find_xpath_atoms(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, ret = lyxp_atomize(ctx, exp, NULL, LY_VALUE_JSON, NULL, ctx_node, ctx_node, &xp_set, options); LY_CHECK_GOTO(ret, cleanup); - /* allocate return set */ - ret = ly_set_new(set); - LY_CHECK_GOTO(ret, cleanup); - /* transform into ly_set */ (*set)->objs = malloc(xp_set.used * sizeof *(*set)->objs); LY_CHECK_ERR_GOTO(!(*set)->objs, LOGMEM(ctx); ret = LY_EMEM, cleanup); @@ -446,15 +499,15 @@ lys_find_expr_atoms(const struct lysc_node *ctx_node, const struct lys_module *c options = LYXP_SCNODE; } + /* allocate return set */ + ret = ly_set_new(set); + LY_CHECK_GOTO(ret, cleanup); + /* atomize expression */ ret = lyxp_atomize(cur_mod->ctx, expr, cur_mod, LY_VALUE_SCHEMA_RESOLVED, (void *)prefixes, ctx_node, ctx_node, &xp_set, options); LY_CHECK_GOTO(ret, cleanup); - /* allocate return set */ - ret = ly_set_new(set); - LY_CHECK_GOTO(ret, cleanup); - /* transform into ly_set */ (*set)->objs = malloc(xp_set.used * sizeof *(*set)->objs); LY_CHECK_ERR_GOTO(!(*set)->objs, LOGMEM(cur_mod->ctx); ret = LY_EMEM, cleanup); @@ -497,6 +550,10 @@ lys_find_xpath(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const ctx = ctx_node->module->ctx; } + /* allocate return set */ + ret = ly_set_new(set); + LY_CHECK_GOTO(ret, cleanup); + /* compile expression */ ret = lyxp_expr_parse(ctx, xpath, 0, 1, &exp); LY_CHECK_GOTO(ret, cleanup); @@ -505,10 +562,6 @@ lys_find_xpath(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const ret = lyxp_atomize(ctx, exp, NULL, LY_VALUE_JSON, NULL, ctx_node, ctx_node, &xp_set, options); LY_CHECK_GOTO(ret, cleanup); - /* allocate return set */ - ret = ly_set_new(set); - LY_CHECK_GOTO(ret, cleanup); - /* transform into ly_set */ (*set)->objs = malloc(xp_set.used * sizeof *(*set)->objs); LY_CHECK_ERR_GOTO(!(*set)->objs, LOGMEM(ctx); ret = LY_EMEM, cleanup); @@ -545,8 +598,8 @@ lys_find_lypath_atoms(const struct ly_path *path, struct ly_set **set) LY_ARRAY_FOR(path, u) { /* add nodes from the path */ LY_CHECK_GOTO(ret = ly_set_add(*set, (void *)path[u].node, 0, NULL), cleanup); - if (path[u].pred_type == LY_PATH_PREDTYPE_LIST) { - LY_ARRAY_FOR(path[u].predicates, v) { + LY_ARRAY_FOR(path[u].predicates, v) { + if ((path[u].predicates[v].type == LY_PATH_PREDTYPE_LIST) || (path[u].predicates[v].type == LY_PATH_PREDTYPE_LIST_VAR)) { /* add all the keys in a predicate */ LY_CHECK_GOTO(ret = ly_set_add(*set, (void *)path[u].predicates[v].key, 0, NULL), cleanup); } @@ -578,7 +631,8 @@ lys_find_path_atoms(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, } /* parse */ - ret = lyxp_expr_parse(ctx, path, strlen(path), 0, &expr); + ret = ly_path_parse(ctx, ctx_node, path, strlen(path), 0, LY_PATH_BEGIN_EITHER, LY_PATH_PREFIX_FIRST, + LY_PATH_PRED_SIMPLE, &expr); LY_CHECK_GOTO(ret, cleanup); /* compile */ @@ -599,7 +653,7 @@ LIBYANG_API_DEF const struct lysc_node * lys_find_path(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *path, ly_bool output) { const struct lysc_node *snode = NULL; - struct lyxp_expr *exp = NULL; + struct lyxp_expr *expr = NULL; struct ly_path *p = NULL; LY_ERR ret; uint8_t oper; @@ -612,12 +666,13 @@ lys_find_path(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const } /* parse */ - ret = lyxp_expr_parse(ctx, path, strlen(path), 0, &exp); + ret = ly_path_parse(ctx, ctx_node, path, strlen(path), 0, LY_PATH_BEGIN_EITHER, LY_PATH_PREFIX_FIRST, + LY_PATH_PRED_SIMPLE, &expr); LY_CHECK_GOTO(ret, cleanup); /* compile */ oper = output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT; - ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, oper, LY_PATH_TARGET_MANY, 0, LY_VALUE_JSON, NULL, &p); + ret = ly_path_compile(ctx, NULL, ctx_node, NULL, expr, oper, LY_PATH_TARGET_MANY, 0, LY_VALUE_JSON, NULL, &p); LY_CHECK_GOTO(ret, cleanup); /* get last node */ @@ -625,7 +680,7 @@ lys_find_path(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const cleanup: ly_path_free(ctx, p); - lyxp_expr_free(ctx, exp); + lyxp_expr_free(ctx, expr); return snode; } @@ -1457,9 +1512,10 @@ error: static LY_ERR lysp_add_internal_ietf_netconf(struct lysp_ctx *pctx, struct lysp_module *mod) { - struct lysp_ext_instance *extp; + struct lysp_ext_instance *extp, *prev_exts = mod->exts; struct lysp_stmt *stmt; struct lysp_import *imp; + uint32_t idx; /* * 1) edit-config's operation @@ -1599,10 +1655,16 @@ lysp_add_internal_ietf_netconf(struct lysp_ctx *pctx, struct lysp_module *mod) stmt->prefix_data = mod; stmt->kw = LY_STMT_TYPE; - if (LY_ARRAY_COUNT(mod->exts) == 3) { + if (!prev_exts) { /* first extension instances */ assert(pctx->main_ctx == pctx); LY_CHECK_RET(ly_set_add(&pctx->ext_inst, mod->exts, 1, NULL)); + } else { + /* replace previously stored extension instances */ + if (!ly_set_contains(&pctx->ext_inst, prev_exts, &idx)) { + LOGINT_RET(mod->mod->ctx); + } + pctx->ext_inst.objs[idx] = mod->exts; } /* create new imports for the used prefixes */ @@ -1630,9 +1692,10 @@ lysp_add_internal_ietf_netconf(struct lysp_ctx *pctx, struct lysp_module *mod) static LY_ERR lysp_add_internal_ietf_netconf_with_defaults(struct lysp_ctx *pctx, struct lysp_module *mod) { - struct lysp_ext_instance *extp; + struct lysp_ext_instance *extp, *prev_exts = mod->exts; struct lysp_stmt *stmt; struct lysp_import *imp; + uint32_t idx; /* add new extension instance */ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM); @@ -1654,10 +1717,16 @@ lysp_add_internal_ietf_netconf_with_defaults(struct lysp_ctx *pctx, struct lysp_ stmt->prefix_data = mod; stmt->kw = LY_STMT_TYPE; - if (LY_ARRAY_COUNT(mod->exts) == 1) { - /* first extension instance */ + if (!prev_exts) { + /* first extension instances */ assert(pctx->main_ctx == pctx); LY_CHECK_RET(ly_set_add(&pctx->ext_inst, mod->exts, 1, NULL)); + } else { + /* replace previously stored extension instances */ + if (!ly_set_contains(&pctx->ext_inst, prev_exts, &idx)) { + LOGINT_RET(mod->mod->ctx); + } + pctx->ext_inst.objs[idx] = mod->exts; } /* create new import for the used prefix */ @@ -1680,8 +1749,6 @@ lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, struct lysp_yin_ctx *yinctx = NULL; struct lysp_ctx *pctx = NULL; struct lysf_ctx fctx = {.ctx = ctx}; - char *filename, *rev, *dot; - size_t len; ly_bool module_created = 0; assert(ctx && in && new_mods); @@ -1762,30 +1829,7 @@ lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, switch (in->type) { case LY_IN_FILEPATH: - /* check that name and revision match filename */ - filename = strrchr(in->method.fpath.filepath, '/'); - if (!filename) { - filename = in->method.fpath.filepath; - } else { - filename++; - } - rev = strchr(filename, '@'); - dot = strrchr(filename, '.'); - - /* name */ - len = strlen(mod->name); - if (strncmp(filename, mod->name, len) || - ((rev && (rev != &filename[len])) || (!rev && (dot != &filename[len])))) { - LOGWRN(ctx, "File name \"%s\" does not match module name \"%s\".", filename, mod->name); - } - if (rev) { - len = dot - ++rev; - if (!mod->parsed->revs || (len != LY_REV_SIZE - 1) || strncmp(mod->parsed->revs[0].date, rev, len)) { - LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename, - mod->parsed->revs ? mod->parsed->revs[0].date : "none"); - } - } - + ly_check_module_filename(ctx, mod->name, mod->parsed->revs ? mod->parsed->revs[0].date : NULL, in->method.fpath.filepath); break; case LY_IN_FD: case LY_IN_FILE: |