summaryrefslogtreecommitdiffstats
path: root/src/tree_schema.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tree_schema.c')
-rw-r--r--src/tree_schema.c156
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: