plugins exts CHANGE ext parsing isolated into a callback
Lots of refactoring and finishing up included.
diff --git a/src/context.c b/src/context.c
index 735f589..47e63d4 100644
--- a/src/context.c
+++ b/src/context.c
@@ -606,45 +606,13 @@
return LY_SUCCESS;
}
-static void
-lysc_node_clear_all_priv(struct lys_module *mod)
-{
- LY_ARRAY_COUNT_TYPE u, v;
-
- if (!mod->compiled) {
- return;
- }
-
- /* set NULL for all ::lysc_node.priv pointers in module */
- lysc_module_dfs_full(mod, lysc_node_clear_priv_dfs_cb, NULL);
-
- /* only lys_compile_extension_instance()
- * can set ::lysp_ext_instance.parsed
- */
- if (mod->parsed) {
- struct lysp_ext_instance *exts_p;
-
- exts_p = mod->parsed->exts;
- LY_ARRAY_FOR(exts_p, u) {
- if (exts_p[u].parsed) {
- /* lys_compile_extension_instance() was called */
- struct lysc_ext_substmt *substmts;
- struct lysc_node *root;
-
- /* set NULL for all ::lysc_node.priv pointers in extensions */
- substmts = mod->compiled->exts[u].substmts;
- LY_ARRAY_FOR(substmts, v) {
- root = *(struct lysc_node **)substmts[v].storage;
- lysc_tree_dfs_full(root, lysc_node_clear_priv_dfs_cb, NULL);
- }
- }
- }
- }
-}
-
LIBYANG_API_DEF LY_ERR
ly_ctx_unset_options(struct ly_ctx *ctx, uint16_t option)
{
+ LY_ARRAY_COUNT_TYPE u, v;
+ const struct lysc_ext_instance *ext;
+ struct lysc_node *root;
+
LY_CHECK_ARG_RET(ctx, ctx, LY_EINVAL);
LY_CHECK_ERR_RET(option & LY_CTX_NO_YANGLIBRARY, LOGARG(ctx, option), LY_EINVAL);
@@ -654,7 +622,24 @@
index = 0;
while ((mod = ly_ctx_get_module_iter(ctx, &index))) {
- lysc_node_clear_all_priv(mod);
+ if (!mod->compiled) {
+ continue;
+ }
+
+ /* set NULL for all ::lysc_node.priv pointers in module */
+ lysc_module_dfs_full(mod, lysc_node_clear_priv_dfs_cb, NULL);
+
+ /* set NULL for all ::lysc_node.priv pointers in compiled extension instances */
+ LY_ARRAY_FOR(mod->compiled->exts, u) {
+ ext = &mod->compiled->exts[u];
+ LY_ARRAY_FOR(ext->substmts, v) {
+ if (ext->substmts[v].stmt & LY_STMT_DATA_NODE_MASK) {
+ LY_LIST_FOR(*(struct lysc_node **)ext->substmts[v].storage, root) {
+ lysc_tree_dfs_full(root, lysc_node_clear_priv_dfs_cb, NULL);
+ }
+ }
+ }
+ }
}
}
diff --git a/src/diff.c b/src/diff.c
index 80b939c..4ef9115 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1157,7 +1157,7 @@
ret = 0;
if (parent_node) {
if (match->flags & LYD_EXT) {
- ret = lyd_insert_ext(parent_node, match);
+ ret = lyplg_ext_insert(parent_node, match);
} else {
ret = lyd_insert_child(parent_node, match);
}
diff --git a/src/log.c b/src/log.c
index 915b6e5..d13d327 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,9 +1,10 @@
/**
* @file log.c
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief Logger routines implementations
*
- * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -33,6 +34,7 @@
#include "tree_data.h"
#include "tree_data_internal.h"
#include "tree_schema.h"
+#include "tree_schema_internal.h"
ATOMIC_T ly_ll = (uint_fast32_t)LY_LLWRN;
ATOMIC_T ly_log_opts = (uint_fast32_t)(LY_LOLOG | LY_LOSTORE_LAST);
@@ -666,28 +668,74 @@
va_end(ap);
}
-LIBYANG_API_DEF void
-lyplg_ext_log(const struct lysc_ext_instance *ext, LY_LOG_LEVEL level, LY_ERR err_no, const char *path, const char *format, ...)
+/**
+ * @brief Print a log message from an extension plugin callback.
+ *
+ * @param[in] ctx libyang context to store the error record. If not provided, the error is just printed.
+ * @param[in] plugin_name Name of the plugin generating the message.
+ * @param[in] level Log message level (error, warning, etc.)
+ * @param[in] err_no Error type code.
+ * @param[in] path Optional path of the error.
+ * @param[in] format Format string to print.
+ * @param[in] ap Var arg list for @p format.
+ */
+static void
+ly_ext_log(const struct ly_ctx *ctx, const char *plugin_name, LY_LOG_LEVEL level, LY_ERR err_no, const char *path,
+ const char *format, va_list ap)
{
- va_list ap;
char *plugin_msg;
- int ret;
if (ATOMIC_LOAD_RELAXED(ly_ll) < level) {
return;
}
- ret = asprintf(&plugin_msg, "Extension plugin \"%s\": %s", ext->def->plugin->id, format);
- if (ret == -1) {
- LOGMEM(ext->module->ctx);
+ if (asprintf(&plugin_msg, "Ext plugin \"%s\": %s", plugin_name, format) == -1) {
+ LOGMEM(ctx);
return;
}
+ log_vprintf(ctx, level, (level == LY_LLERR ? LY_EPLUGIN : 0) | err_no, LYVE_OTHER, path ? strdup(path) : NULL, NULL,
+ plugin_msg, ap);
+ free(plugin_msg);
+}
+
+LIBYANG_API_DEF void
+lyplg_ext_parse_log(const struct lysp_ctx *pctx, const struct lysp_ext_instance *ext, LY_LOG_LEVEL level, LY_ERR err_no,
+ const char *format, ...)
+{
+ va_list ap;
+ char *path = NULL;
+
+ if (ATOMIC_LOAD_RELAXED(path_flag)) {
+ ly_vlog_build_path(PARSER_CTX(pctx), &path);
+ }
+
va_start(ap, format);
- log_vprintf(ext->module->ctx, level, (level == LY_LLERR ? LY_EPLUGIN : 0) | err_no, LYVE_OTHER,
- path ? strdup(path) : NULL, NULL, plugin_msg, ap);
+ ly_ext_log(PARSER_CTX(pctx), ext->record->plugin.id, level, err_no, path, format, ap);
va_end(ap);
- free(plugin_msg);
+ free(path);
+}
+
+LIBYANG_API_DEF void
+lyplg_ext_compile_log(const struct lysc_ctx *cctx, const struct lysc_ext_instance *ext, LY_LOG_LEVEL level, LY_ERR err_no,
+ const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ ly_ext_log(ext->module->ctx, ext->def->plugin->id, level, err_no, cctx ? cctx->path : NULL, format, ap);
+ va_end(ap);
+}
+
+LIBYANG_API_DEF void
+lyplg_ext_compile_log_path(const char *path, const struct lysc_ext_instance *ext, LY_LOG_LEVEL level, LY_ERR err_no,
+ const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ ly_ext_log(ext->module->ctx, ext->def->plugin->id, level, err_no, path, format, ap);
+ va_end(ap);
}
/**
diff --git a/src/log.h b/src/log.h
index 6afd2e7..f1fde4c 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,9 +1,10 @@
/**
* @file log.h
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief Logger manipulation routines and error definitions.
*
- * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
diff --git a/src/parser_common.c b/src/parser_common.c
index 4a0e421..809ed86 100644
--- a/src/parser_common.c
+++ b/src/parser_common.c
@@ -46,6 +46,7 @@
#include "parser_data.h"
#include "path.h"
#include "plugins_exts/metadata.h"
+#include "schema_features.h"
#include "set.h"
#include "tree.h"
#include "tree_data.h"
@@ -286,6 +287,62 @@
return LY_SUCCESS;
}
+void
+lys_parser_fill_filepath(struct ly_ctx *ctx, struct ly_in *in, const char **filepath)
+{
+ char path[PATH_MAX];
+
+#ifndef __APPLE__
+ char proc_path[32];
+ int len;
+#endif
+
+ LY_CHECK_ARG_RET(NULL, ctx, in, filepath, );
+ if (*filepath) {
+ /* filepath already set */
+ return;
+ }
+
+ switch (in->type) {
+ case LY_IN_FILEPATH:
+ if (realpath(in->method.fpath.filepath, path) != NULL) {
+ lydict_insert(ctx, path, 0, filepath);
+ } else {
+ lydict_insert(ctx, in->method.fpath.filepath, 0, filepath);
+ }
+
+ break;
+ case LY_IN_FD:
+#ifdef __APPLE__
+ if (fcntl(in->method.fd, F_GETPATH, path) != -1) {
+ lydict_insert(ctx, path, 0, filepath);
+ }
+#elif defined _WIN32
+ HANDLE h = _get_osfhandle(in->method.fd);
+ FILE_NAME_INFO info;
+ if (GetFileInformationByHandleEx(h, FileNameInfo, &info, sizeof info)) {
+ char *buf = calloc(info.FileNameLength + 1 /* trailing NULL */, MB_CUR_MAX);
+ len = wcstombs(buf, info.FileName, info.FileNameLength * MB_CUR_MAX);
+ lydict_insert(ctx, buf, len, filepath);
+ }
+#else
+ /* get URI if there is /proc */
+ sprintf(proc_path, "/proc/self/fd/%d", in->method.fd);
+ if ((len = readlink(proc_path, path, PATH_MAX - 1)) > 0) {
+ lydict_insert(ctx, path, len, filepath);
+ }
+#endif
+ break;
+ case LY_IN_MEMORY:
+ case LY_IN_FILE:
+ /* nothing to do */
+ break;
+ default:
+ LOGINT(ctx);
+ break;
+ }
+}
+
static LY_ERR lysp_stmt_container(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
struct lysp_node **siblings);
static LY_ERR lysp_stmt_choice(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
@@ -337,7 +394,6 @@
* @param[in] insubstmt The statement this extension instance is a substatement of.
* @param[in] insubstmt_index Index of the keyword instance this extension instance is a substatement of.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -377,11 +433,11 @@
* @return LY_ERR values.
*/
static LY_ERR
-lysp_stmt_text_field(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint32_t substmt_index,
- const char **value, enum yang_arg arg, struct lysp_ext_instance **exts)
+lysp_stmt_text_field(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint32_t substmt_index, const char **value,
+ enum yang_arg arg, struct lysp_ext_instance **exts)
{
if (*value) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
@@ -394,7 +450,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, substmt_index, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
}
@@ -413,8 +469,8 @@
* @return LY_ERR values.
*/
static LY_ERR
-lysp_stmt_qnames(struct lysp_ctx *ctx, const struct lysp_stmt *stmt,
- struct lysp_qname **qnames, enum yang_arg arg, struct lysp_ext_instance **exts)
+lysp_stmt_qnames(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_qname **qnames, enum yang_arg arg,
+ struct lysp_ext_instance **exts)
{
struct lysp_qname *item;
@@ -431,7 +487,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*qnames) - 1, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
}
@@ -450,8 +506,8 @@
* @return LY_ERR values.
*/
static LY_ERR
-lysp_stmt_text_fields(struct lysp_ctx *ctx, const struct lysp_stmt *stmt,
- const char ***texts, enum yang_arg arg, struct lysp_ext_instance **exts)
+lysp_stmt_text_fields(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, const char ***texts, enum yang_arg arg,
+ struct lysp_ext_instance **exts)
{
const char **item;
@@ -467,7 +523,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*texts) - 1, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
}
@@ -513,7 +569,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_STATUS, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "status");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "status");
return LY_EVALID;
}
}
@@ -560,7 +616,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_WHEN, 0, &when->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "when");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "when");
return LY_EVALID;
}
}
@@ -604,7 +660,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONFIG, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "config");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "config");
return LY_EVALID;
}
}
@@ -650,7 +706,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MANDATORY, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "mandatory");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "mandatory");
return LY_EVALID;
}
}
@@ -692,7 +748,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &restr->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
}
@@ -772,8 +828,8 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &any->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
- (any->nodetype & LYS_ANYDATA) == LYS_ANYDATA ? ly_stmt2str(LY_STMT_ANYDATA) : ly_stmt2str(LY_STMT_ANYXML));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw),
+ (any->nodetype & LYS_ANYDATA) == LYS_ANYDATA ? lyplg_ext_stmt2str(LY_STMT_ANYDATA) : lyplg_ext_stmt2str(LY_STMT_ANYXML));
return LY_EVALID;
}
}
@@ -802,7 +858,7 @@
unsigned long long int unum = 0;
if (*flags & LYS_SET_VALUE) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
*flags |= LYS_SET_VALUE;
@@ -812,7 +868,7 @@
arg_len = strlen(stmt->arg);
if (!arg_len || (stmt->arg[0] == '+') || ((stmt->arg[0] == '0') && (arg_len > 1)) ||
((stmt->kw == LY_STMT_POSITION) && !strncmp(stmt->arg, "-0", 2))) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
goto error;
}
@@ -820,23 +876,23 @@
if (stmt->kw == LY_STMT_VALUE) {
num = strtoll(stmt->arg, &ptr, LY_BASE_DEC);
if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
goto error;
}
} else {
unum = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
if (unum > UINT64_C(4294967295)) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
goto error;
}
}
/* we have not parsed the whole argument */
if ((size_t)(ptr - stmt->arg) != arg_len) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
goto error;
}
if (errno == ERANGE) {
- LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
goto error;
}
if (stmt->kw == LY_STMT_VALUE) {
@@ -851,7 +907,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw == LY_STMT_VALUE ? LY_STMT_VALUE : LY_STMT_POSITION, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
}
@@ -884,7 +940,7 @@
} /* else nothing specific for YANG_BIT */
LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &enm->name));
- CHECK_UNIQUENESS(ctx, *enums, name, ly_stmt2str(stmt->kw), enm->name);
+ CHECK_UNIQUENESS(ctx, *enums, name, lyplg_ext_stmt2str(stmt->kw), enm->name);
for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
switch (child->kw) {
@@ -892,7 +948,7 @@
LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
break;
case LY_STMT_IF_FEATURE:
- PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", ly_stmt2str(stmt->kw));
+ PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", lyplg_ext_stmt2str(stmt->kw));
LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &enm->iffeatures, Y_STR_ARG, &enm->exts));
break;
case LY_STMT_REFERENCE:
@@ -902,23 +958,24 @@
LY_CHECK_RET(lysp_stmt_status(ctx, child, &enm->flags, &enm->exts));
break;
case LY_STMT_VALUE:
- LY_CHECK_ERR_RET(stmt->kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
- ly_stmt2str(stmt->kw)), LY_EVALID);
+ LY_CHECK_ERR_RET(stmt->kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw),
+ lyplg_ext_stmt2str(stmt->kw)), LY_EVALID);
LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
break;
case LY_STMT_POSITION:
- LY_CHECK_ERR_RET(stmt->kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
- ly_stmt2str(stmt->kw)), LY_EVALID);
+ LY_CHECK_ERR_RET(stmt->kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw),
+ lyplg_ext_stmt2str(stmt->kw)), LY_EVALID);
LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &enm->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
}
+
return LY_SUCCESS;
}
@@ -971,7 +1028,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_FRACTION_DIGITS, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "fraction-digits");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "fraction-digits");
return LY_EVALID;
}
}
@@ -1016,7 +1073,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REQUIRE_INSTANCE, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "require-instance");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "require-instance");
return LY_EVALID;
}
}
@@ -1030,7 +1087,6 @@
* @param[in] stmt Source statement data from the parsed extension instance.
* @param[in,out] pat Value to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1068,7 +1124,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MODIFIER, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "modifier");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "modifier");
return LY_EVALID;
}
}
@@ -1126,7 +1182,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_PATTERN, 0, &restr->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "pattern");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "pattern");
return LY_EVALID;
}
}
@@ -1134,6 +1190,509 @@
}
/**
+ * @brief Parse the deviate statement. Substatement of deviation statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] devs Array of deviates to add to.
+ * @param[in,out] exts Extension instances to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_deviate(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_deviate **devs, struct lysp_ext_instance **exts)
+{
+ (void)stmt;
+ (void)devs;
+ (void)exts;
+
+ /* TODO */
+ LOGERR(PARSER_CTX(ctx), LY_EINVAL, "Extension instance \"deviate\" substatement is not supported.");
+ return LY_EINVAL;
+}
+
+/**
+ * @brief Parse the deviation statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] deviations Array of deviations to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_deviation(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_deviation **deviations)
+{
+ struct lysp_deviation *dev;
+
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *deviations, dev, LY_EMEM);
+
+ /* store nodeid */
+ LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
+ LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &dev->nodeid));
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_DESCRIPTION:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &dev->dsc, Y_STR_ARG, &dev->exts));
+ break;
+ case LY_STMT_DEVIATE:
+ LY_CHECK_RET(lysp_stmt_deviate(ctx, child, &dev->deviates, &dev->exts));
+ break;
+ case LY_STMT_REFERENCE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &dev->ref, Y_STR_ARG, &dev->exts));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &dev->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_DEVIATION));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the yang-version statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[out] version Version to write to.
+ * @param[in,out] exts Extension instances to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_yangver(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *version, struct lysp_ext_instance **exts)
+{
+ if (*version) {
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yin-element");
+ return LY_EVALID;
+ }
+
+ /* store flag */
+ if (!strcmp(stmt->arg, "1")) {
+ *version = LYS_VERSION_1_0;
+ } else if (!strcmp(stmt->arg, "1.1")) {
+ *version = LYS_VERSION_1_1;
+ } else {
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, strlen(stmt->arg), stmt->arg, "yang-version");
+ return LY_EVALID;
+ }
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_YANG_VERSION));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the module statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] mod Module to fill.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_module(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_module *mod)
+{
+ (void)stmt;
+ (void)mod;
+
+ /* TODO */
+ LOGERR(PARSER_CTX(ctx), LY_EINVAL, "Extension instance \"module\" substatement is not supported.");
+ return LY_EINVAL;
+}
+
+/**
+ * @brief Parse the submodule statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] submod Module to fill.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_submodule(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_submodule *submod)
+{
+ (void)stmt;
+ (void)submod;
+
+ /* TODO */
+ LOGERR(PARSER_CTX(ctx), LY_EINVAL, "Extension instance \"submodule\" substatement is not supported.");
+ return LY_EINVAL;
+}
+
+/**
+ * @brief Parse the yin-element statement. Substatement of argument statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] flags Flags to write to.
+ * @param[in,out] exts Extension instances to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_yinelem(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
+{
+ if (*flags & LYS_YINELEM_MASK) {
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yin-element");
+ return LY_EVALID;
+ }
+
+ /* store flag */
+ if (!strcmp(stmt->arg, "true")) {
+ *flags |= LYS_YINELEM_TRUE;
+ } else if (!strcmp(stmt->arg, "false")) {
+ *flags |= LYS_YINELEM_FALSE;
+ } else {
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, strlen(stmt->arg), stmt->arg, "yin-element");
+ return LY_EVALID;
+ }
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_YIN_ELEMENT));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the argument statement. Substatement of extension statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] ex Extension to fill.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_argument(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_ext *ex)
+{
+ if (ex->argname) {
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "argument");
+ return LY_EVALID;
+ }
+
+ /* store argument name */
+ LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
+ LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &ex->argname));
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_YIN_ELEMENT:
+ LY_CHECK_RET(lysp_stmt_yinelem(ctx, child, &ex->flags, &ex->exts));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &ex->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_ARGUMENT));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the extension statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] extensions Array of extensions to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_extension(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_ext **extensions)
+{
+ struct lysp_ext *ex;
+
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *extensions, ex, LY_EMEM);
+
+ /* store name */
+ LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
+ LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &ex->name));
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_DESCRIPTION:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ex->dsc, Y_STR_ARG, &ex->exts));
+ break;
+ case LY_STMT_REFERENCE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ex->ref, Y_STR_ARG, &ex->exts));
+ break;
+ case LY_STMT_STATUS:
+ LY_CHECK_RET(lysp_stmt_status(ctx, child, &ex->flags, &ex->exts));
+ break;
+ case LY_STMT_ARGUMENT:
+ LY_CHECK_RET(lysp_stmt_argument(ctx, child, ex));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &ex->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_EXTENSION));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the feature statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] features Array of features to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_feature(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_feature **features)
+{
+ struct lysp_feature *feat;
+
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *features, feat, LY_EMEM);
+
+ /* store name */
+ LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
+ LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &feat->name));
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_DESCRIPTION:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &feat->dsc, Y_STR_ARG, &feat->exts));
+ break;
+ case LY_STMT_IF_FEATURE:
+ LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &feat->iffeatures, Y_STR_ARG, &feat->exts));
+ break;
+ case LY_STMT_REFERENCE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &feat->ref, Y_STR_ARG, &feat->exts));
+ break;
+ case LY_STMT_STATUS:
+ LY_CHECK_RET(lysp_stmt_status(ctx, child, &feat->flags, &feat->exts));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &feat->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_FEATURE));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the identity statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] identities Array of identities to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_identity(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_ident **identities)
+{
+ struct lysp_ident *ident;
+
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *identities, ident, LY_EMEM);
+
+ /* store name */
+ LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
+ LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &ident->name));
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_DESCRIPTION:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ident->dsc, Y_STR_ARG, &ident->exts));
+ break;
+ case LY_STMT_IF_FEATURE:
+ LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &ident->iffeatures, Y_STR_ARG, &ident->exts));
+ break;
+ case LY_STMT_REFERENCE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ident->ref, Y_STR_ARG, &ident->exts));
+ break;
+ case LY_STMT_STATUS:
+ LY_CHECK_RET(lysp_stmt_status(ctx, child, &ident->flags, &ident->exts));
+ break;
+ case LY_STMT_BASE:
+ LY_CHECK_RET(lysp_stmt_text_fields(ctx, child, &ident->bases, Y_PREF_IDENTIF_ARG, &ident->exts));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &ident->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_IDENTITY));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the import statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] imports Array of imports to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_import(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_import **imports)
+{
+ struct lysp_import *imp;
+ const char *str = NULL;
+
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *imports, imp, LY_EMEM);
+
+ /* store name */
+ LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
+ LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &imp->name));
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_PREFIX:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts));
+ LY_CHECK_RET(lysp_check_prefix(ctx, *imports, NULL, &imp->prefix), LY_EVALID);
+ break;
+ case LY_STMT_DESCRIPTION:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &imp->dsc, Y_STR_ARG, &imp->exts));
+ break;
+ case LY_STMT_REFERENCE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &imp->ref, Y_STR_ARG, &imp->exts));
+ break;
+ case LY_STMT_REVISION_DATE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, stmt, 0, &str, Y_STR_ARG, &imp->exts));
+ strcpy(imp->rev, str);
+ lydict_remove(PARSER_CTX(ctx), str);
+ LY_CHECK_RET(lysp_check_date(ctx, imp->rev, LY_REV_SIZE - 1, "revision-date"));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &imp->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_IMPORT));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the include statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] includes Array of identities to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_include(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_include **includes)
+{
+ struct lysp_include *inc;
+ const char *str = NULL;
+
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *includes, inc, LY_EMEM);
+
+ /* store name */
+ LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
+ LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &inc->name));
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_DESCRIPTION:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &inc->dsc, Y_STR_ARG, &inc->exts));
+ break;
+ case LY_STMT_REFERENCE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &inc->ref, Y_STR_ARG, &inc->exts));
+ break;
+ case LY_STMT_REVISION_DATE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, stmt, 0, &str, Y_STR_ARG, &inc->exts));
+ strcpy(inc->rev, str);
+ lydict_remove(PARSER_CTX(ctx), str);
+ LY_CHECK_RET(lysp_check_date(ctx, inc->rev, LY_REV_SIZE - 1, "revision-date"));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &inc->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_INCLUDE));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse the revision statement.
+ *
+ * @param[in] ctx parser context.
+ * @param[in] stmt Source statement data from the parsed extension instance.
+ * @param[in,out] includes Array of identities to add to.
+ * @return LY_ERR values.
+ */
+static LY_ERR
+lysp_stmt_revision(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_revision **revs)
+{
+ struct lysp_revision *rev;
+
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *revs, rev, LY_EMEM);
+
+ /* store date */
+ LY_CHECK_RET(lysp_check_date(ctx, stmt->arg, LY_REV_SIZE - 1, "revision"));
+ strcpy(rev->date, stmt->arg);
+
+ /* parse substatements */
+ for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
+ switch (child->kw) {
+ case LY_STMT_DESCRIPTION:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rev->dsc, Y_STR_ARG, &rev->exts));
+ break;
+ case LY_STMT_REFERENCE:
+ LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rev->ref, Y_STR_ARG, &rev->exts));
+ break;
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &rev->exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_REVISION));
+ return LY_EVALID;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
* @brief Parse the type statement.
*
* @param[in] ctx parser context.
@@ -1178,7 +1737,7 @@
break;
case LY_STMT_LENGTH:
if (type->length) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(child->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(child->kw));
return LY_EVALID;
}
type->length = calloc(1, sizeof *type->length);
@@ -1201,7 +1760,7 @@
break;
case LY_STMT_RANGE:
if (type->range) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(child->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(child->kw));
return LY_EVALID;
}
type->range = calloc(1, sizeof *type->range);
@@ -1223,7 +1782,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPE, 0, &type->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "type");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "type");
return LY_EVALID;
}
}
@@ -1296,7 +1855,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF, 0, &leaf->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "leaf");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "leaf");
return LY_EVALID;
}
}
@@ -1322,8 +1881,8 @@
* @return LY_ERR values.
*/
static LY_ERR
-lysp_stmt_maxelements(struct lysp_ctx *ctx, const struct lysp_stmt *stmt,
- uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
+lysp_stmt_maxelements(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint32_t *max, uint16_t *flags,
+ struct lysp_ext_instance **exts)
{
size_t arg_len;
char *ptr;
@@ -1369,7 +1928,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MAX_ELEMENTS, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "max-elements");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "max-elements");
return LY_EVALID;
}
}
@@ -1385,12 +1944,11 @@
* @param[in,out] min Value to write to.
* @param[in,out] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-lysp_stmt_minelements(struct lysp_ctx *ctx, const struct lysp_stmt *stmt,
- uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts)
+lysp_stmt_minelements(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint32_t *min, uint16_t *flags,
+ struct lysp_ext_instance **exts)
{
size_t arg_len;
char *ptr;
@@ -1430,7 +1988,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MIN_ELEMENTS, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "min-elements");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "min-elements");
return LY_EVALID;
}
}
@@ -1445,7 +2003,6 @@
* @param[in] stmt Source statement data from the parsed extension instance.
* @param[in,out] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1476,7 +2033,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_ORDERED_BY, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "ordered-by");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "ordered-by");
return LY_EVALID;
}
}
@@ -1491,7 +2048,6 @@
* @param[in] stmt Source statement data from the parsed extension instance.
* @param[in] parent Parent node to connect to (not into).
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1557,7 +2113,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF_LIST, 0, &llist->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "llist");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "llist");
return LY_EVALID;
}
}
@@ -1577,7 +2133,6 @@
* @param[in] ctx parser context.
* @param[in] stmt Source statement data from the parsed extension instance.
* @param[in,out] refines Refines to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1628,7 +2183,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REFINE, 0, &rf->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "refine");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "refine");
return LY_EVALID;
}
}
@@ -1684,7 +2239,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPEDEF, 0, &tpdf->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "typedef");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "typedef");
return LY_EVALID;
}
}
@@ -1718,7 +2273,7 @@
struct lysp_node_action_inout *inout_p)
{
if (inout_p->nodetype) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
@@ -1731,7 +2286,7 @@
for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
switch (child->kw) {
case LY_STMT_ANYDATA:
- PARSER_CHECK_STMTVER2_RET(ctx, "anydata", ly_stmt2str(stmt->kw));
+ PARSER_CHECK_STMTVER2_RET(ctx, "anydata", lyplg_ext_stmt2str(stmt->kw));
/* fall through */
case LY_STMT_ANYXML:
LY_CHECK_RET(lysp_stmt_any(ctx, child, &inout_p->node, &inout_p->child));
@@ -1758,7 +2313,7 @@
LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &inout_p->node, &inout_p->typedefs));
break;
case LY_STMT_MUST:
- PARSER_CHECK_STMTVER2_RET(ctx, "must", ly_stmt2str(stmt->kw));
+ PARSER_CHECK_STMTVER2_RET(ctx, "must", lyplg_ext_stmt2str(stmt->kw));
LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &inout_p->musts));
break;
case LY_STMT_GROUPING:
@@ -1768,13 +2323,13 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &inout_p->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
}
if (!inout_p->child) {
- LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(stmt->kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", lyplg_ext_stmt2str(stmt->kw));
return LY_EVALID;
}
@@ -1837,7 +2392,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, parent ? LY_STMT_ACTION : LY_STMT_RPC, 0, &act->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), parent ? "action" : "rpc");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), parent ? "action" : "rpc");
return LY_EVALID;
}
}
@@ -1935,7 +2490,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_NOTIFICATION, 0, ¬if->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "notification");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "notification");
return LY_EVALID;
}
}
@@ -2022,7 +2577,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_GROUPING, 0, &grp->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "grouping");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "grouping");
return LY_EVALID;
}
}
@@ -2112,7 +2667,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_AUGMENT, 0, &aug->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "augment");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "augment");
return LY_EVALID;
}
}
@@ -2174,7 +2729,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_USES, 0, &uses->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "uses");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "uses");
return LY_EVALID;
}
}
@@ -2254,7 +2809,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CASE, 0, &cas->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "case");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "case");
return LY_EVALID;
}
}
@@ -2343,7 +2898,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CHOICE, 0, &choice->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "choice");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "choice");
return LY_EVALID;
}
}
@@ -2445,7 +3000,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONTAINER, 0, &cont->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "container");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "container");
return LY_EVALID;
}
}
@@ -2561,7 +3116,7 @@
LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LIST, 0, &list->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "list");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "list");
return LY_EVALID;
}
}
@@ -2569,53 +3124,74 @@
return LY_SUCCESS;
}
-LY_ERR
-lysp_stmt_parse(struct lysc_ctx *ctx, const struct lysp_stmt *stmt, void **result, struct lysp_ext_instance **exts)
+/**
+ * @brief Parse generic statement structure into a specific parsed-schema structure.
+ *
+ * @param[in] pctx Parse context of the @p stmt being processed.
+ * @param[in] stmt Generic statement structure to process.
+ * @param[out] result Specific parsed-schema structure for the given statement. For the specific type for the particular statement, check the function code.
+ * @param[in,out] exts [sized array](@ref sizedarrays) For extension instances in case of statements that do not store extension instances in their own list.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lysp_stmt_parse(struct lysp_ctx *pctx, const struct lysp_stmt *stmt, void **result, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
uint16_t flags;
- struct lysp_ctx pctx = {0};
- struct ly_set pmods = {0};
- void *objs;
-
- /* local context */
- pctx.format = LYS_IN_YANG;
- pctx.parsed_mods = &pmods;
- objs = &ctx->pmod;
- pmods.objs = objs;
- pmods.count = 1;
-
- LOG_LOCSET(NULL, NULL, ctx->path, NULL);
switch (stmt->kw) {
+ case LY_STMT_NOTIFICATION:
+ ret = lysp_stmt_notif(pctx, stmt, NULL, (struct lysp_node_notif **)result);
+ break;
+ case LY_STMT_INPUT:
+ case LY_STMT_OUTPUT: {
+ struct lysp_node_action_inout *inout;
+
+ *result = inout = calloc(1, sizeof *inout);
+ LY_CHECK_ERR_RET(!inout, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ ret = lysp_stmt_inout(pctx, stmt, NULL, inout);
+ break;
+ }
case LY_STMT_ACTION:
case LY_STMT_RPC:
- ret = lysp_stmt_action(&pctx, stmt, NULL, (struct lysp_node_action **)result);
+ ret = lysp_stmt_action(pctx, stmt, NULL, (struct lysp_node_action **)result);
break;
case LY_STMT_ANYDATA:
case LY_STMT_ANYXML:
- ret = lysp_stmt_any(&pctx, stmt, NULL, (struct lysp_node **)result);
+ ret = lysp_stmt_any(pctx, stmt, NULL, (struct lysp_node **)result);
break;
case LY_STMT_AUGMENT:
- ret = lysp_stmt_augment(&pctx, stmt, NULL, (struct lysp_node_augment **)result);
- break;
- case LY_STMT_BASE:
- ret = lysp_stmt_text_fields(&pctx, stmt, (const char ***)result, Y_PREF_IDENTIF_ARG, exts);
- break;
- case LY_STMT_BIT:
- case LY_STMT_ENUM:
- ret = lysp_stmt_type_enum(&pctx, stmt, (struct lysp_type_enum **)result);
+ ret = lysp_stmt_augment(pctx, stmt, NULL, (struct lysp_node_augment **)result);
break;
case LY_STMT_CASE:
- ret = lysp_stmt_case(&pctx, stmt, NULL, (struct lysp_node **)result);
+ ret = lysp_stmt_case(pctx, stmt, NULL, (struct lysp_node **)result);
break;
case LY_STMT_CHOICE:
- ret = lysp_stmt_choice(&pctx, stmt, NULL, (struct lysp_node **)result);
+ ret = lysp_stmt_choice(pctx, stmt, NULL, (struct lysp_node **)result);
break;
- case LY_STMT_CONFIG:
- assert(*result);
- ret = lysp_stmt_config(&pctx, stmt, *(uint16_t **)result, exts);
+ case LY_STMT_CONTAINER:
+ ret = lysp_stmt_container(pctx, stmt, NULL, (struct lysp_node **)result);
break;
+ case LY_STMT_GROUPING:
+ ret = lysp_stmt_grouping(pctx, stmt, NULL, (struct lysp_node_grp **)result);
+ break;
+ case LY_STMT_LEAF:
+ ret = lysp_stmt_leaf(pctx, stmt, NULL, (struct lysp_node **)result);
+ break;
+ case LY_STMT_LEAF_LIST:
+ ret = lysp_stmt_leaflist(pctx, stmt, NULL, (struct lysp_node **)result);
+ break;
+ case LY_STMT_LIST:
+ ret = lysp_stmt_list(pctx, stmt, NULL, (struct lysp_node **)result);
+ break;
+ case LY_STMT_USES:
+ ret = lysp_stmt_uses(pctx, stmt, NULL, (struct lysp_node **)result);
+ break;
+ case LY_STMT_BASE:
+ ret = lysp_stmt_text_fields(pctx, stmt, (const char ***)result, Y_PREF_IDENTIF_ARG, exts);
+ break;
+ case LY_STMT_ARGUMENT:
+ case LY_STMT_BELONGS_TO:
case LY_STMT_CONTACT:
case LY_STMT_DESCRIPTION:
case LY_STMT_ERROR_APP_TAG:
@@ -2625,177 +3201,305 @@
case LY_STMT_ORGANIZATION:
case LY_STMT_PRESENCE:
case LY_STMT_REFERENCE:
+ case LY_STMT_REVISION_DATE:
case LY_STMT_UNITS:
- ret = lysp_stmt_text_field(&pctx, stmt, 0, (const char **)result, Y_STR_ARG, exts);
+ ret = lysp_stmt_text_field(pctx, stmt, 0, (const char **)result, Y_STR_ARG, exts);
break;
- case LY_STMT_CONTAINER:
- ret = lysp_stmt_container(&pctx, stmt, NULL, (struct lysp_node **)result);
+ case LY_STMT_BIT:
+ case LY_STMT_ENUM:
+ ret = lysp_stmt_type_enum(pctx, stmt, (struct lysp_type_enum **)result);
+ break;
+ case LY_STMT_CONFIG:
+ assert(*result);
+ ret = lysp_stmt_config(pctx, stmt, *(uint16_t **)result, exts);
break;
case LY_STMT_DEFAULT:
case LY_STMT_IF_FEATURE:
case LY_STMT_UNIQUE:
- ret = lysp_stmt_qnames(&pctx, stmt, (struct lysp_qname **)result, Y_STR_ARG, exts);
+ ret = lysp_stmt_qnames(pctx, stmt, (struct lysp_qname **)result, Y_STR_ARG, exts);
+ break;
+ case LY_STMT_DEVIATE:
+ ret = lysp_stmt_deviate(pctx, stmt, (struct lysp_deviate **)result, exts);
+ break;
+ case LY_STMT_DEVIATION:
+ ret = lysp_stmt_deviation(pctx, stmt, (struct lysp_deviation **)result);
+ break;
+ case LY_STMT_EXTENSION:
+ ret = lysp_stmt_extension(pctx, stmt, (struct lysp_ext **)result);
break;
case LY_STMT_EXTENSION_INSTANCE:
- ret = lysp_stmt_ext(&pctx, stmt, LY_STMT_EXTENSION_INSTANCE, 0, exts);
+ ret = lysp_stmt_ext(pctx, stmt, LY_STMT_EXTENSION_INSTANCE, 0, (struct lysp_ext_instance **)result);
+ break;
+ case LY_STMT_FEATURE:
+ ret = lysp_stmt_feature(pctx, stmt, (struct lysp_feature **)result);
break;
case LY_STMT_FRACTION_DIGITS:
- ret = lysp_stmt_type_fracdigits(&pctx, stmt, *(uint8_t **)result, exts);
- break;
- case LY_STMT_GROUPING:
- ret = lysp_stmt_grouping(&pctx, stmt, NULL, (struct lysp_node_grp **)result);
- break;
- case LY_STMT_INPUT:
- case LY_STMT_OUTPUT: {
- struct lysp_node_action_inout *inout;
-
- *result = inout = calloc(1, sizeof *inout);
- LY_CHECK_ERR_RET(!inout, LOGMEM(ctx->ctx), LY_EMEM);
- ret = lysp_stmt_inout(&pctx, stmt, NULL, inout);
- break;
- }
- case LY_STMT_LEAF:
- ret = lysp_stmt_leaf(&pctx, stmt, NULL, (struct lysp_node **)result);
- break;
- case LY_STMT_LEAF_LIST:
- ret = lysp_stmt_leaflist(&pctx, stmt, NULL, (struct lysp_node **)result);
+ ret = lysp_stmt_type_fracdigits(pctx, stmt, *(uint8_t **)result, exts);
break;
case LY_STMT_LENGTH:
- case LY_STMT_MUST:
- case LY_STMT_RANGE:
- ret = lysp_stmt_restrs(&pctx, stmt, (struct lysp_restr **)result);
+ case LY_STMT_RANGE: {
+ struct lysp_restr *restr;
+
+ *result = restr = calloc(1, sizeof *restr);
+ LY_CHECK_ERR_RET(!restr, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+
+ ret = lysp_stmt_restr(pctx, stmt, restr);
break;
- case LY_STMT_LIST:
- ret = lysp_stmt_list(&pctx, stmt, NULL, (struct lysp_node **)result);
+ }
+ case LY_STMT_MUST:
+ ret = lysp_stmt_restrs(pctx, stmt, (struct lysp_restr **)result);
+ break;
+ case LY_STMT_IDENTITY:
+ ret = lysp_stmt_identity(pctx, stmt, (struct lysp_ident **)result);
+ break;
+ case LY_STMT_IMPORT:
+ ret = lysp_stmt_import(pctx, stmt, (struct lysp_import **)result);
+ break;
+ case LY_STMT_INCLUDE:
+ ret = lysp_stmt_include(pctx, stmt, (struct lysp_include **)result);
break;
case LY_STMT_MANDATORY:
- ret = lysp_stmt_mandatory(&pctx, stmt, *(uint16_t **)result, exts);
+ ret = lysp_stmt_mandatory(pctx, stmt, *(uint16_t **)result, exts);
break;
case LY_STMT_MAX_ELEMENTS:
flags = 0;
- ret = lysp_stmt_maxelements(&pctx, stmt, *(uint32_t **)result, &flags, exts);
+ ret = lysp_stmt_maxelements(pctx, stmt, *(uint32_t **)result, &flags, exts);
break;
case LY_STMT_MIN_ELEMENTS:
flags = 0;
- ret = lysp_stmt_minelements(&pctx, stmt, *(uint32_t **)result, &flags, exts);
+ ret = lysp_stmt_minelements(pctx, stmt, *(uint32_t **)result, &flags, exts);
break;
case LY_STMT_MODIFIER:
- ret = lysp_stmt_type_pattern_modifier(&pctx, stmt, (const char **)result, exts);
+ ret = lysp_stmt_type_pattern_modifier(pctx, stmt, (const char **)result, exts);
break;
- case LY_STMT_NOTIFICATION:
- ret = lysp_stmt_notif(&pctx, stmt, NULL, (struct lysp_node_notif **)result);
+ case LY_STMT_MODULE: {
+ struct lysp_module *mod;
+
+ *result = mod = calloc(1, sizeof *mod);
+ LY_CHECK_ERR_RET(!mod, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ ret = lysp_stmt_module(pctx, stmt, mod);
break;
+ }
case LY_STMT_ORDERED_BY:
- ret = lysp_stmt_orderedby(&pctx, stmt, *(uint16_t **)result, exts);
+ ret = lysp_stmt_orderedby(pctx, stmt, *(uint16_t **)result, exts);
break;
case LY_STMT_PATH: {
const char *str_path = NULL;
- LY_CHECK_RET(lysp_stmt_text_field(&pctx, stmt, 0, &str_path, Y_STR_ARG, exts));
- ret = ly_path_parse(ctx->ctx, NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
+ LY_CHECK_RET(lysp_stmt_text_field(pctx, stmt, 0, &str_path, Y_STR_ARG, exts));
+ ret = ly_path_parse(PARSER_CTX(pctx), NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, (struct lyxp_expr **)result);
- lydict_remove(ctx->ctx, str_path);
+ lydict_remove(PARSER_CTX(pctx), str_path);
break;
}
case LY_STMT_PATTERN:
- ret = lysp_stmt_type_pattern(&pctx, stmt, (struct lysp_restr **)result);
+ ret = lysp_stmt_type_pattern(pctx, stmt, (struct lysp_restr **)result);
break;
case LY_STMT_POSITION:
case LY_STMT_VALUE:
flags = 0;
- ret = lysp_stmt_type_enum_value_pos(&pctx, stmt, *(int64_t **)result, &flags, exts);
+ ret = lysp_stmt_type_enum_value_pos(pctx, stmt, *(int64_t **)result, &flags, exts);
break;
case LY_STMT_PREFIX:
- ret = lysp_stmt_text_field(&pctx, stmt, 0, (const char **)result, Y_IDENTIF_ARG, exts);
+ ret = lysp_stmt_text_field(pctx, stmt, 0, (const char **)result, Y_IDENTIF_ARG, exts);
break;
case LY_STMT_REFINE:
- ret = lysp_stmt_refine(&pctx, stmt, (struct lysp_refine **)result);
+ ret = lysp_stmt_refine(pctx, stmt, (struct lysp_refine **)result);
break;
case LY_STMT_REQUIRE_INSTANCE:
flags = 0;
- ret = lysp_stmt_type_reqinstance(&pctx, stmt, *(uint8_t **)result, &flags, exts);
+ ret = lysp_stmt_type_reqinstance(pctx, stmt, *(uint8_t **)result, &flags, exts);
+ break;
+ case LY_STMT_REVISION:
+ ret = lysp_stmt_revision(pctx, stmt, (struct lysp_revision **)result);
break;
case LY_STMT_STATUS:
- ret = lysp_stmt_status(&pctx, stmt, *(uint16_t **)result, exts);
+ ret = lysp_stmt_status(pctx, stmt, (uint16_t *)result, exts);
break;
+ case LY_STMT_SUBMODULE: {
+ struct lysp_submodule *submod;
+
+ *result = submod = calloc(1, sizeof *submod);
+ LY_CHECK_ERR_RET(!submod, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ ret = lysp_stmt_submodule(pctx, stmt, submod);
+ break;
+ }
case LY_STMT_TYPE: {
struct lysp_type *type;
*result = type = calloc(1, sizeof *type);
- LY_CHECK_ERR_RET(!type, LOGMEM(ctx->ctx), LY_EMEM);
- ret = lysp_stmt_type(&pctx, stmt, type);
+ LY_CHECK_ERR_RET(!type, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ ret = lysp_stmt_type(pctx, stmt, type);
break;
}
case LY_STMT_TYPEDEF:
- ret = lysp_stmt_typedef(&pctx, stmt, NULL, (struct lysp_tpdf **)result);
- break;
- case LY_STMT_USES:
- ret = lysp_stmt_uses(&pctx, stmt, NULL, (struct lysp_node **)result);
+ ret = lysp_stmt_typedef(pctx, stmt, NULL, (struct lysp_tpdf **)result);
break;
case LY_STMT_WHEN:
- ret = lysp_stmt_when(&pctx, stmt, (struct lysp_when **)result);
+ ret = lysp_stmt_when(pctx, stmt, (struct lysp_when **)result);
+ break;
+ case LY_STMT_YANG_VERSION:
+ ret = lysp_stmt_yangver(pctx, stmt, *(uint8_t **)result, exts);
+ break;
+ case LY_STMT_YIN_ELEMENT:
+ ret = lysp_stmt_yinelem(pctx, stmt, *(uint16_t **)result, exts);
break;
default:
- LOGINT(ctx->ctx);
+ LOGINT(PARSER_CTX(pctx));
return LY_EINT;
}
- LOG_LOCBACK(0, 0, 1, 0);
return ret;
}
-void
-lys_parser_fill_filepath(struct ly_ctx *ctx, struct ly_in *in, const char **filepath)
+LY_ERR
+lys_parse_ext_instance_stmt(struct lysp_ctx *pctx, struct lysp_ext_substmt *substmt, struct lysp_stmt *stmt)
{
- char path[PATH_MAX];
+ LY_ERR rc = LY_SUCCESS;
-#ifndef __APPLE__
- char proc_path[32];
- int len;
-#endif
-
- LY_CHECK_ARG_RET(NULL, ctx, in, filepath, );
- if (*filepath) {
- /* filepath already set */
- return;
+ if (!substmt->storage) {
+ /* nothing to parse, ignored */
+ goto cleanup;
}
- switch (in->type) {
- case LY_IN_FILEPATH:
- if (realpath(in->method.fpath.filepath, path) != NULL) {
- lydict_insert(ctx, path, 0, filepath);
- } else {
- lydict_insert(ctx, in->method.fpath.filepath, 0, filepath);
+ switch (stmt->kw) {
+ case LY_STMT_NOTIFICATION:
+ case LY_STMT_INPUT:
+ case LY_STMT_OUTPUT:
+ case LY_STMT_ACTION:
+ case LY_STMT_RPC:
+ case LY_STMT_ANYDATA:
+ case LY_STMT_ANYXML:
+ case LY_STMT_AUGMENT:
+ case LY_STMT_CASE:
+ case LY_STMT_CHOICE:
+ case LY_STMT_CONTAINER:
+ case LY_STMT_GROUPING:
+ case LY_STMT_LEAF:
+ case LY_STMT_LEAF_LIST:
+ case LY_STMT_LIST:
+ case LY_STMT_USES: {
+ struct lysp_node **pnodes_p, *pnode = NULL;
+
+ /* parse the node */
+ LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, (void **)&pnode, NULL), cleanup);
+
+ /* usually is a linked-list of all the parsed schema nodes */
+ pnodes_p = substmt->storage;
+ while (*pnodes_p) {
+ pnodes_p = &(*pnodes_p)->next;
}
+ *pnodes_p = pnode;
break;
- case LY_IN_FD:
-#ifdef __APPLE__
- if (fcntl(in->method.fd, F_GETPATH, path) != -1) {
- lydict_insert(ctx, path, 0, filepath);
- }
-#elif defined _WIN32
- HANDLE h = _get_osfhandle(in->method.fd);
- FILE_NAME_INFO info;
- if (GetFileInformationByHandleEx(h, FileNameInfo, &info, sizeof info)) {
- char *buf = calloc(info.FileNameLength + 1 /* trailing NULL */, MB_CUR_MAX);
- len = wcstombs(buf, info.FileName, info.FileNameLength * MB_CUR_MAX);
- lydict_insert(ctx, buf, len, filepath);
- }
-#else
- /* get URI if there is /proc */
- sprintf(proc_path, "/proc/self/fd/%d", in->method.fd);
- if ((len = readlink(proc_path, path, PATH_MAX - 1)) > 0) {
- lydict_insert(ctx, path, len, filepath);
- }
-#endif
+ }
+ case LY_STMT_BASE:
+ case LY_STMT_BIT:
+ case LY_STMT_DEFAULT:
+ case LY_STMT_DEVIATE:
+ case LY_STMT_DEVIATION:
+ case LY_STMT_ENUM:
+ case LY_STMT_EXTENSION:
+ case LY_STMT_EXTENSION_INSTANCE:
+ case LY_STMT_FEATURE:
+ case LY_STMT_IDENTITY:
+ case LY_STMT_IF_FEATURE:
+ case LY_STMT_IMPORT:
+ case LY_STMT_INCLUDE:
+ case LY_STMT_MUST:
+ case LY_STMT_PATTERN:
+ case LY_STMT_REFINE:
+ case LY_STMT_REVISION:
+ case LY_STMT_TYPEDEF:
+ case LY_STMT_UNIQUE:
+ /* parse, sized array */
+ LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
break;
- case LY_IN_MEMORY:
- case LY_IN_FILE:
- /* nothing to do */
+
+ case LY_STMT_ARGUMENT:
+ case LY_STMT_BELONGS_TO:
+ case LY_STMT_CONTACT:
+ case LY_STMT_DESCRIPTION:
+ case LY_STMT_ERROR_APP_TAG:
+ case LY_STMT_ERROR_MESSAGE:
+ case LY_STMT_FRACTION_DIGITS:
+ case LY_STMT_KEY:
+ case LY_STMT_LENGTH:
+ case LY_STMT_MANDATORY:
+ case LY_STMT_MAX_ELEMENTS:
+ case LY_STMT_MIN_ELEMENTS:
+ case LY_STMT_MODIFIER:
+ case LY_STMT_MODULE:
+ case LY_STMT_NAMESPACE:
+ case LY_STMT_ORGANIZATION:
+ case LY_STMT_PATH:
+ case LY_STMT_POSITION:
+ case LY_STMT_PREFIX:
+ case LY_STMT_PRESENCE:
+ case LY_STMT_RANGE:
+ case LY_STMT_REFERENCE:
+ case LY_STMT_REQUIRE_INSTANCE:
+ case LY_STMT_REVISION_DATE:
+ case LY_STMT_SUBMODULE:
+ case LY_STMT_TYPE:
+ case LY_STMT_UNITS:
+ case LY_STMT_VALUE:
+ case LY_STMT_WHEN:
+ case LY_STMT_YANG_VERSION:
+ case LY_STMT_YIN_ELEMENT:
+ /* single item */
+ if (*(void **)substmt->storage) {
+ LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
+ rc = LY_EVALID;
+ goto cleanup;
+ }
+
+ /* parse */
+ LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
break;
+
+ case LY_STMT_CONFIG:
+ /* single item */
+ if ((*(uint16_t *)substmt->storage) & LYS_CONFIG_MASK) {
+ LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
+ rc = LY_EVALID;
+ goto cleanup;
+ }
+
+ /* parse */
+ LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
+ break;
+
+ case LY_STMT_ORDERED_BY:
+ /* single item */
+ if ((*(uint16_t *)substmt->storage) & LYS_ORDBY_MASK) {
+ LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
+ rc = LY_EVALID;
+ goto cleanup;
+ }
+
+ /* parse */
+ LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
+ break;
+
+ case LY_STMT_STATUS:
+ /* single item */
+ if ((*(uint16_t *)substmt->storage) & LYS_STATUS_MASK) {
+ LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
+ rc = LY_EVALID;
+ goto cleanup;
+ }
+
+ /* parse */
+ LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
+ break;
+
default:
- LOGINT(ctx);
- break;
+ LOGINT(PARSER_CTX(pctx));
+ rc = LY_EINT;
+ goto cleanup;
}
+
+cleanup:
+ return rc;
}
diff --git a/src/parser_internal.h b/src/parser_internal.h
index 09410a0..4863145 100644
--- a/src/parser_internal.h
+++ b/src/parser_internal.h
@@ -20,6 +20,8 @@
struct lyd_ctx;
struct ly_in;
+struct lysp_ext_substmt;
+struct lysp_stmt;
struct lysp_yang_ctx;
struct lysp_yin_ctx;
struct lysp_ctx;
@@ -358,4 +360,14 @@
LY_ERR lyd_parse_set_data_flags(struct lyd_node *node, struct lyd_meta **meta, struct lyd_ctx *lydctx,
struct lysc_ext_instance *ext);
+/**
+ * @brief Parse an instance extension statement.
+ *
+ * @param[in] pctx Parse context.
+ * @param[in] substmt Parsed ext instance substatement info.
+ * @param[in] stmt Parsed generic statement to process.
+ * @return LY_ERR value.
+ */
+LY_ERR lys_parse_ext_instance_stmt(struct lysp_ctx *pctx, struct lysp_ext_substmt *substmt, struct lysp_stmt *stmt);
+
#endif /* LY_PARSER_INTERNAL_H_ */
diff --git a/src/parser_json.c b/src/parser_json.c
index 3badd6c..2565c12 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -926,7 +926,7 @@
if (*node_p) {
/* insert, keep first pointer correct */
if (ext) {
- lyd_insert_ext(parent, *node_p);
+ lyplg_ext_insert(parent, *node_p);
} else {
lyd_insert_node(parent, first_p, *node_p, last);
}
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index cacda64..3daed88 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -915,7 +915,7 @@
{
/* insert, keep first pointer correct */
if (parent && (LYD_CTX(parent) != LYD_CTX(node))) {
- lyd_insert_ext(parent, node);
+ lyplg_ext_insert(parent, node);
} else {
lyd_insert_node(parent, first_p, node, lybctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0);
}
diff --git a/src/parser_xml.c b/src/parser_xml.c
index a1fd82c..ff91715 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -868,7 +868,7 @@
if (insert_anchor) {
lyd_insert_after(insert_anchor, node);
} else if (ext) {
- LY_CHECK_GOTO(ret = lyd_insert_ext(parent, node), error);
+ LY_CHECK_GOTO(ret = lyplg_ext_insert(parent, node), error);
} else {
lyd_insert_node(parent, first_p, node, lydctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0);
}
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 5db623d..cde230a 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -76,7 +76,7 @@
if (KW == LY_STMT_SYNTAX_SEMICOLON) { \
__loop_end = 1; \
} else if (KW != LY_STMT_SYNTAX_LEFT_BRACE) { \
- LOGVAL_PARSER(CTX, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\", expected \";\" or \"{\".", ly_stmt2str(KW)); \
+ LOGVAL_PARSER(CTX, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\", expected \";\" or \"{\".", lyplg_ext_stmt2str(KW)); \
RET = LY_EVALID; \
goto ERR_LABEL; \
} else { \
@@ -707,7 +707,6 @@
* @param[out] kw YANG keyword read.
* @param[out] word_p Pointer to the keyword in the data. Useful for extension instances.
* @param[out] word_len Length of the keyword in the data. Useful for extension instances.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -867,7 +866,6 @@
* @param[in] word Extension instance substatement name (keyword).
* @param[in] word_len Extension instance substatement name length.
* @param[in,out] child Children of this extension instance to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -918,15 +916,15 @@
* @param[in] ctx yang parser context for logging.
* @param[in] ext_name Extension instance substatement name (keyword).
* @param[in] ext_name_len Extension instance substatement name length.
- * @param[in] insubstmt The statement this extension instance is a substatement of.
- * @param[in] insubstmt_index Index of the keyword instance this extension instance is a substatement of.
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of @p parent statement.
+ * @param[in] parent_stmt_index In case of several @p parent_stmt, index of the relevant @p parent statement.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-parse_ext(struct lysp_yang_ctx *ctx, const char *ext_name, size_t ext_name_len, enum ly_stmt insubstmt,
- LY_ARRAY_COUNT_TYPE insubstmt_index, struct lysp_ext_instance **exts)
+parse_ext(struct lysp_yang_ctx *ctx, const char *ext_name, size_t ext_name_len, const void *parent,
+ enum ly_stmt parent_stmt, LY_ARRAY_COUNT_TYPE parent_stmt_index, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -954,8 +952,9 @@
e->format = LY_VALUE_SCHEMA;
e->parsed = NULL;
e->prefix_data = PARSER_CUR_PMOD(ctx);
- e->parent_stmt = insubstmt;
- e->parent_stmt_index = insubstmt_index;
+ e->parent = (void *)parent;
+ e->parent_stmt = parent_stmt;
+ e->parent_stmt_index = parent_stmt_index;
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
@@ -971,16 +970,16 @@
* description, etc...
*
* @param[in] ctx yang parser context for logging.
- * @param[in] substmt Type of this substatement.
- * @param[in] substmt_index Index of this substatement.
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of statement in @p value.
+ * @param[in] parent_stmt_index In case of several @p parent_stmt, index of the relevant @p parent statement.
* @param[in,out] value Place to store the parsed value.
* @param[in] arg Type of the YANG keyword argument (of the value).
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-parse_text_field(struct lysp_yang_ctx *ctx, enum ly_stmt substmt, uint32_t substmt_index,
+parse_text_field(struct lysp_yang_ctx *ctx, const void *parent, enum ly_stmt parent_stmt, uint32_t parent_stmt_index,
const char **value, enum yang_arg arg, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -989,7 +988,7 @@
enum ly_stmt kw;
if (*value) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(substmt));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(parent_stmt));
return LY_EVALID;
}
@@ -1002,10 +1001,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, substmt, substmt_index, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, parent, parent_stmt, parent_stmt_index, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(substmt));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(parent_stmt));
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1019,20 +1018,18 @@
* @brief Parse the yang-version statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[out] version Storage for the parsed information.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] mod Module to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_yangversion(struct lysp_yang_ctx *ctx, uint8_t *version, struct lysp_ext_instance **exts)
+parse_yangversion(struct lysp_yang_ctx *ctx, struct lysp_module *mod)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
size_t word_len;
enum ly_stmt kw;
- if (*version) {
+ if (mod->version) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yang-version");
return LY_EVALID;
}
@@ -1041,9 +1038,9 @@
LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
if ((word_len == 1) && !strncmp(word, "1", word_len)) {
- *version = LYS_VERSION_1_0;
+ mod->version = LYS_VERSION_1_0;
} else if ((word_len == ly_strlen_const("1.1")) && !strncmp(word, "1.1", word_len)) {
- *version = LYS_VERSION_1_1;
+ mod->version = LYS_VERSION_1_1;
} else {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "yang-version");
free(buf);
@@ -1054,10 +1051,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_YANG_VERSION, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, mod, LY_STMT_YANG_VERSION, 0, &mod->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "yang-version");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "yang-version");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1071,20 +1068,18 @@
* @brief Parse the belongs-to statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] prefix Place to store the parsed belongs-to prefix value.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] submod Submodule to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_belongsto(struct lysp_yang_ctx *ctx, const char **prefix, struct lysp_ext_instance **exts)
+parse_belongsto(struct lysp_yang_ctx *ctx, struct lysp_submodule *submod)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
size_t word_len;
enum ly_stmt kw;
- if (*prefix) {
+ if (submod->prefix) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "belongs-to");
return LY_EVALID;
}
@@ -1102,20 +1097,20 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_PREFIX:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_PREFIX, 0, prefix, Y_IDENTIF_ARG, exts));
+ LY_CHECK_RET(parse_text_field(ctx, submod->prefix, LY_STMT_PREFIX, 0, &submod->prefix, Y_IDENTIF_ARG, &submod->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_BELONGS_TO, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, submod, LY_STMT_BELONGS_TO, 0, &submod->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "belongs-to");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "belongs-to");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
/* mandatory substatements */
- if (!*prefix) {
+ if (!submod->prefix) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "prefix", "belongs-to");
return LY_EVALID;
}
@@ -1128,9 +1123,8 @@
* @brief Parse the revision-date statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] rev Array to store the parsed value in.
+ * @param[in,out] rev Buffer to store the parsed value in.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1162,10 +1156,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_REVISION_DATE, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, rev, LY_STMT_REVISION_DATE, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "revision-date");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "revision-date");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1181,7 +1175,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in] module_name Name of the module to check name collisions.
* @param[in,out] includes Parsed includes to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1211,20 +1204,20 @@
switch (kw) {
case LY_STMT_DESCRIPTION:
PARSER_CHECK_STMTVER2_RET(ctx, "description", "include");
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &inc->dsc, Y_STR_ARG, &inc->exts));
+ LY_CHECK_RET(parse_text_field(ctx, inc->dsc, LY_STMT_DESCRIPTION, 0, &inc->dsc, Y_STR_ARG, &inc->exts));
break;
case LY_STMT_REFERENCE:
PARSER_CHECK_STMTVER2_RET(ctx, "reference", "include");
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &inc->ref, Y_STR_ARG, &inc->exts));
+ LY_CHECK_RET(parse_text_field(ctx, inc->ref, LY_STMT_REFERENCE, 0, &inc->ref, Y_STR_ARG, &inc->exts));
break;
case LY_STMT_REVISION_DATE:
LY_CHECK_RET(parse_revisiondate(ctx, inc->rev, &inc->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_INCLUDE, 0, &inc->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, inc, LY_STMT_INCLUDE, 0, &inc->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "include");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "include");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, inc->exts, ret, cleanup);
@@ -1240,7 +1233,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in] module_prefix Prefix of the module to check prefix collisions.
* @param[in,out] imports Parsed imports to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1261,25 +1253,25 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_PREFIX:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_PREFIX, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts));
+ LY_CHECK_RET(parse_text_field(ctx, imp->prefix, LY_STMT_PREFIX, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts));
LY_CHECK_RET(lysp_check_prefix((struct lysp_ctx *)ctx, *imports, module_prefix, &imp->prefix), LY_EVALID);
break;
case LY_STMT_DESCRIPTION:
PARSER_CHECK_STMTVER2_RET(ctx, "description", "import");
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &imp->dsc, Y_STR_ARG, &imp->exts));
+ LY_CHECK_RET(parse_text_field(ctx, imp->dsc, LY_STMT_DESCRIPTION, 0, &imp->dsc, Y_STR_ARG, &imp->exts));
break;
case LY_STMT_REFERENCE:
PARSER_CHECK_STMTVER2_RET(ctx, "reference", "import");
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &imp->ref, Y_STR_ARG, &imp->exts));
+ LY_CHECK_RET(parse_text_field(ctx, imp->ref, LY_STMT_REFERENCE, 0, &imp->ref, Y_STR_ARG, &imp->exts));
break;
case LY_STMT_REVISION_DATE:
LY_CHECK_RET(parse_revisiondate(ctx, imp->rev, &imp->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_IMPORT, 0, &imp->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, imp, LY_STMT_IMPORT, 0, &imp->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "import");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "import");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, imp->exts, ret, cleanup);
@@ -1297,7 +1289,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] revs Parsed revisions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1326,16 +1317,16 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &rev->dsc, Y_STR_ARG, &rev->exts));
+ LY_CHECK_RET(parse_text_field(ctx, rev->dsc, LY_STMT_DESCRIPTION, 0, &rev->dsc, Y_STR_ARG, &rev->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &rev->ref, Y_STR_ARG, &rev->exts));
+ LY_CHECK_RET(parse_text_field(ctx, rev->ref, LY_STMT_REFERENCE, 0, &rev->ref, Y_STR_ARG, &rev->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_REVISION, 0, &rev->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, rev, LY_STMT_REVISION, 0, &rev->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "revision");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "revision");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, rev->exts, ret, cleanup);
@@ -1349,15 +1340,15 @@
* @brief Parse a generic text field that can have more instances such as base.
*
* @param[in] ctx yang parser context for logging.
- * @param[in] substmt Type of this substatement.
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of @p parent statement.
* @param[in,out] texts Parsed values to add to.
* @param[in] arg Type of the expected argument.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-parse_text_fields(struct lysp_yang_ctx *ctx, enum ly_stmt substmt, const char ***texts, enum yang_arg arg,
+parse_text_fields(struct lysp_yang_ctx *ctx, enum ly_stmt parent_stmt, const char ***texts, enum yang_arg arg,
struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -1376,10 +1367,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, substmt, LY_ARRAY_COUNT(*texts) - 1, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, *texts, parent_stmt, LY_ARRAY_COUNT(*texts) - 1, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(substmt));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(parent_stmt));
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1393,16 +1384,15 @@
* @brief Parse a generic text field that can have more instances such as base.
*
* @param[in] ctx yang parser context for logging.
- * @param[in] substmt Type of this substatement.
+ * @param[in] parent_stmt Type of statement stored in @p qnames.
* @param[in,out] qnames Parsed qnames to add to.
* @param[in] arg Type of the expected argument.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-parse_qnames(struct lysp_yang_ctx *ctx, enum ly_stmt substmt, struct lysp_qname **qnames,
- enum yang_arg arg, struct lysp_ext_instance **exts)
+parse_qnames(struct lysp_yang_ctx *ctx, enum ly_stmt parent_stmt, struct lysp_qname **qnames, enum yang_arg arg,
+ struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1421,10 +1411,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, substmt, LY_ARRAY_COUNT(*qnames) - 1, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, *qnames, parent_stmt, LY_ARRAY_COUNT(*qnames) - 1, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(substmt));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(parent_stmt));
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1440,7 +1430,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1473,10 +1462,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_CONFIG, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, flags, LY_STMT_CONFIG, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "config");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "config");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1492,7 +1481,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1525,10 +1513,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_MANDATORY, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, flags, LY_STMT_MANDATORY, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "mandatory");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "mandatory");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1544,7 +1532,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in] restr_kw Type of this particular restriction.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1558,28 +1545,29 @@
/* get value */
LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
- CHECK_NONEMPTY(ctx, word_len, ly_stmt2str(restr_kw));
+ CHECK_NONEMPTY(ctx, word_len, lyplg_ext_stmt2str(restr_kw));
INSERT_WORD_GOTO(ctx, buf, restr->arg.str, word, word_len, ret, cleanup);
restr->arg.mod = PARSER_CUR_PMOD(ctx);
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr->dsc, LY_STMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &restr->ref, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr->ref, LY_STMT_REFERENCE, 0, &restr->ref, Y_STR_ARG, &restr->exts));
break;
case LY_STMT_ERROR_APP_TAG:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_ERROR_APP_TAG, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr, LY_STMT_ERROR_APP_TAG, 0, &restr->eapptag, Y_STR_ARG,
+ &restr->exts));
break;
case LY_STMT_ERROR_MESSAGE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_ERROR_MESSAGE, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr, LY_STMT_ERROR_MESSAGE, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, restr_kw, 0, &restr->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, restr, restr_kw, 0, &restr->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(restr_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(restr_kw));
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, restr->exts, ret, cleanup);
@@ -1595,7 +1583,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in] restr_kw Type of this particular restriction.
* @param[in,out] restrs Restrictions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1613,7 +1600,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1648,10 +1634,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_STATUS, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, flags, LY_STMT_STATUS, 0, exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "status");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "status");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -1666,7 +1652,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] when_p When pointer to parse to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -1695,16 +1680,18 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &when->dsc, Y_STR_ARG, &when->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_text_field(ctx, when->dsc, LY_STMT_DESCRIPTION, 0, &when->dsc, Y_STR_ARG, &when->exts),
+ cleanup);
break;
case LY_STMT_REFERENCE:
- LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_REFERENCE, 0, &when->ref, Y_STR_ARG, &when->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_text_field(ctx, when->ref, LY_STMT_REFERENCE, 0, &when->ref, Y_STR_ARG, &when->exts),
+ cleanup);
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_WHEN, 0, &when->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, *when_p, LY_STMT_WHEN, 0, &when->exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "when");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "when");
ret = LY_EVALID;
goto cleanup;
}
@@ -1726,8 +1713,8 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in] any_kw Type of this particular keyword.
+ * @param[in] parent Node parent.
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -1756,7 +1743,7 @@
LY_CHECK_RET(parse_config(ctx, &any->flags, &any->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &any->dsc, Y_STR_ARG, &any->exts));
+ LY_CHECK_RET(parse_text_field(ctx, any->dsc, LY_STMT_DESCRIPTION, 0, &any->dsc, Y_STR_ARG, &any->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &any->iffeatures, Y_STR_ARG, &any->exts));
@@ -1768,7 +1755,7 @@
LY_CHECK_RET(parse_restrs(ctx, kw, &any->musts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &any->ref, Y_STR_ARG, &any->exts));
+ LY_CHECK_RET(parse_text_field(ctx, any->ref, LY_STMT_REFERENCE, 0, &any->ref, Y_STR_ARG, &any->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &any->flags, &any->exts));
@@ -1777,10 +1764,10 @@
LY_CHECK_RET(parse_when(ctx, &any->when));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, any_kw, 0, &any->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, any, any_kw, 0, &any->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(any_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(any_kw));
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, any->exts, ret, cleanup);
@@ -1795,15 +1782,11 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in] val_kw Type of this particular keyword.
- * @param[in,out] value Value to write to.
- * @param[in,out] flags Flags to write to.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] enm Structure to fill.
* @return LY_ERR values.
*/
LY_ERR
-parse_type_enum_value_pos(struct lysp_yang_ctx *ctx, enum ly_stmt val_kw, int64_t *value, uint16_t *flags,
- struct lysp_ext_instance **exts)
+parse_type_enum_value_pos(struct lysp_yang_ctx *ctx, enum ly_stmt val_kw, struct lysp_type_enum *enm)
{
LY_ERR ret = LY_SUCCESS;
char *buf = NULL, *word, *ptr;
@@ -1812,18 +1795,18 @@
unsigned long long int unum = 0;
enum ly_stmt kw;
- if (*flags & LYS_SET_VALUE) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(val_kw));
+ if (enm->flags & LYS_SET_VALUE) {
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(val_kw));
ret = LY_EVALID;
goto cleanup;
}
- *flags |= LYS_SET_VALUE;
+ enm->flags |= LYS_SET_VALUE;
/* get value */
LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
if (!word_len || (word[0] == '+') || ((word[0] == '0') && (word_len > 1)) || ((val_kw == LY_STMT_POSITION) && !strncmp(word, "-0", 2))) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, lyplg_ext_stmt2str(val_kw));
ret = LY_EVALID;
goto cleanup;
}
@@ -1832,43 +1815,43 @@
if (val_kw == LY_STMT_VALUE) {
num = strtoll(word, &ptr, LY_BASE_DEC);
if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, lyplg_ext_stmt2str(val_kw));
ret = LY_EVALID;
goto cleanup;
}
} else {
unum = strtoull(word, &ptr, LY_BASE_DEC);
if (unum > UINT64_C(4294967295)) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, lyplg_ext_stmt2str(val_kw));
ret = LY_EVALID;
goto cleanup;
}
}
/* we have not parsed the whole argument */
if ((size_t)(ptr - word) != word_len) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, lyplg_ext_stmt2str(val_kw));
ret = LY_EVALID;
goto cleanup;
}
if (errno == ERANGE) {
- LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, ly_stmt2str(val_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, lyplg_ext_stmt2str(val_kw));
ret = LY_EVALID;
goto cleanup;
}
if (val_kw == LY_STMT_VALUE) {
- *value = num;
+ enm->value = num;
} else {
- *value = unum;
+ enm->value = unum;
}
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- ret = parse_ext(ctx, word, word_len, val_kw == LY_STMT_VALUE ? LY_STMT_VALUE : LY_STMT_POSITION, 0, exts);
+ ret = parse_ext(ctx, word, word_len, enm, val_kw, 0, &enm->exts);
LY_CHECK_GOTO(ret, cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(val_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(val_kw));
ret = LY_EVALID;
goto cleanup;
}
@@ -1886,7 +1869,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in] enum_kw Type of this particular keyword.
* @param[in,out] enums Enums or bits to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1908,38 +1890,38 @@
} /* else nothing specific for YANG_BIT */
INSERT_WORD_GOTO(ctx, buf, enm->name, word, word_len, ret, cleanup);
- CHECK_UNIQUENESS(ctx, *enums, name, ly_stmt2str(enum_kw), enm->name);
+ CHECK_UNIQUENESS(ctx, *enums, name, lyplg_ext_stmt2str(enum_kw), enm->name);
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
+ LY_CHECK_RET(parse_text_field(ctx, enm->dsc, LY_STMT_DESCRIPTION, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
break;
case LY_STMT_IF_FEATURE:
- PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", ly_stmt2str(enum_kw));
+ PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", lyplg_ext_stmt2str(enum_kw));
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &enm->iffeatures, Y_STR_ARG, &enm->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &enm->ref, Y_STR_ARG, &enm->exts));
+ LY_CHECK_RET(parse_text_field(ctx, enm->ref, LY_STMT_REFERENCE, 0, &enm->ref, Y_STR_ARG, &enm->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &enm->flags, &enm->exts));
break;
case LY_STMT_VALUE:
- LY_CHECK_ERR_RET(enum_kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw),
- ly_stmt2str(enum_kw)), LY_EVALID);
- LY_CHECK_RET(parse_type_enum_value_pos(ctx, kw, &enm->value, &enm->flags, &enm->exts));
+ LY_CHECK_ERR_RET(enum_kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw),
+ lyplg_ext_stmt2str(enum_kw)), LY_EVALID);
+ LY_CHECK_RET(parse_type_enum_value_pos(ctx, kw, enm));
break;
case LY_STMT_POSITION:
- LY_CHECK_ERR_RET(enum_kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw),
- ly_stmt2str(enum_kw)), LY_EVALID);
- LY_CHECK_RET(parse_type_enum_value_pos(ctx, kw, &enm->value, &enm->flags, &enm->exts));
+ LY_CHECK_ERR_RET(enum_kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw),
+ lyplg_ext_stmt2str(enum_kw)), LY_EVALID);
+ LY_CHECK_RET(parse_type_enum_value_pos(ctx, kw, enm));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, enum_kw, 0, &enm->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, enm, enum_kw, 0, &enm->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(enum_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(enum_kw));
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, enm->exts, ret, cleanup);
@@ -1953,13 +1935,11 @@
* @brief Parse the fraction-digits statement. Substatement of type statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] fracdig Value to write to.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] type Type to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_fracdigits(struct lysp_yang_ctx *ctx, uint8_t *fracdig, struct lysp_ext_instance **exts)
+parse_type_fracdigits(struct lysp_yang_ctx *ctx, struct lysp_type *type)
{
LY_ERR ret = LY_SUCCESS;
char *buf = NULL, *word, *ptr;
@@ -1967,7 +1947,7 @@
unsigned long long int num;
enum ly_stmt kw;
- if (*fracdig) {
+ if (type->fraction_digits) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "fraction-digits");
return LY_EVALID;
}
@@ -1994,15 +1974,15 @@
ret = LY_EVALID;
goto cleanup;
}
- *fracdig = num;
+ type->fraction_digits = num;
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_FRACTION_DIGITS, 0, exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, type, LY_STMT_FRACTION_DIGITS, 0, &type->exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "fraction-digits");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "fraction-digits");
ret = LY_EVALID;
goto cleanup;
}
@@ -2018,32 +1998,28 @@
* @brief Parse the require-instance statement. Substatement of type statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] reqinst Value to write to.
- * @param[in,out] flags Flags to write to.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] type Type to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_reqinstance(struct lysp_yang_ctx *ctx, uint8_t *reqinst, uint16_t *flags,
- struct lysp_ext_instance **exts)
+parse_type_reqinstance(struct lysp_yang_ctx *ctx, struct lysp_type *type)
{
LY_ERR ret = LY_SUCCESS;
char *buf = NULL, *word;
size_t word_len;
enum ly_stmt kw;
- if (*flags & LYS_SET_REQINST) {
+ if (type->flags & LYS_SET_REQINST) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "require-instance");
return LY_EVALID;
}
- *flags |= LYS_SET_REQINST;
+ type->flags |= LYS_SET_REQINST;
/* get value */
LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if ((word_len == ly_strlen_const("true")) && !strncmp(word, "true", word_len)) {
- *reqinst = 1;
+ type->require_instance = 1;
} else if ((word_len != ly_strlen_const("false")) || strncmp(word, "false", word_len)) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "require-instance");
ret = LY_EVALID;
@@ -2053,10 +2029,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_REQUIRE_INSTANCE, 0, exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, type, LY_STMT_REQUIRE_INSTANCE, 0, &type->exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "require-instance");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "require-instance");
ret = LY_EVALID;
goto cleanup;
}
@@ -2072,20 +2048,18 @@
* @brief Parse the modifier statement. Substatement of type pattern statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] pat Value to write to.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] restr Restriction to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_pattern_modifier(struct lysp_yang_ctx *ctx, const char **pat, struct lysp_ext_instance **exts)
+parse_type_pattern_modifier(struct lysp_yang_ctx *ctx, struct lysp_restr *restr)
{
LY_ERR ret = LY_SUCCESS;
char *buf = NULL, *word;
size_t word_len;
enum ly_stmt kw;
- if ((*pat)[0] == LYSP_RESTR_PATTERN_NACK) {
+ if (restr->arg.str[0] == LYSP_RESTR_PATTERN_NACK) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "modifier");
return LY_EVALID;
}
@@ -2100,23 +2074,23 @@
}
/* replace the value in the dictionary */
- buf = malloc(strlen(*pat) + 1);
+ buf = malloc(strlen(restr->arg.str) + 1);
LY_CHECK_ERR_GOTO(!buf, LOGMEM(PARSER_CTX(ctx)); ret = LY_EMEM, cleanup);
- strcpy(buf, *pat);
- lydict_remove(PARSER_CTX(ctx), *pat);
+ strcpy(buf, restr->arg.str);
+ lydict_remove(PARSER_CTX(ctx), restr->arg.str);
assert(buf[0] == LYSP_RESTR_PATTERN_ACK);
buf[0] = LYSP_RESTR_PATTERN_NACK;
- LY_CHECK_GOTO(ret = lydict_insert_zc(PARSER_CTX(ctx), buf, pat), cleanup);
+ LY_CHECK_GOTO(ret = lydict_insert_zc(PARSER_CTX(ctx), buf, &restr->arg.str), cleanup);
buf = NULL;
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_MODIFIER, 0, exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, restr, LY_STMT_MODIFIER, 0, &restr->exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "modifier");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "modifier");
ret = LY_EVALID;
goto cleanup;
}
@@ -2133,7 +2107,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] patterns Restrictions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2169,26 +2142,26 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr->dsc, LY_STMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &restr->ref, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr->ref, LY_STMT_REFERENCE, 0, &restr->ref, Y_STR_ARG, &restr->exts));
break;
case LY_STMT_ERROR_APP_TAG:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_ERROR_APP_TAG, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr, LY_STMT_ERROR_APP_TAG, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
break;
case LY_STMT_ERROR_MESSAGE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_ERROR_MESSAGE, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
+ LY_CHECK_RET(parse_text_field(ctx, restr, LY_STMT_ERROR_MESSAGE, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
break;
case LY_STMT_MODIFIER:
PARSER_CHECK_STMTVER2_RET(ctx, "modifier", "pattern");
- LY_CHECK_RET(parse_type_pattern_modifier(ctx, &restr->arg.str, &restr->exts));
+ LY_CHECK_RET(parse_type_pattern_modifier(ctx, restr));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_PATTERN, 0, &restr->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, restr, LY_STMT_PATTERN, 0, &restr->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "pattern");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "pattern");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, restr->exts, ret, cleanup);
@@ -2203,7 +2176,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] type Type to wrote to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2243,12 +2215,12 @@
type->flags |= LYS_SET_ENUM;
break;
case LY_STMT_FRACTION_DIGITS:
- LY_CHECK_RET(parse_type_fracdigits(ctx, &type->fraction_digits, &type->exts));
+ LY_CHECK_RET(parse_type_fracdigits(ctx, type));
type->flags |= LYS_SET_FRDIGITS;
break;
case LY_STMT_LENGTH:
if (type->length) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(kw));
return LY_EVALID;
}
type->length = calloc(1, sizeof *type->length);
@@ -2259,7 +2231,7 @@
break;
case LY_STMT_PATH:
if (type->path) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(LY_STMT_PATH));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(LY_STMT_PATH));
return LY_EVALID;
}
@@ -2268,7 +2240,7 @@
* care of removing the parsed value from the dictionary. But in this case, it is not possible
* to rely on lysp_module_free because the result of the parsing is stored in a local variable.
*/
- LY_CHECK_ERR_RET(ret = parse_text_field(ctx, LY_STMT_PATH, 0, &str_path, Y_STR_ARG, &type->exts),
+ LY_CHECK_ERR_RET(ret = parse_text_field(ctx, type, LY_STMT_PATH, 0, &str_path, Y_STR_ARG, &type->exts),
lydict_remove(PARSER_CTX(ctx), str_path), ret);
ret = ly_path_parse(PARSER_CTX(ctx), NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
@@ -2283,7 +2255,7 @@
break;
case LY_STMT_RANGE:
if (type->range) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(kw));
return LY_EVALID;
}
type->range = calloc(1, sizeof *type->range);
@@ -2293,7 +2265,7 @@
type->flags |= LYS_SET_RANGE;
break;
case LY_STMT_REQUIRE_INSTANCE:
- LY_CHECK_RET(parse_type_reqinstance(ctx, &type->require_instance, &type->flags, &type->exts));
+ LY_CHECK_RET(parse_type_reqinstance(ctx, type));
/* LYS_SET_REQINST checked and set inside parse_type_reqinstance() */
break;
case LY_STMT_TYPE:
@@ -2302,10 +2274,10 @@
type->flags |= LYS_SET_TYPE;
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_TYPE, 0, &type->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, type, LY_STMT_TYPE, 0, &type->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "type");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "type");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, type->exts, ret, cleanup);
@@ -2320,7 +2292,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -2348,11 +2319,11 @@
LY_CHECK_RET(parse_config(ctx, &leaf->flags, &leaf->exts));
break;
case LY_STMT_DEFAULT:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DEFAULT, 0, &leaf->dflt.str, Y_STR_ARG, &leaf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, &leaf->dflt, LY_STMT_DEFAULT, 0, &leaf->dflt.str, Y_STR_ARG, &leaf->exts));
leaf->dflt.mod = PARSER_CUR_PMOD(ctx);
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &leaf->dsc, Y_STR_ARG, &leaf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, leaf->dsc, LY_STMT_DESCRIPTION, 0, &leaf->dsc, Y_STR_ARG, &leaf->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &leaf->iffeatures, Y_STR_ARG, &leaf->exts));
@@ -2364,7 +2335,7 @@
LY_CHECK_RET(parse_restrs(ctx, kw, &leaf->musts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &leaf->ref, Y_STR_ARG, &leaf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, leaf->ref, LY_STMT_REFERENCE, 0, &leaf->ref, Y_STR_ARG, &leaf->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &leaf->flags, &leaf->exts));
@@ -2373,16 +2344,16 @@
LY_CHECK_RET(parse_type(ctx, &leaf->type));
break;
case LY_STMT_UNITS:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_UNITS, 0, &leaf->units, Y_STR_ARG, &leaf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, leaf->units, LY_STMT_UNITS, 0, &leaf->units, Y_STR_ARG, &leaf->exts));
break;
case LY_STMT_WHEN:
LY_CHECK_RET(parse_when(ctx, &leaf->when));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_LEAF, 0, &leaf->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, leaf, LY_STMT_LEAF, 0, &leaf->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "leaf");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "leaf");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, leaf->exts, ret, cleanup);
@@ -2405,7 +2376,6 @@
* @param[in,out] max Value to write to.
* @param[in,out] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -2457,10 +2427,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_MAX_ELEMENTS, 0, exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, max, LY_STMT_MAX_ELEMENTS, 0, exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "max-elements");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "max-elements");
ret = LY_EVALID;
goto cleanup;
}
@@ -2479,7 +2449,6 @@
* @param[in,out] min Value to write to.
* @param[in,out] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -2524,10 +2493,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_MIN_ELEMENTS, 0, exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, min, LY_STMT_MIN_ELEMENTS, 0, exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "min-elements");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "min-elements");
ret = LY_EVALID;
goto cleanup;
}
@@ -2543,20 +2512,18 @@
* @brief Parse the ordered-by statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] flags Flags to write to.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] llist List or leaf-list to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_orderedby(struct lysp_yang_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_orderedby(struct lysp_yang_ctx *ctx, struct lysp_node *llist)
{
LY_ERR ret = LY_SUCCESS;
char *buf = NULL, *word;
size_t word_len;
enum ly_stmt kw;
- if (*flags & LYS_ORDBY_MASK) {
+ if (llist->flags & LYS_ORDBY_MASK) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "ordered-by");
return LY_EVALID;
}
@@ -2565,9 +2532,9 @@
LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if ((word_len == ly_strlen_const("system")) && !strncmp(word, "system", word_len)) {
- *flags |= LYS_ORDBY_SYSTEM;
+ llist->flags |= LYS_ORDBY_SYSTEM;
} else if ((word_len == ly_strlen_const("user")) && !strncmp(word, "user", word_len)) {
- *flags |= LYS_ORDBY_USER;
+ llist->flags |= LYS_ORDBY_USER;
} else {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "ordered-by");
ret = LY_EVALID;
@@ -2577,10 +2544,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_ORDERED_BY, 0, exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, llist, LY_STMT_ORDERED_BY, 0, &llist->exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "ordered-by");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "ordered-by");
ret = LY_EVALID;
goto cleanup;
}
@@ -2629,7 +2596,7 @@
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_DEFAULT, &llist->dflts, Y_STR_ARG, &llist->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &llist->dsc, Y_STR_ARG, &llist->exts));
+ LY_CHECK_RET(parse_text_field(ctx, llist->dsc, LY_STMT_DESCRIPTION, 0, &llist->dsc, Y_STR_ARG, &llist->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &llist->iffeatures, Y_STR_ARG, &llist->exts));
@@ -2644,10 +2611,10 @@
LY_CHECK_RET(parse_restrs(ctx, kw, &llist->musts));
break;
case LY_STMT_ORDERED_BY:
- LY_CHECK_RET(parse_orderedby(ctx, &llist->flags, &llist->exts));
+ LY_CHECK_RET(parse_orderedby(ctx, &llist->node));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &llist->ref, Y_STR_ARG, &llist->exts));
+ LY_CHECK_RET(parse_text_field(ctx, llist->ref, LY_STMT_REFERENCE, 0, &llist->ref, Y_STR_ARG, &llist->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &llist->flags, &llist->exts));
@@ -2656,16 +2623,16 @@
LY_CHECK_RET(parse_type(ctx, &llist->type));
break;
case LY_STMT_UNITS:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_UNITS, 0, &llist->units, Y_STR_ARG, &llist->exts));
+ LY_CHECK_RET(parse_text_field(ctx, llist->units, LY_STMT_UNITS, 0, &llist->units, Y_STR_ARG, &llist->exts));
break;
case LY_STMT_WHEN:
LY_CHECK_RET(parse_when(ctx, &llist->when));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_LEAF_LIST, 0, &llist->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, llist, LY_STMT_LEAF_LIST, 0, &llist->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "llist");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "llist");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, llist->exts, ret, cleanup);
@@ -2686,7 +2653,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] refines Refines to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2714,7 +2680,7 @@
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_DEFAULT, &rf->dflts, Y_STR_ARG, &rf->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &rf->dsc, Y_STR_ARG, &rf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, rf->dsc, LY_STMT_DESCRIPTION, 0, &rf->dsc, Y_STR_ARG, &rf->exts));
break;
case LY_STMT_IF_FEATURE:
PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "refine");
@@ -2733,16 +2699,16 @@
LY_CHECK_RET(parse_mandatory(ctx, &rf->flags, &rf->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &rf->ref, Y_STR_ARG, &rf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, rf->ref, LY_STMT_REFERENCE, 0, &rf->ref, Y_STR_ARG, &rf->exts));
break;
case LY_STMT_PRESENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_PRESENCE, 0, &rf->presence, Y_STR_ARG, &rf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, rf->presence, LY_STMT_PRESENCE, 0, &rf->presence, Y_STR_ARG, &rf->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_REFINE, 0, &rf->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, rf, LY_STMT_REFINE, 0, &rf->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "refine");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "refine");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, rf->exts, ret, cleanup);
@@ -2757,7 +2723,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] typedefs Typedefs to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2779,14 +2744,14 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DEFAULT:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DEFAULT, 0, &tpdf->dflt.str, Y_STR_ARG, &tpdf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, &tpdf->dflt, LY_STMT_DEFAULT, 0, &tpdf->dflt.str, Y_STR_ARG, &tpdf->exts));
tpdf->dflt.mod = PARSER_CUR_PMOD(ctx);
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &tpdf->dsc, Y_STR_ARG, &tpdf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, tpdf->dsc, LY_STMT_DESCRIPTION, 0, &tpdf->dsc, Y_STR_ARG, &tpdf->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &tpdf->ref, Y_STR_ARG, &tpdf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, tpdf->ref, LY_STMT_REFERENCE, 0, &tpdf->ref, Y_STR_ARG, &tpdf->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &tpdf->flags, &tpdf->exts));
@@ -2795,13 +2760,13 @@
LY_CHECK_RET(parse_type(ctx, &tpdf->type));
break;
case LY_STMT_UNITS:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_UNITS, 0, &tpdf->units, Y_STR_ARG, &tpdf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, tpdf->units, LY_STMT_UNITS, 0, &tpdf->units, Y_STR_ARG, &tpdf->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_TYPEDEF, 0, &tpdf->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, tpdf, LY_STMT_TYPEDEF, 0, &tpdf->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "typedef");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "typedef");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, tpdf->exts, ret, cleanup);
@@ -2829,7 +2794,6 @@
* @param[in] ctx yang parser context for logging.
* @param[in] kw Type of this particular keyword
* @param[in,out] inout_p Input/output pointer to write to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2843,7 +2807,7 @@
ly_bool input = &((struct lysp_node_action *)parent)->input == inout_p ? 1 : 0;
if (inout_p->nodetype) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(inout_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(inout_kw));
return LY_EVALID;
}
@@ -2856,7 +2820,7 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_ANYDATA:
- PARSER_CHECK_STMTVER2_RET(ctx, "anydata", ly_stmt2str(inout_kw));
+ PARSER_CHECK_STMTVER2_RET(ctx, "anydata", lyplg_ext_stmt2str(inout_kw));
/* fall through */
case LY_STMT_ANYXML:
LY_CHECK_RET(parse_any(ctx, kw, (struct lysp_node *)inout_p, &inout_p->child));
@@ -2883,24 +2847,24 @@
LY_CHECK_RET(parse_typedef(ctx, (struct lysp_node *)inout_p, &inout_p->typedefs));
break;
case LY_STMT_MUST:
- PARSER_CHECK_STMTVER2_RET(ctx, "must", ly_stmt2str(inout_kw));
+ PARSER_CHECK_STMTVER2_RET(ctx, "must", lyplg_ext_stmt2str(inout_kw));
LY_CHECK_RET(parse_restrs(ctx, kw, &inout_p->musts));
break;
case LY_STMT_GROUPING:
LY_CHECK_RET(parse_grouping(ctx, (struct lysp_node *)inout_p, &inout_p->groupings));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, inout_kw, 0, &inout_p->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, inout_p, inout_kw, 0, &inout_p->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(inout_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(inout_kw));
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, inout_p->exts, ret, cleanup);
}
if (!inout_p->child) {
- LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(inout_kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", lyplg_ext_stmt2str(inout_kw));
return LY_EVALID;
}
@@ -2913,7 +2877,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] actions Actions to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -2936,13 +2899,13 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &act->dsc, Y_STR_ARG, &act->exts));
+ LY_CHECK_RET(parse_text_field(ctx, act->dsc, LY_STMT_DESCRIPTION, 0, &act->dsc, Y_STR_ARG, &act->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &act->iffeatures, Y_STR_ARG, &act->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &act->ref, Y_STR_ARG, &act->exts));
+ LY_CHECK_RET(parse_text_field(ctx, act->ref, LY_STMT_REFERENCE, 0, &act->ref, Y_STR_ARG, &act->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &act->flags, &act->exts));
@@ -2962,10 +2925,10 @@
LY_CHECK_RET(parse_grouping(ctx, (struct lysp_node *)act, &act->groupings));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, parent ? LY_STMT_ACTION : LY_STMT_RPC, 0, &act->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, act, parent ? LY_STMT_ACTION : LY_STMT_RPC, 0, &act->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), parent ? "action" : "rpc");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), parent ? "action" : "rpc");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, act->exts, ret, cleanup);
@@ -2992,7 +2955,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] notifs Notifications to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3015,13 +2977,13 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, ¬if->dsc, Y_STR_ARG, ¬if->exts));
+ LY_CHECK_RET(parse_text_field(ctx, notif->dsc, LY_STMT_DESCRIPTION, 0, ¬if->dsc, Y_STR_ARG, ¬if->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, ¬if->iffeatures, Y_STR_ARG, ¬if->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, ¬if->ref, Y_STR_ARG, ¬if->exts));
+ LY_CHECK_RET(parse_text_field(ctx, notif->ref, LY_STMT_REFERENCE, 0, ¬if->ref, Y_STR_ARG, ¬if->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, ¬if->flags, ¬if->exts));
@@ -3063,10 +3025,10 @@
LY_CHECK_RET(parse_grouping(ctx, (struct lysp_node *)notif, ¬if->groupings));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_NOTIFICATION, 0, ¬if->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, notif, LY_STMT_NOTIFICATION, 0, ¬if->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "notification");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "notification");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, notif->exts, ret, cleanup);
@@ -3081,7 +3043,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] groupings Groupings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3104,10 +3065,10 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &grp->dsc, Y_STR_ARG, &grp->exts));
+ LY_CHECK_RET(parse_text_field(ctx, grp->dsc, LY_STMT_DESCRIPTION, 0, &grp->dsc, Y_STR_ARG, &grp->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &grp->ref, Y_STR_ARG, &grp->exts));
+ LY_CHECK_RET(parse_text_field(ctx, grp->ref, LY_STMT_REFERENCE, 0, &grp->ref, Y_STR_ARG, &grp->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &grp->flags, &grp->exts));
@@ -3153,10 +3114,10 @@
LY_CHECK_RET(parse_notif(ctx, &grp->node, &grp->notifs));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_GROUPING, 0, &grp->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, grp, LY_STMT_GROUPING, 0, &grp->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "grouping");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "grouping");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, grp->exts, ret, cleanup);
@@ -3177,7 +3138,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] augments Augments to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3201,13 +3161,13 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
+ LY_CHECK_RET(parse_text_field(ctx, aug->dsc, LY_STMT_DESCRIPTION, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &aug->iffeatures, Y_STR_ARG, &aug->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &aug->ref, Y_STR_ARG, &aug->exts));
+ LY_CHECK_RET(parse_text_field(ctx, aug->ref, LY_STMT_REFERENCE, 0, &aug->ref, Y_STR_ARG, &aug->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &aug->flags, &aug->exts));
@@ -3253,10 +3213,10 @@
LY_CHECK_RET(parse_notif(ctx, (struct lysp_node *)aug, &aug->notifs));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_AUGMENT, 0, &aug->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, aug, LY_STMT_AUGMENT, 0, &aug->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "augment");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "augment");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, aug->exts, ret, cleanup);
@@ -3271,7 +3231,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3296,13 +3255,13 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
+ LY_CHECK_RET(parse_text_field(ctx, uses->dsc, LY_STMT_DESCRIPTION, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &uses->iffeatures, Y_STR_ARG, &uses->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &uses->ref, Y_STR_ARG, &uses->exts));
+ LY_CHECK_RET(parse_text_field(ctx, uses->ref, LY_STMT_REFERENCE, 0, &uses->ref, Y_STR_ARG, &uses->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &uses->flags, &uses->exts));
@@ -3318,10 +3277,10 @@
LY_CHECK_RET(parse_augment(ctx, (struct lysp_node *)uses, &uses->augments));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_USES, 0, &uses->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, uses, LY_STMT_USES, 0, &uses->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "uses");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "uses");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, uses->exts, ret, cleanup);
@@ -3336,7 +3295,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3361,13 +3319,13 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
+ LY_CHECK_RET(parse_text_field(ctx, cas->dsc, LY_STMT_DESCRIPTION, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &cas->iffeatures, Y_STR_ARG, &cas->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &cas->ref, Y_STR_ARG, &cas->exts));
+ LY_CHECK_RET(parse_text_field(ctx, cas->ref, LY_STMT_REFERENCE, 0, &cas->ref, Y_STR_ARG, &cas->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &cas->flags, &cas->exts));
@@ -3401,10 +3359,10 @@
LY_CHECK_RET(parse_uses(ctx, (struct lysp_node *)cas, &cas->child));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_CASE, 0, &cas->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, cas, LY_STMT_CASE, 0, &cas->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "case");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "case");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, cas->exts, ret, cleanup);
@@ -3419,7 +3377,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3447,7 +3404,7 @@
LY_CHECK_RET(parse_config(ctx, &choice->flags, &choice->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &choice->dsc, Y_STR_ARG, &choice->exts));
+ LY_CHECK_RET(parse_text_field(ctx, choice->dsc, LY_STMT_DESCRIPTION, 0, &choice->dsc, Y_STR_ARG, &choice->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &choice->iffeatures, Y_STR_ARG, &choice->exts));
@@ -3456,7 +3413,7 @@
LY_CHECK_RET(parse_mandatory(ctx, &choice->flags, &choice->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &choice->ref, Y_STR_ARG, &choice->exts));
+ LY_CHECK_RET(parse_text_field(ctx, choice->ref, LY_STMT_REFERENCE, 0, &choice->ref, Y_STR_ARG, &choice->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &choice->flags, &choice->exts));
@@ -3465,7 +3422,7 @@
LY_CHECK_RET(parse_when(ctx, &choice->when));
break;
case LY_STMT_DEFAULT:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DEFAULT, 0, &choice->dflt.str, Y_PREF_IDENTIF_ARG,
+ LY_CHECK_RET(parse_text_field(ctx, &choice->dflt, LY_STMT_DEFAULT, 0, &choice->dflt.str, Y_PREF_IDENTIF_ARG,
&choice->exts));
choice->dflt.mod = PARSER_CUR_PMOD(ctx);
break;
@@ -3496,10 +3453,10 @@
LY_CHECK_RET(parse_list(ctx, (struct lysp_node *)choice, &choice->child));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_CHOICE, 0, &choice->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, choice, LY_STMT_CHOICE, 0, &choice->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "choice");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "choice");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, choice->exts, ret, cleanup);
@@ -3514,7 +3471,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3542,13 +3498,13 @@
LY_CHECK_RET(parse_config(ctx, &cont->flags, &cont->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &cont->dsc, Y_STR_ARG, &cont->exts));
+ LY_CHECK_RET(parse_text_field(ctx, cont->dsc, LY_STMT_DESCRIPTION, 0, &cont->dsc, Y_STR_ARG, &cont->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &cont->iffeatures, Y_STR_ARG, &cont->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &cont->ref, Y_STR_ARG, &cont->exts));
+ LY_CHECK_RET(parse_text_field(ctx, cont->ref, LY_STMT_REFERENCE, 0, &cont->ref, Y_STR_ARG, &cont->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &cont->flags, &cont->exts));
@@ -3557,7 +3513,7 @@
LY_CHECK_RET(parse_when(ctx, &cont->when));
break;
case LY_STMT_PRESENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_PRESENCE, 0, &cont->presence, Y_STR_ARG, &cont->exts));
+ LY_CHECK_RET(parse_text_field(ctx, cont->presence, LY_STMT_PRESENCE, 0, &cont->presence, Y_STR_ARG, &cont->exts));
break;
case LY_STMT_ANYDATA:
@@ -3603,10 +3559,10 @@
LY_CHECK_RET(parse_notif(ctx, (struct lysp_node *)cont, &cont->notifs));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_CONTAINER, 0, &cont->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, cont, LY_STMT_CONTAINER, 0, &cont->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "container");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "container");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, cont->exts, ret, cleanup);
@@ -3621,7 +3577,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] siblings Siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3649,13 +3604,13 @@
LY_CHECK_RET(parse_config(ctx, &list->flags, &list->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &list->dsc, Y_STR_ARG, &list->exts));
+ LY_CHECK_RET(parse_text_field(ctx, list->dsc, LY_STMT_DESCRIPTION, 0, &list->dsc, Y_STR_ARG, &list->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &list->iffeatures, Y_STR_ARG, &list->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &list->ref, Y_STR_ARG, &list->exts));
+ LY_CHECK_RET(parse_text_field(ctx, list->ref, LY_STMT_REFERENCE, 0, &list->ref, Y_STR_ARG, &list->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &list->flags, &list->exts));
@@ -3664,7 +3619,7 @@
LY_CHECK_RET(parse_when(ctx, &list->when));
break;
case LY_STMT_KEY:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_KEY, 0, &list->key, Y_STR_ARG, &list->exts));
+ LY_CHECK_RET(parse_text_field(ctx, list, LY_STMT_KEY, 0, &list->key, Y_STR_ARG, &list->exts));
break;
case LY_STMT_MAX_ELEMENTS:
LY_CHECK_RET(parse_maxelements(ctx, &list->max, &list->flags, &list->exts));
@@ -3673,7 +3628,7 @@
LY_CHECK_RET(parse_minelements(ctx, &list->min, &list->flags, &list->exts));
break;
case LY_STMT_ORDERED_BY:
- LY_CHECK_RET(parse_orderedby(ctx, &list->flags, &list->exts));
+ LY_CHECK_RET(parse_orderedby(ctx, &list->node));
break;
case LY_STMT_UNIQUE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_UNIQUE, &list->uniques, Y_STR_ARG, &list->exts));
@@ -3722,10 +3677,10 @@
LY_CHECK_RET(parse_notif(ctx, (struct lysp_node *)list, &list->notifs));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_LIST, 0, &list->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, list, LY_STMT_LIST, 0, &list->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "list");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "list");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, list->exts, ret, cleanup);
@@ -3739,20 +3694,18 @@
* @brief Parse the yin-element statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] flags Flags to write to.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] ext Extension to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_yinelement(struct lysp_yang_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_yinelement(struct lysp_yang_ctx *ctx, struct lysp_ext *ext)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
size_t word_len;
enum ly_stmt kw;
- if (*flags & LYS_YINELEM_MASK) {
+ if (ext->flags & LYS_YINELEM_MASK) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yin-element");
return LY_EVALID;
}
@@ -3761,9 +3714,9 @@
LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
if ((word_len == ly_strlen_const("true")) && !strncmp(word, "true", word_len)) {
- *flags |= LYS_YINELEM_TRUE;
+ ext->flags |= LYS_YINELEM_TRUE;
} else if ((word_len == ly_strlen_const("false")) && !strncmp(word, "false", word_len)) {
- *flags |= LYS_YINELEM_FALSE;
+ ext->flags |= LYS_YINELEM_FALSE;
} else {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "yin-element");
free(buf);
@@ -3774,11 +3727,11 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_YIN_ELEMENT, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, ext, LY_STMT_YIN_ELEMENT, 0, &ext->exts));
LY_CHECK_RET(ret);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "yin-element");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "yin-element");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -3792,39 +3745,36 @@
* @brief Parse the argument statement.
*
* @param[in] ctx yang parser context for logging.
- * @param[in,out] argument Value to write to.
- * @param[in,out] flags Flags to write to.
- * @param[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] ext Extension to fill.
* @return LY_ERR values.
*/
static LY_ERR
-parse_argument(struct lysp_yang_ctx *ctx, const char **argument, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_argument(struct lysp_yang_ctx *ctx, struct lysp_ext *ext)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
size_t word_len;
enum ly_stmt kw;
- if (*argument) {
+ if (ext->argname) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "argument");
return LY_EVALID;
}
/* get value */
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
- INSERT_WORD_GOTO(ctx, buf, *argument, word, word_len, ret, cleanup);
+ INSERT_WORD_GOTO(ctx, buf, ext->argname, word, word_len, ret, cleanup);
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_YIN_ELEMENT:
- LY_CHECK_RET(parse_yinelement(ctx, flags, exts));
+ LY_CHECK_RET(parse_yinelement(ctx, ext));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_ARGUMENT, 0, exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, ext, LY_STMT_ARGUMENT, 0, &ext->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "argument");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "argument");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
@@ -3839,7 +3789,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] extensions Extensions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -3860,22 +3809,22 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &ex->dsc, Y_STR_ARG, &ex->exts));
+ LY_CHECK_RET(parse_text_field(ctx, ex->dsc, LY_STMT_DESCRIPTION, 0, &ex->dsc, Y_STR_ARG, &ex->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &ex->ref, Y_STR_ARG, &ex->exts));
+ LY_CHECK_RET(parse_text_field(ctx, ex->ref, LY_STMT_REFERENCE, 0, &ex->ref, Y_STR_ARG, &ex->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &ex->flags, &ex->exts));
break;
case LY_STMT_ARGUMENT:
- LY_CHECK_RET(parse_argument(ctx, &ex->argname, &ex->flags, &ex->exts));
+ LY_CHECK_RET(parse_argument(ctx, ex));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_EXTENSION, 0, &ex->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, ex, LY_STMT_EXTENSION, 0, &ex->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "extension");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "extension");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, ex->exts, ret, cleanup);
@@ -3890,7 +3839,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] deviates Deviates to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -3978,7 +3926,7 @@
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
case LYS_DEV_DELETE:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
@@ -3989,11 +3937,12 @@
case LY_STMT_DEFAULT:
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
case LYS_DEV_REPLACE:
- LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_DEFAULT, 0, &d_rpl->dflt.str, Y_STR_ARG, &d->exts), cleanup);
+ ret = parse_text_field(ctx, &d_rpl->dflt, LY_STMT_DEFAULT, 0, &d_rpl->dflt.str, Y_STR_ARG, &d->exts);
+ LY_CHECK_GOTO(ret, cleanup);
d_rpl->dflt.mod = PARSER_CUR_PMOD(ctx);
break;
default:
@@ -4005,7 +3954,7 @@
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
case LYS_DEV_DELETE:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
@@ -4017,7 +3966,7 @@
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
case LYS_DEV_DELETE:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
@@ -4029,7 +3978,7 @@
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
case LYS_DEV_DELETE:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
@@ -4041,7 +3990,7 @@
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
case LYS_DEV_REPLACE:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
@@ -4054,12 +4003,12 @@
case LYS_DEV_NOT_SUPPORTED:
case LYS_DEV_ADD:
case LYS_DEV_DELETE:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
if (d_rpl->type) {
- LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
}
@@ -4073,7 +4022,7 @@
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
case LYS_DEV_REPLACE:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
@@ -4084,19 +4033,19 @@
case LY_STMT_UNITS:
switch (dev_mod) {
case LYS_DEV_NOT_SUPPORTED:
- LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
+ LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
default:
- LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_UNITS, 0, d_units, Y_STR_ARG, &d->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_text_field(ctx, *d_units, LY_STMT_UNITS, 0, d_units, Y_STR_ARG, &d->exts), cleanup);
break;
}
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_DEVIATE, 0, &d->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, d, LY_STMT_DEVIATE, 0, &d->exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "deviate");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "deviate");
ret = LY_EVALID;
goto cleanup;
}
@@ -4120,7 +4069,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] deviations Deviations to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -4143,19 +4091,19 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &dev->dsc, Y_STR_ARG, &dev->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_text_field(ctx, dev->dsc, LY_STMT_DESCRIPTION, 0, &dev->dsc, Y_STR_ARG, &dev->exts), cleanup);
break;
case LY_STMT_DEVIATE:
LY_CHECK_GOTO(ret = parse_deviate(ctx, &dev->deviates), cleanup);
break;
case LY_STMT_REFERENCE:
- LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_REFERENCE, 0, &dev->ref, Y_STR_ARG, &dev->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_text_field(ctx, dev->ref, LY_STMT_REFERENCE, 0, &dev->ref, Y_STR_ARG, &dev->exts), cleanup);
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_DEVIATION, 0, &dev->exts), cleanup);
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, dev, LY_STMT_DEVIATION, 0, &dev->exts), cleanup);
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "deviation");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "deviation");
ret = LY_EVALID;
goto cleanup;
}
@@ -4182,7 +4130,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] features Features to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -4203,22 +4150,22 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &feat->dsc, Y_STR_ARG, &feat->exts));
+ LY_CHECK_RET(parse_text_field(ctx, feat->dsc, LY_STMT_DESCRIPTION, 0, &feat->dsc, Y_STR_ARG, &feat->exts));
break;
case LY_STMT_IF_FEATURE:
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &feat->iffeatures, Y_STR_ARG, &feat->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &feat->ref, Y_STR_ARG, &feat->exts));
+ LY_CHECK_RET(parse_text_field(ctx, feat->ref, LY_STMT_REFERENCE, 0, &feat->ref, Y_STR_ARG, &feat->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &feat->flags, &feat->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_FEATURE, 0, &feat->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, feat, LY_STMT_FEATURE, 0, &feat->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "feature");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "feature");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, feat->exts, ret, cleanup);
@@ -4233,7 +4180,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] identities Identities to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -4254,14 +4200,14 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &ident->dsc, Y_STR_ARG, &ident->exts));
+ LY_CHECK_RET(parse_text_field(ctx, ident->dsc, LY_STMT_DESCRIPTION, 0, &ident->dsc, Y_STR_ARG, &ident->exts));
break;
case LY_STMT_IF_FEATURE:
PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "identity");
LY_CHECK_RET(parse_qnames(ctx, LY_STMT_IF_FEATURE, &ident->iffeatures, Y_STR_ARG, &ident->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &ident->ref, Y_STR_ARG, &ident->exts));
+ LY_CHECK_RET(parse_text_field(ctx, ident->ref, LY_STMT_REFERENCE, 0, &ident->ref, Y_STR_ARG, &ident->exts));
break;
case LY_STMT_STATUS:
LY_CHECK_RET(parse_status(ctx, &ident->flags, &ident->exts));
@@ -4274,10 +4220,10 @@
LY_CHECK_RET(parse_text_fields(ctx, LY_STMT_BASE, &ident->bases, Y_PREF_IDENTIF_ARG, &ident->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_IDENTITY, 0, &ident->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, ident, LY_STMT_IDENTITY, 0, &ident->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "identity");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "identity");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, ident->exts, ret, cleanup);
@@ -4292,7 +4238,6 @@
*
* @param[in] ctx yang parser context for logging.
* @param[in,out] mod Module to write to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -4314,7 +4259,9 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
#define CHECK_ORDER(SECTION) \
- if (mod_stmt > SECTION) {LOGVAL_PARSER(ctx, LY_VCODE_INORD, ly_stmt2str(kw), ly_stmt2str(prev_kw)); return LY_EVALID;}mod_stmt = SECTION
+ if (mod_stmt > SECTION) {\
+ LOGVAL_PARSER(ctx, LY_VCODE_INORD, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(prev_kw)); return LY_EVALID;\
+ } mod_stmt = SECTION
switch (kw) {
/* module header */
@@ -4375,13 +4322,13 @@
switch (kw) {
/* module header */
case LY_STMT_YANG_VERSION:
- LY_CHECK_RET(parse_yangversion(ctx, &mod->version, &mod->exts));
+ LY_CHECK_RET(parse_yangversion(ctx, mod));
break;
case LY_STMT_NAMESPACE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_NAMESPACE, 0, &mod->mod->ns, Y_STR_ARG, &mod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, mod, LY_STMT_NAMESPACE, 0, &mod->mod->ns, Y_STR_ARG, &mod->exts));
break;
case LY_STMT_PREFIX:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_PREFIX, 0, &mod->mod->prefix, Y_IDENTIF_ARG, &mod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, mod->mod->prefix, LY_STMT_PREFIX, 0, &mod->mod->prefix, Y_IDENTIF_ARG, &mod->exts));
break;
/* linkage */
@@ -4394,16 +4341,16 @@
/* meta */
case LY_STMT_ORGANIZATION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_ORGANIZATION, 0, &mod->mod->org, Y_STR_ARG, &mod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, mod, LY_STMT_ORGANIZATION, 0, &mod->mod->org, Y_STR_ARG, &mod->exts));
break;
case LY_STMT_CONTACT:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_CONTACT, 0, &mod->mod->contact, Y_STR_ARG, &mod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, mod, LY_STMT_CONTACT, 0, &mod->mod->contact, Y_STR_ARG, &mod->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &mod->mod->dsc, Y_STR_ARG, &mod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, mod->mod->dsc, LY_STMT_DESCRIPTION, 0, &mod->mod->dsc, Y_STR_ARG, &mod->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &mod->mod->ref, Y_STR_ARG, &mod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, mod->mod->ref, LY_STMT_REFERENCE, 0, &mod->mod->ref, Y_STR_ARG, &mod->exts));
break;
/* revision */
@@ -4465,11 +4412,11 @@
LY_CHECK_RET(parse_typedef(ctx, NULL, &mod->typedefs));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_MODULE, 0, &mod->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, mod, LY_STMT_MODULE, 0, &mod->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "module");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "module");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, mod->exts, ret, cleanup);
@@ -4523,7 +4470,7 @@
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
#define CHECK_ORDER(SECTION) \
- if (mod_stmt > SECTION) {LOGVAL_PARSER(ctx, LY_VCODE_INORD, ly_stmt2str(kw), ly_stmt2str(prev_kw)); return LY_EVALID;}mod_stmt = SECTION
+ if (mod_stmt > SECTION) {LOGVAL_PARSER(ctx, LY_VCODE_INORD, lyplg_ext_stmt2str(kw), lyplg_ext_stmt2str(prev_kw)); return LY_EVALID;}mod_stmt = SECTION
switch (kw) {
/* module header */
@@ -4583,10 +4530,10 @@
switch (kw) {
/* module header */
case LY_STMT_YANG_VERSION:
- LY_CHECK_RET(parse_yangversion(ctx, &submod->version, &submod->exts));
+ LY_CHECK_RET(parse_yangversion(ctx, (struct lysp_module *)submod));
break;
case LY_STMT_BELONGS_TO:
- LY_CHECK_RET(parse_belongsto(ctx, &submod->prefix, &submod->exts));
+ LY_CHECK_RET(parse_belongsto(ctx, submod));
break;
/* linkage */
@@ -4603,16 +4550,16 @@
/* meta */
case LY_STMT_ORGANIZATION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_ORGANIZATION, 0, &submod->org, Y_STR_ARG, &submod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, submod, LY_STMT_ORGANIZATION, 0, &submod->org, Y_STR_ARG, &submod->exts));
break;
case LY_STMT_CONTACT:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_CONTACT, 0, &submod->contact, Y_STR_ARG, &submod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, submod, LY_STMT_CONTACT, 0, &submod->contact, Y_STR_ARG, &submod->exts));
break;
case LY_STMT_DESCRIPTION:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &submod->dsc, Y_STR_ARG, &submod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, submod->dsc, LY_STMT_DESCRIPTION, 0, &submod->dsc, Y_STR_ARG, &submod->exts));
break;
case LY_STMT_REFERENCE:
- LY_CHECK_RET(parse_text_field(ctx, LY_STMT_REFERENCE, 0, &submod->ref, Y_STR_ARG, &submod->exts));
+ LY_CHECK_RET(parse_text_field(ctx, submod->ref, LY_STMT_REFERENCE, 0, &submod->ref, Y_STR_ARG, &submod->exts));
break;
/* revision */
@@ -4674,11 +4621,11 @@
LY_CHECK_RET(parse_typedef(ctx, NULL, &submod->typedefs));
break;
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_SUBMODULE, 0, &submod->exts));
+ LY_CHECK_RET(parse_ext(ctx, word, word_len, submod, LY_STMT_SUBMODULE, 0, &submod->exts));
break;
default:
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "submodule");
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(kw), "submodule");
return LY_EVALID;
}
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, submod->exts, ret, cleanup);
@@ -4781,7 +4728,7 @@
ret = LY_EINVAL;
goto cleanup;
} else if (kw != LY_STMT_SUBMODULE) {
- LOGVAL_PARSER(*context, LY_VCODE_MOD_SUBOMD, ly_stmt2str(kw));
+ LOGVAL_PARSER(*context, LY_VCODE_MOD_SUBOMD, lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
}
@@ -4851,7 +4798,7 @@
ret = LY_EINVAL;
goto cleanup;
} else if (kw != LY_STMT_MODULE) {
- LOGVAL_PARSER((*context), LY_VCODE_MOD_SUBOMD, ly_stmt2str(kw));
+ LOGVAL_PARSER((*context), LY_VCODE_MOD_SUBOMD, lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
}
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 50f2b66..7382796 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -104,8 +104,10 @@
struct yin_subelement {
enum ly_stmt type; /**< type of keyword */
- void *dest; /**< meta infromation passed to responsible function (mostly information about where parsed subelement should be stored) */
- uint16_t flags; /**< describes constraints of subelement can be set to YIN_SUBELEM_MANDATORY, YIN_SUBELEM_UNIQUE, YIN_SUBELEM_FIRST, YIN_SUBELEM_VER2, and YIN_SUBELEM_DEFAULT_TEXT */
+ void *dest; /**< meta infromation passed to responsible function (mostly information about where parsed
+ subelement should be stored) */
+ uint16_t flags; /**< describes constraints of subelement can be set to YIN_SUBELEM_MANDATORY,
+ YIN_SUBELEM_UNIQUE, YIN_SUBELEM_FIRST, YIN_SUBELEM_VER2, and YIN_SUBELEM_DEFAULT_TEXT */
};
/* Meta information passed to yin_parse_argument function,
@@ -158,7 +160,7 @@
};
LY_ERR yin_parse_content(struct lysp_yin_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
- enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts);
+ const void *parent, enum ly_stmt parent_stmt, const char **text_content, struct lysp_ext_instance **exts);
/**
* @brief Match yang keyword from yin data.
@@ -168,13 +170,12 @@
* @param[in] name_len Lenght of keyword name.
* @param[in] prefix Start of keyword prefix.
* @param[in] prefix_len Lenght of prefix.
- * @param[in] parrent Identification of parrent element, use LY_STMT_NONE for elements without parrent.
- *
+ * @param[in] parent Identification of parent element, use LY_STMT_NONE for elements without parent.
* @return yang_keyword values.
*/
enum ly_stmt
-yin_match_keyword(struct lysp_yin_ctx *ctx, const char *name, size_t name_len,
- const char *prefix, size_t prefix_len, enum ly_stmt parent)
+yin_match_keyword(struct lysp_yin_ctx *ctx, const char *name, size_t name_len, const char *prefix, size_t prefix_len,
+ enum ly_stmt parent)
{
const char *start = NULL;
enum ly_stmt kw = LY_STMT_NONE;
@@ -221,7 +222,6 @@
*
* @param[in] name String representing name.
* @param[in] len Lenght of the name.
- *
* @return yin_argument values.
*/
enum yin_argument
@@ -337,8 +337,7 @@
* @param[in] count Number of subelements.
* @param[in] parent Parent node if any.
* @param[out] result Allocated subelems array.
- *
- * @return LY_SUCCESS on success LY_EMEM on memmory allocation failure.
+ * @return LY_ERR values.
*/
static LY_ERR
subelems_allocator(struct lysp_yin_ctx *ctx, size_t count, struct lysp_node *parent,
@@ -408,7 +407,6 @@
*
* @param[in] ctx Yin parser context for logging.
* @param[in] val_type Type of the input string to select method of checking character validity.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -462,7 +460,6 @@
* @param[out] arg_val Where value of argument should be stored. Can be NULL iff arg_type is specified as YIN_ARG_NONE.
* @param[in] val_type Type of expected value of attribute.
* @param[in] current_element Identification of current element, used for logging.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -482,7 +479,7 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
} else if (arg == arg_type) {
LY_CHECK_ERR_RET(found, LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_DUP_ATTR,
- yin_attr2str(arg), ly_stmt2str(current_element)), LY_EVALID);
+ yin_attr2str(arg), lyplg_ext_stmt2str(current_element)), LY_EVALID);
found = true;
/* go to value */
@@ -492,7 +489,7 @@
LY_CHECK_RET(!(*arg_val), LY_EMEM);
} else {
LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_UNEXP_ATTR, ctx->xmlctx->name_len,
- ctx->xmlctx->name, ly_stmt2str(current_element));
+ ctx->xmlctx->name, lyplg_ext_stmt2str(current_element));
return LY_EVALID;
}
} else {
@@ -507,7 +504,7 @@
/* anything else than Y_MAYBE_STR_ARG is mandatory */
if ((val_type != Y_MAYBE_STR_ARG) && !found) {
LOGVAL_PARSER((struct lysp_ctx *)ctx, LYVE_SYNTAX_YIN, "Missing mandatory attribute %s of %s element.",
- yin_attr2str(arg_type), ly_stmt2str(current_element));
+ yin_attr2str(arg_type), lyplg_ext_stmt2str(current_element));
return LY_EVALID;
}
@@ -520,7 +517,6 @@
* @param[in] type Type of wanted record.
* @param[in] array_size Size of array.
* @param[in] array Searched array.
- *
* @return Pointer to desired record on success, NULL if element is not in the array.
*/
static struct yin_subelement *
@@ -541,7 +537,6 @@
* @param[in] subelem_info Array of information about subelements.
* @param[in] subelem_info_size Size of subelem_info array.
* @param[in] current_element Identification of element that is currently being parsed, used for logging.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -552,7 +547,7 @@
/* if there is element that is mandatory and isn't parsed log error and return LY_EVALID */
if ((subelem_info[i].flags & YIN_SUBELEM_MANDATORY) && !(subelem_info[i].flags & YIN_SUBELEM_PARSED)) {
LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_MAND_SUBELEM,
- ly_stmt2str(subelem_info[i].type), ly_stmt2str(current_element));
+ lyplg_ext_stmt2str(subelem_info[i].type), lyplg_ext_stmt2str(current_element));
return LY_EVALID;
}
}
@@ -568,7 +563,6 @@
* @param[in] subelem_info_size Size of subelem_info array.
* @param[in] current_element Identification of element that is currently being parsed, used for logging.
* @param[in] exp_first Record in subelem_info array that is expected to be defined as first subelement, used for logging.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -579,7 +573,7 @@
for (signed char i = 0; i < subelem_info_size; ++i) {
if (subelem_info[i].flags & YIN_SUBELEM_PARSED) {
LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_FIRT_SUBELEM,
- ly_stmt2str(exp_first->type), ly_stmt2str(current_element));
+ lyplg_ext_stmt2str(exp_first->type), lyplg_ext_stmt2str(current_element));
return LY_EVALID;
}
}
@@ -592,7 +586,8 @@
* for example prefix or namespace element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] kw Type of current element.
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of @p parent statement.
* @param[out] value Where value of attribute should be stored.
* @param[in] arg_type Expected type of attribute.
* @param[in] arg_val_type Type of expected value of attribute.
@@ -600,33 +595,34 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_simple_element(struct lysp_yin_ctx *ctx, enum ly_stmt kw, const char **value,
+yin_parse_simple_element(struct lysp_yin_ctx *ctx, const void *parent, enum ly_stmt parent_stmt, const char **value,
enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
{
- LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, value, arg_val_type, kw));
struct yin_subelement subelems[] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), kw, NULL, exts);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, value, arg_val_type, parent_stmt));
+
+ return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, parent_stmt, NULL, exts);
}
/**
* @brief Parse path element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] kw Type of current element.
* @param[out] type Type structure to store parsed value, flags and extension instances.
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_path(struct lysp_yin_ctx *ctx, enum ly_stmt kw, struct lysp_type *type)
+yin_parse_path(struct lysp_yin_ctx *ctx, struct lysp_type *type)
{
LY_ERR ret;
const char *str_path;
- LY_CHECK_RET(yin_parse_simple_element(ctx, kw, &str_path, YIN_ARG_VALUE, Y_STR_ARG, &type->exts));
+ LY_CHECK_RET(yin_parse_simple_element(ctx, type, LY_STMT_PATH, &str_path, YIN_ARG_VALUE, Y_STR_ARG, &type->exts));
+
ret = ly_path_parse(ctx->xmlctx->ctx, NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
lydict_remove(ctx->xmlctx->ctx, str_path);
@@ -674,7 +670,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_PATTERN, NULL, &restr->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), restr, LY_STMT_PATTERN, NULL, &restr->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, restr->exts, 1, NULL));
@@ -724,7 +720,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_FRACTION_DIGITS, NULL, &type->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), type, LY_STMT_FRACTION_DIGITS, NULL, &type->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, type->exts, 1, NULL));
@@ -761,7 +757,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ENUM, NULL, &en->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), en, LY_STMT_ENUM, NULL, &en->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, en->exts, 1, NULL));
@@ -796,7 +792,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_BIT, NULL, &en->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), en, LY_STMT_BIT, NULL, &en->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, en->exts, 1, NULL));
@@ -809,7 +805,7 @@
* more instances, such as base or if-feature.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] kw Type of current element.
+ * @param[in] parent_stmt Type of parent statement.
* @param[out] values Parsed values to add to.
* @param[in] arg_type Expected type of attribute.
* @param[in] arg_val_type Type of expected value of attribute.
@@ -817,21 +813,21 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_simple_elements(struct lysp_yin_ctx *ctx, enum ly_stmt kw, const char ***values, enum yin_argument arg_type,
- enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
+yin_parse_simple_elements(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, const char ***values,
+ enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
{
const char **value;
-
- LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *values, value, LY_EMEM);
- LY_ARRAY_COUNT_TYPE index = LY_ARRAY_COUNT(*values) - 1;
+ LY_ARRAY_COUNT_TYPE index = LY_ARRAY_COUNT(*values);
struct yin_subelement subelems[] = {
{LY_STMT_EXTENSION_INSTANCE, &index, 0}
};
- LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, value, arg_val_type, kw));
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *values, value, LY_EMEM);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), kw, NULL, exts));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, value, arg_val_type, parent_stmt));
+
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), *values, parent_stmt, NULL, exts));
return LY_SUCCESS;
}
@@ -840,7 +836,8 @@
* @brief Parse simple element without any special constraints and argument mapped to yin attribute.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] kw Type of current element.
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of @p parent statement.
* @param[in] subinfo Information about subelement, is used to determin which function should be called and where to store parsed value.
* @param[in] arg_type Expected type of attribute.
* @param[in] arg_val_type Type of expected value of attribute.
@@ -848,15 +845,15 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_simple_elem(struct lysp_yin_ctx *ctx, enum ly_stmt kw, struct yin_subelement *subinfo,
+yin_parse_simple_elem(struct lysp_yin_ctx *ctx, const void *parent, enum ly_stmt parent_stmt, struct yin_subelement *subinfo,
enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
{
if (subinfo->flags & YIN_SUBELEM_UNIQUE) {
- LY_CHECK_RET(yin_parse_simple_element(ctx, kw, (const char **)subinfo->dest,
- arg_type, arg_val_type, exts));
+ LY_CHECK_RET(yin_parse_simple_element(ctx, parent, parent_stmt, (const char **)subinfo->dest, arg_type,
+ arg_val_type, exts));
} else {
- LY_CHECK_RET(yin_parse_simple_elements(ctx, kw, (const char ***)subinfo->dest,
- arg_type, arg_val_type, exts));
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, parent_stmt, (const char ***)subinfo->dest, arg_type,
+ arg_val_type, exts));
}
return LY_SUCCESS;
@@ -866,24 +863,22 @@
* @brief Parse base element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] parent Identification of parent element.
+ * @param[in] parent_stmt Type of parent statement.
* @param[out] dest Where parsed values should be stored.
* @param[in,out] exts Extension instances to add to.
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_base(struct lysp_yin_ctx *ctx, enum ly_stmt parent, void *dest, struct lysp_ext_instance **exts)
+yin_parse_base(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, void *dest, struct lysp_ext_instance **exts)
{
- struct lysp_type *type = NULL;
+ struct lysp_type *type;
- if (parent == LY_STMT_TYPE) {
+ if (parent_stmt == LY_STMT_TYPE) {
type = (struct lysp_type *)dest;
- LY_CHECK_RET(yin_parse_simple_elements(ctx, LY_STMT_BASE, &type->bases, YIN_ARG_NAME,
- Y_PREF_IDENTIF_ARG, exts));
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, LY_STMT_BASE, &type->bases, YIN_ARG_NAME, Y_PREF_IDENTIF_ARG, exts));
type->flags |= LYS_SET_BASE;
- } else if (parent == LY_STMT_IDENTITY) {
- LY_CHECK_RET(yin_parse_simple_elements(ctx, LY_STMT_BASE, (const char ***)dest,
- YIN_ARG_NAME, Y_PREF_IDENTIF_ARG, exts));
+ } else if (parent_stmt == LY_STMT_IDENTITY) {
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, LY_STMT_BASE, (const char ***)dest, YIN_ARG_NAME, Y_PREF_IDENTIF_ARG, exts));
} else {
LOGINT(ctx->xmlctx->ctx);
return LY_EINT;
@@ -920,7 +915,7 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REQUIRE_INSTANCE, NULL, &type->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), type, LY_STMT_REQUIRE_INSTANCE, NULL, &type->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, type->exts, 1, NULL));
@@ -932,21 +927,22 @@
* @brief Parse modifier element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
+ * @param[in] parent Current statement parent.
* @param[in,out] pat Value to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_modifier(struct lysp_yin_ctx *ctx, const char **pat, struct lysp_ext_instance **exts)
+yin_parse_modifier(struct lysp_yin_ctx *ctx, const void *parent, const char **pat, struct lysp_ext_instance **exts)
{
- assert(**pat == 0x06);
const char *temp_val;
char *modified_val;
struct yin_subelement subelems[] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
+ assert(**pat == 0x06);
+
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MODIFIER));
if (strcmp(temp_val, "invert-match") != 0) {
@@ -967,7 +963,7 @@
modified_val[0] = LYSP_RESTR_PATTERN_NACK;
LY_CHECK_RET(lydict_insert_zc(ctx->xmlctx->ctx, modified_val, pat));
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MODIFIER, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, LY_STMT_MODIFIER, NULL, exts));
return LY_SUCCESS;
}
@@ -978,11 +974,11 @@
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] restr_kw Identificaton of element that is being parsed, can be set to LY_STMT_MUST, LY_STMT_LENGTH or LY_STMT_RANGE.
* @param[in] restr Value to write to.
+ * @return LY_ERR values.
*/
static LY_ERR
yin_parse_restriction(struct lysp_yin_ctx *ctx, enum ly_stmt restr_kw, struct lysp_restr *restr)
{
- assert(restr_kw == LY_STMT_MUST || restr_kw == LY_STMT_LENGTH || restr_kw == LY_STMT_RANGE);
struct yin_subelement subelems[] = {
{LY_STMT_DESCRIPTION, &restr->dsc, YIN_SUBELEM_UNIQUE},
{LY_STMT_ERROR_APP_TAG, &restr->eapptag, YIN_SUBELEM_UNIQUE},
@@ -993,11 +989,13 @@
/* argument of must is called condition, but argument of length and range is called value */
enum yin_argument arg_type = (restr_kw == LY_STMT_MUST) ? YIN_ARG_CONDITION : YIN_ARG_VALUE;
+ assert(restr_kw == LY_STMT_MUST || restr_kw == LY_STMT_LENGTH || restr_kw == LY_STMT_RANGE);
+
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, &restr->arg.str, Y_STR_ARG, restr_kw));
restr->arg.mod = PARSER_CUR_PMOD(ctx);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), restr_kw, NULL, &restr->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), restr, restr_kw, NULL, &restr->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, restr->exts, 1, NULL));
@@ -1007,10 +1005,8 @@
/**
* @brief Parse range element.
- *
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[out] type Type structure to store parsed value and flags.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1029,7 +1025,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[out] type Type structure to store parsed value and flags.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1048,7 +1043,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] restrs Restrictions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1064,19 +1058,18 @@
* @brief Parse a node id into an array.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] kw Type of current element.
+ * @param[in] parent_stmt Type of parent statement.
* @param[in] subinfo Information about subelement, is used to determin which function should be called and where to store parsed value.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_qname(struct lysp_yin_ctx *ctx, enum ly_stmt kw, struct yin_subelement *subinfo,
+yin_parse_qname(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, struct yin_subelement *subinfo,
struct lysp_ext_instance **exts)
{
struct lysp_qname *qname, **qnames;
- switch (kw) {
+ switch (parent_stmt) {
case LY_STMT_DEFAULT:
if (subinfo->flags & YIN_SUBELEM_UNIQUE) {
qname = (struct lysp_qname *)subinfo->dest;
@@ -1085,19 +1078,21 @@
LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *qnames, qname, LY_EMEM);
}
qname->mod = PARSER_CUR_PMOD(ctx);
- return yin_parse_simple_element(ctx, kw, &qname->str, YIN_ARG_VALUE, Y_STR_ARG, exts);
+ return yin_parse_simple_element(ctx, qname, parent_stmt, &qname->str, YIN_ARG_VALUE, Y_STR_ARG, exts);
case LY_STMT_UNIQUE:
assert(!(subinfo->flags & YIN_SUBELEM_UNIQUE));
+
qnames = (struct lysp_qname **)subinfo->dest;
LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *qnames, qname, LY_EMEM);
qname->mod = PARSER_CUR_PMOD(ctx);
- return yin_parse_simple_element(ctx, kw, &qname->str, YIN_ARG_TAG, Y_STR_ARG, exts);
+ return yin_parse_simple_element(ctx, *qnames, parent_stmt, &qname->str, YIN_ARG_TAG, Y_STR_ARG, exts);
case LY_STMT_IF_FEATURE:
assert(!(subinfo->flags & YIN_SUBELEM_UNIQUE));
+
qnames = (struct lysp_qname **)subinfo->dest;
LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *qnames, qname, LY_EMEM);
qname->mod = PARSER_CUR_PMOD(ctx);
- return yin_parse_simple_element(ctx, kw, &qname->str, YIN_ARG_NAME, Y_STR_ARG, exts);
+ return yin_parse_simple_element(ctx, *qnames, parent_stmt, &qname->str, YIN_ARG_NAME, Y_STR_ARG, exts);
default:
break;
}
@@ -1110,13 +1105,12 @@
* @brief Parse position or value element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] kw Type of current element, can be set to LY_STMT_POSITION or LY_STMT_VALUE.
+ * @param[in] parent_stmt Type of parent statement.
* @param[out] enm Enum structure to save value, flags and extension instances.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_value_pos(struct lysp_yin_ctx *ctx, enum ly_stmt kw, struct lysp_type_enum *enm)
+yin_parse_value_pos(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, struct lysp_type_enum *enm)
{
LY_ERR ret = LY_SUCCESS;
const char *temp_val = NULL;
@@ -1124,51 +1118,51 @@
long long int num = 0;
unsigned long long int unum = 0;
- assert(kw == LY_STMT_POSITION || kw == LY_STMT_VALUE);
+ assert(parent_stmt == LY_STMT_POSITION || parent_stmt == LY_STMT_VALUE);
/* set value flag */
enm->flags |= LYS_SET_VALUE;
/* get attribute value */
LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
- LY_CHECK_GOTO(ret = yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, kw), cleanup);
+ LY_CHECK_GOTO(ret = yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, parent_stmt), cleanup);
if (!temp_val || (temp_val[0] == '\0') || (temp_val[0] == '+') ||
- ((temp_val[0] == '0') && (temp_val[1] != '\0')) || ((kw == LY_STMT_POSITION) && !strcmp(temp_val, "-0"))) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
+ ((temp_val[0] == '0') && (temp_val[1] != '\0')) || ((parent_stmt == LY_STMT_POSITION) && !strcmp(temp_val, "-0"))) {
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", lyplg_ext_stmt2str(parent_stmt));
ret = LY_EVALID;
goto cleanup;
}
/* convert value */
errno = 0;
- if (kw == LY_STMT_VALUE) {
+ if (parent_stmt == LY_STMT_VALUE) {
num = strtoll(temp_val, &ptr, LY_BASE_DEC);
if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", lyplg_ext_stmt2str(parent_stmt));
ret = LY_EVALID;
goto cleanup;
}
} else {
unum = strtoull(temp_val, &ptr, LY_BASE_DEC);
if (unum > UINT64_C(4294967295)) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", lyplg_ext_stmt2str(parent_stmt));
ret = LY_EVALID;
goto cleanup;
}
}
/* check if whole argument value was converted */
if (*ptr != '\0') {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", lyplg_ext_stmt2str(parent_stmt));
ret = LY_EVALID;
goto cleanup;
}
if (errno == ERANGE) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_OOB_YIN, temp_val, "value", ly_stmt2str(kw));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_OOB_YIN, temp_val, "value", lyplg_ext_stmt2str(parent_stmt));
ret = LY_EVALID;
goto cleanup;
}
/* save correctly ternary operator can't be used because num and unum have different signes */
- if (kw == LY_STMT_VALUE) {
+ if (parent_stmt == LY_STMT_VALUE) {
enm->value = num;
} else {
enm->value = unum;
@@ -1179,7 +1173,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_GOTO(ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), kw, NULL, &enm->exts), cleanup);
+ LY_CHECK_GOTO(ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), enm, parent_stmt, NULL, &enm->exts), cleanup);
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_GOTO(ret = ly_set_add(&ctx->ext_inst, enm->exts, 1, NULL), cleanup);
@@ -1195,7 +1189,6 @@
* @param[in] ctx YIN parser context for logging and to store current state.
* @param[out] submod Structure of submodule that is being parsed.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values
*/
static LY_ERR
@@ -1217,7 +1210,7 @@
}
lydict_remove(ctx->xmlctx->ctx, belongsto);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_BELONGS_TO, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), submod, LY_STMT_BELONGS_TO, NULL, exts));
return LY_SUCCESS;
}
@@ -1227,28 +1220,30 @@
* text element as child.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] elem_type Type of element can be set to LY_STMT_ORGANIZATION or LY_STMT_CONTACT or LY_STMT_DESCRIPTION or LY_STMT_REFERENCE.
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of @p parent statement.
* @param[out] value Where the content of meta element should be stored.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_meta(struct lysp_yin_ctx *ctx, enum ly_stmt elem_type, const char **value, struct lysp_ext_instance **exts)
+yin_parse_meta(struct lysp_yin_ctx *ctx, const void *parent, enum ly_stmt parent_stmt, const char **value,
+ struct lysp_ext_instance **exts)
{
- assert(elem_type == LY_STMT_ORGANIZATION || elem_type == LY_STMT_CONTACT || elem_type == LY_STMT_DESCRIPTION || elem_type == LY_STMT_REFERENCE);
-
struct yin_subelement subelems[] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
{LY_STMT_ARG_TEXT, value, YIN_SUBELEM_MANDATORY | YIN_SUBELEM_UNIQUE | YIN_SUBELEM_FIRST}
};
+ assert(parent_stmt == LY_STMT_ORGANIZATION || parent_stmt == LY_STMT_CONTACT || parent_stmt == LY_STMT_DESCRIPTION ||
+ parent_stmt == LY_STMT_REFERENCE);
+
/* check attributes */
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, parent_stmt));
/* parse content */
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), elem_type, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, parent_stmt, NULL, exts));
return LY_SUCCESS;
}
@@ -1257,13 +1252,13 @@
* @brief Parse error-message element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
+ * @param[in] parent Current statement parent.
* @param[out] value Where the content of error-message element should be stored.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_err_msg(struct lysp_yin_ctx *ctx, const char **value, struct lysp_ext_instance **exts)
+yin_parse_err_msg(struct lysp_yin_ctx *ctx, const void *parent, const char **value, struct lysp_ext_instance **exts)
{
struct yin_subelement subelems[] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
@@ -1274,7 +1269,7 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, LY_STMT_ERROR_MESSAGE));
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ERROR_MESSAGE, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, LY_STMT_ERROR_MESSAGE, NULL, exts));
return LY_SUCCESS;
}
@@ -1283,17 +1278,17 @@
* @brief Parse type element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] parent Identification of parent element.
- * @param[in,out] type Type to write to.
- *
+ * @param[in] parent_stmt Type of parent statement.
+ * @param[in,out] subinfo Information about subelement, is used to determin which function should be called and where
+ * to store parsed value.
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_type(struct lysp_yin_ctx *ctx, enum ly_stmt parent, struct yin_subelement *subinfo)
+yin_parse_type(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, struct yin_subelement *subinfo)
{
struct lysp_type *type = NULL;
- if (parent == LY_STMT_DEVIATE) {
+ if (parent_stmt == LY_STMT_DEVIATE) {
*(struct lysp_type **)subinfo->dest = calloc(1, sizeof **(struct lysp_type **)subinfo->dest);
LY_CHECK_ERR_RET(!(*(struct lysp_type **)subinfo->dest), LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
type = *((struct lysp_type **)subinfo->dest);
@@ -1302,7 +1297,7 @@
}
/* type as child of another type */
- if (parent == LY_STMT_TYPE) {
+ if (parent_stmt == LY_STMT_TYPE) {
struct lysp_type *nested_type = NULL;
LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, type->types, nested_type, LY_EMEM);
@@ -1328,7 +1323,7 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &type->name, Y_PREF_IDENTIF_ARG, LY_STMT_TYPE));
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_TYPE, NULL, &type->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), type, LY_STMT_TYPE, NULL, &type->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, type->exts, 1, NULL));
@@ -1343,7 +1338,6 @@
* @param[in,out] max Value to write to.
* @param[in] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1382,7 +1376,8 @@
*max = num;
}
- LY_CHECK_GOTO(ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MAX_ELEMENTS, NULL, exts), cleanup);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), max, LY_STMT_MAX_ELEMENTS, NULL, exts);
+ LY_CHECK_GOTO(ret, cleanup);
cleanup:
lydict_remove(ctx->xmlctx->ctx, temp_val);
@@ -1396,7 +1391,6 @@
* @param[in,out] min Value to write to.
* @param[in] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1433,7 +1427,7 @@
}
*min = num;
lydict_remove(ctx->xmlctx->ctx, temp_val);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MIN_ELEMENTS, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), min, LY_STMT_MIN_ELEMENTS, NULL, exts));
return LY_SUCCESS;
}
@@ -1442,31 +1436,32 @@
* @brief Parse min-elements or max-elements element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] parent Identification of parent element.
- * @param[in] current Identification of current element.
+ * @param[in] parent_stmt Type of parent statement.
+ * @param[in] cur_stmt Type of current element.
* @param[in] dest Where the parsed value and flags should be stored.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_minmax(struct lysp_yin_ctx *ctx, enum ly_stmt parent, enum ly_stmt current, void *dest)
+yin_parse_minmax(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, enum ly_stmt cur_stmt, void *dest)
{
- assert(current == LY_STMT_MAX_ELEMENTS || current == LY_STMT_MIN_ELEMENTS);
- assert(parent == LY_STMT_LEAF_LIST || parent == LY_STMT_REFINE || parent == LY_STMT_LIST || parent == LY_STMT_DEVIATE);
uint32_t *lim;
uint16_t *flags;
struct lysp_ext_instance **exts;
- if (parent == LY_STMT_LEAF_LIST) {
- lim = (current == LY_STMT_MAX_ELEMENTS) ? &((struct lysp_node_leaflist *)dest)->max : &((struct lysp_node_leaflist *)dest)->min;
+ assert(cur_stmt == LY_STMT_MAX_ELEMENTS || cur_stmt == LY_STMT_MIN_ELEMENTS);
+ assert(parent_stmt == LY_STMT_LEAF_LIST || parent_stmt == LY_STMT_REFINE || parent_stmt == LY_STMT_LIST ||
+ parent_stmt == LY_STMT_DEVIATE);
+
+ if (parent_stmt == LY_STMT_LEAF_LIST) {
+ lim = (cur_stmt == LY_STMT_MAX_ELEMENTS) ? &((struct lysp_node_leaflist *)dest)->max : &((struct lysp_node_leaflist *)dest)->min;
flags = &((struct lysp_node_leaflist *)dest)->flags;
exts = &((struct lysp_node_leaflist *)dest)->exts;
- } else if (parent == LY_STMT_REFINE) {
- lim = (current == LY_STMT_MAX_ELEMENTS) ? &((struct lysp_refine *)dest)->max : &((struct lysp_refine *)dest)->min;
+ } else if (parent_stmt == LY_STMT_REFINE) {
+ lim = (cur_stmt == LY_STMT_MAX_ELEMENTS) ? &((struct lysp_refine *)dest)->max : &((struct lysp_refine *)dest)->min;
flags = &((struct lysp_refine *)dest)->flags;
exts = &((struct lysp_refine *)dest)->exts;
- } else if (parent == LY_STMT_LIST) {
- lim = (current == LY_STMT_MAX_ELEMENTS) ? &((struct lysp_node_list *)dest)->max : &((struct lysp_node_list *)dest)->min;
+ } else if (parent_stmt == LY_STMT_LIST) {
+ lim = (cur_stmt == LY_STMT_MAX_ELEMENTS) ? &((struct lysp_node_list *)dest)->max : &((struct lysp_node_list *)dest)->min;
flags = &((struct lysp_node_list *)dest)->flags;
exts = &((struct lysp_node_list *)dest)->exts;
} else {
@@ -1475,7 +1470,7 @@
exts = ((struct minmax_dev_meta *)dest)->exts;
}
- if (current == LY_STMT_MAX_ELEMENTS) {
+ if (cur_stmt == LY_STMT_MAX_ELEMENTS) {
LY_CHECK_RET(yin_parse_maxelements(ctx, lim, flags, exts));
} else {
LY_CHECK_RET(yin_parse_minelements(ctx, lim, flags, exts));
@@ -1488,13 +1483,13 @@
* @brief Parse ordered-by element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
+ * @param[in] parent Current statement parent.
* @param[out] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_orderedby(struct lysp_yin_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
+yin_parse_orderedby(struct lysp_yin_ctx *ctx, const void *parent, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val;
struct yin_subelement subelems[] = {
@@ -1515,7 +1510,7 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ORDERED_BY, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, LY_STMT_ORDERED_BY, NULL, exts));
return LY_SUCCESS;
}
@@ -1524,9 +1519,8 @@
* @brief Parse any-data or any-xml element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] any_kw Identification of current element, can be set to LY_STMT_ANYDATA or LY_STMT_ANYXML
+ * @param[in] any_stmt Type of current statement, can be set to LY_STMT_ANYDATA or LY_STMT_ANYXML
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1555,7 +1549,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), any_kw, NULL, &any->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), any, any_kw, NULL, &any->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, any->exts, 1, NULL));
@@ -1568,7 +1562,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1601,7 +1594,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_LEAF, NULL, &leaf->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), leaf, LY_STMT_LEAF, NULL, &leaf->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, leaf->exts, 1, NULL));
@@ -1614,7 +1607,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1649,7 +1641,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_LEAF_LIST, NULL, &llist->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), llist, LY_STMT_LEAF_LIST, NULL, &llist->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, llist->exts, 1, NULL));
@@ -1672,7 +1664,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] typedef_meta Meta information about parent node and typedefs to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1698,7 +1689,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_TYPEDEF, NULL, &tpdf->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), tpdf, LY_STMT_TYPEDEF, NULL, &tpdf->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, tpdf->exts, 1, NULL));
@@ -1717,7 +1708,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] refines Refines to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1748,7 +1738,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REFINE, NULL, &rf->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), rf, LY_STMT_REFINE, NULL, &rf->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, rf->exts, 1, NULL));
@@ -1761,7 +1751,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1791,7 +1780,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_USES, NULL, &uses->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), uses, LY_STMT_USES, NULL, &uses->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, uses->exts, 1, NULL));
@@ -1804,7 +1793,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] revs Parsed revisions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1834,7 +1822,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REVISION, NULL, &rev->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), rev, LY_STMT_REVISION, NULL, &rev->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, rev->exts, 1, NULL));
@@ -1847,7 +1835,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] inc_meta Meta informatinou about module/submodule name and includes to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1877,7 +1864,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_INCLUDE, NULL, &inc->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), inc, LY_STMT_INCLUDE, NULL, &inc->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, inc->exts, 1, NULL));
@@ -1891,7 +1878,6 @@
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] rev Array to store the parsed value in.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1910,7 +1896,7 @@
strcpy(rev, temp_rev);
lydict_remove(ctx->xmlctx->ctx, temp_rev);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REVISION_DATE, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), rev, LY_STMT_REVISION_DATE, NULL, exts));
return LY_SUCCESS;
}
@@ -1921,7 +1907,6 @@
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -1946,7 +1931,7 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_CONFIG, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), flags, LY_STMT_CONFIG, NULL, exts));
return LY_SUCCESS;
}
@@ -1955,13 +1940,13 @@
* @brief Parse yang-version element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
+ * @param[in] parent Current statement parent.
* @param[out] version Storage for the parsed information.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_yangversion(struct lysp_yin_ctx *ctx, uint8_t *version, struct lysp_ext_instance **exts)
+yin_parse_yangversion(struct lysp_yin_ctx *ctx, const void *parent, uint8_t *version, struct lysp_ext_instance **exts)
{
const char *temp_version = NULL;
struct yin_subelement subelems[] = {
@@ -1982,7 +1967,7 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_version);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_YANG_VERSION, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, LY_STMT_YANG_VERSION, NULL, exts));
return LY_SUCCESS;
}
@@ -1992,7 +1977,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] imp_meta Meta information about prefix and imports to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2014,7 +1998,7 @@
/* parse import attributes */
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, &imp->name, Y_IDENTIF_ARG, LY_STMT_IMPORT));
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_IMPORT, NULL, &imp->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), imp, LY_STMT_IMPORT, NULL, &imp->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, imp->exts, 1, NULL));
@@ -2031,7 +2015,6 @@
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2056,7 +2039,7 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MANDATORY, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), flags, LY_STMT_MANDATORY, NULL, exts));
return LY_SUCCESS;
}
@@ -2067,7 +2050,6 @@
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2094,7 +2076,7 @@
}
lydict_remove(ctx->xmlctx->ctx, value);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_STATUS, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), flags, LY_STMT_STATUS, NULL, exts));
return LY_SUCCESS;
}
@@ -2104,6 +2086,7 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[out] when_p When pointer to parse to.
+ * @return LY_ERR values.
*/
static LY_ERR
yin_parse_when(struct lysp_yin_ctx *ctx, struct lysp_when **when_p)
@@ -2127,7 +2110,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_WHEN, NULL, &when->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), when, LY_STMT_WHEN, NULL, &when->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, when->exts, 1, NULL));
@@ -2139,14 +2122,13 @@
* @brief Parse yin-elemenet element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in,out] data Data to read from, always moved to currently handled position.
+ * @param[in] parent Current statement parent.
* @param[in,out] flags Flags to add to.
- * @prama[in,out] exts Extension instances to add to.
- *
+ * @param[in,out] exts Extension instances to add to.
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_yin_element(struct lysp_yin_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
+yin_parse_yin_element(struct lysp_yin_ctx *ctx, const void *parent, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val = NULL;
struct yin_subelement subelems[] = {
@@ -2167,7 +2149,7 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_YIN_ELEMENT, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, LY_STMT_YIN_ELEMENT, NULL, exts));
return LY_SUCCESS;
}
@@ -2175,14 +2157,14 @@
/**
* @brief Parse argument element.
*
- * @param[in,out] xmlctx Xml context.
- * @param[in,out] arg_meta Meta information about destionation of parsed data.
+ * @param[in,out] ctx YIN parser context for logging and to store current state.
+ * @param[in] parent Current statement parent.
+ * @param[in,out] arg_meta Meta information about destination of parsed data.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_argument(struct lysp_yin_ctx *ctx, struct yin_argument_meta *arg_meta, struct lysp_ext_instance **exts)
+yin_parse_argument(struct lysp_yin_ctx *ctx, const void *parent, struct yin_argument_meta *arg_meta, struct lysp_ext_instance **exts)
{
struct yin_subelement subelems[] = {
{LY_STMT_YIN_ELEMENT, arg_meta->flags, YIN_SUBELEM_UNIQUE},
@@ -2192,7 +2174,7 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg_meta->argument, Y_IDENTIF_ARG, LY_STMT_ARGUMENT));
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ARGUMENT, NULL, exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), parent, LY_STMT_ARGUMENT, NULL, exts));
return LY_SUCCESS;
}
@@ -2202,7 +2184,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] extensions Extensions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2223,7 +2204,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_EXTENSION, NULL, &ex->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), ex, LY_STMT_EXTENSION, NULL, &ex->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, ex->exts, 1, NULL));
@@ -2236,7 +2217,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] features Features to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2260,7 +2240,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_FEATURE, NULL, &feat->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), feat, LY_STMT_FEATURE, NULL, &feat->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, feat->exts, 1, NULL));
@@ -2273,7 +2253,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] identities Identities to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2298,7 +2277,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_IDENTITY, NULL, &ident->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), ident, LY_STMT_IDENTITY, NULL, &ident->exts));
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, ident->exts, 1, NULL));
@@ -2311,7 +2290,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2357,7 +2335,7 @@
LY_STMT_USES, &list->child, 0,
LY_STMT_WHEN, &list->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_LIST, NULL, &list->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, list, LY_STMT_LIST, NULL, &list->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2377,7 +2355,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] notif_meta Meta information about parent node and notifications to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2417,7 +2394,7 @@
LY_STMT_USES, ¬if->child, 0,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_NOTIFICATION, NULL, ¬if->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, notif, LY_STMT_NOTIFICATION, NULL, ¬if->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2432,7 +2409,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in,out] gr_meta Meta information about parent node and groupings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2471,7 +2447,7 @@
LY_STMT_TYPEDEF, &grp->typedefs, 0,
LY_STMT_USES, &grp->child, 0,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_GROUPING, NULL, &grp->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, grp, LY_STMT_GROUPING, NULL, &grp->exts);
subelems_deallocator(subelems_size, subelems);
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
@@ -2491,7 +2467,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2534,7 +2509,7 @@
LY_STMT_USES, &cont->child, 0,
LY_STMT_WHEN, &cont->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_CONTAINER, NULL, &cont->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, cont, LY_STMT_CONTAINER, NULL, &cont->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2549,7 +2524,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2585,7 +2559,7 @@
LY_STMT_USES, &cas->child, 0,
LY_STMT_WHEN, &cas->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_CASE, NULL, &cas->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, cas, LY_STMT_CASE, NULL, &cas->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2600,7 +2574,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] node_meta Meta information about parent node and siblings to add to.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -2640,7 +2613,7 @@
LY_STMT_STATUS, &choice->flags, YIN_SUBELEM_UNIQUE,
LY_STMT_WHEN, &choice->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_CHOICE, NULL, &choice->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, choice, LY_STMT_CHOICE, NULL, &choice->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2656,7 +2629,6 @@
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] inout_kw Identification of input/output element.
* @param[in] inout_meta Meta information about parent node and siblings and input/output pointer to write to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2689,7 +2661,7 @@
LY_STMT_TYPEDEF, &inout_meta->inout_p->typedefs, 0,
LY_STMT_USES, &inout_meta->inout_p->child, 0,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, inout_kw, NULL, &inout_meta->inout_p->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, inout_meta->inout_p, inout_kw, NULL, &inout_meta->inout_p->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2697,7 +2669,7 @@
LY_CHECK_RET(ly_set_add(&ctx->ext_inst, inout_meta->inout_p->exts, 1, NULL));
if (!inout_meta->inout_p->child) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(inout_kw));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_MISSTMT, "data-def-stmt", lyplg_ext_stmt2str(inout_kw));
return LY_EVALID;
}
@@ -2709,7 +2681,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] act_meta Meta information about parent node and actions to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2741,7 +2712,7 @@
LY_STMT_STATUS, &act->flags, YIN_SUBELEM_UNIQUE,
LY_STMT_TYPEDEF, &act->typedefs, 0,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = (yin_parse_content(ctx, subelems, subelems_size, kw, NULL, &act->exts));
+ ret = (yin_parse_content(ctx, subelems, subelems_size, act, kw, NULL, &act->exts));
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2765,7 +2736,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] aug_meta Meta information about parent node and augments to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2806,7 +2776,7 @@
LY_STMT_USES, &aug->child, 0,
LY_STMT_WHEN, &aug->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_AUGMENT, NULL, &aug->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, aug, LY_STMT_AUGMENT, NULL, &aug->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -2821,7 +2791,6 @@
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
* @param[in] deviates Deviates to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -2862,7 +2831,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d->exts);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), d, LY_STMT_DEVIATE, NULL, &d->exts);
} else if (dev_mod == LYS_DEV_ADD) {
d_add = calloc(1, sizeof *d_add);
@@ -2882,7 +2851,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d->exts);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), d, LY_STMT_DEVIATE, NULL, &d->exts);
} else if (dev_mod == LYS_DEV_REPLACE) {
d_rpl = calloc(1, sizeof *d_rpl);
@@ -2901,7 +2870,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d->exts);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), d, LY_STMT_DEVIATE, NULL, &d->exts);
} else {
d_del = calloc(1, sizeof *d_del);
@@ -2915,7 +2884,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d->exts);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), d, LY_STMT_DEVIATE, NULL, &d->exts);
}
LY_CHECK_GOTO(ret, cleanup);
@@ -2961,7 +2930,8 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_GOTO(ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATION, NULL, &dev->exts), cleanup);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), dev, LY_STMT_DEVIATION, NULL, &dev->exts);
+ LY_CHECK_GOTO(ret, cleanup);
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
LY_CHECK_GOTO(ret = ly_set_add(&ctx->ext_inst, dev->exts, 1, NULL), cleanup);
@@ -3043,28 +3013,30 @@
* @brief Check if relative order of two keywords is valid.
*
* @param[in] ctx YIN parser context used for logging.
- * @param[in] kw Current keyword.
- * @param[in] next_kw Next keyword.
- * @param[in] parrent Identification of parrent element, can be se to to LY_STMT_MODULE of LY_STMT_SUBMODULE,
+ * @param[in] cur_stmt Type of current statement.
+ * @param[in] next_stmt Type of next statement.
+ * @param[in] parent_stmt Type of parent statement, can be se to to LY_STMT_MODULE of LY_STMT_SUBMODULE,
* because relative order is required only in module and submodule sub-elements, used for logging.
* @return LY_SUCCESS on success and LY_EVALID if relative order is invalid.
*/
static LY_ERR
-yin_check_relative_order(struct lysp_yin_ctx *ctx, enum ly_stmt kw, enum ly_stmt next_kw, enum ly_stmt parrent)
+yin_check_relative_order(struct lysp_yin_ctx *ctx, enum ly_stmt cur_stmt, enum ly_stmt next_stmt, enum ly_stmt parent_stmt)
{
- assert(parrent == LY_STMT_MODULE || parrent == LY_STMT_SUBMODULE);
enum yang_module_stmt gr, next_gr;
- if (kw == LY_STMT_EXTENSION_INSTANCE) {
+ assert(parent_stmt == LY_STMT_MODULE || parent_stmt == LY_STMT_SUBMODULE);
+
+ if (cur_stmt == LY_STMT_EXTENSION_INSTANCE) {
/* no order defined */
return LY_SUCCESS;
}
- LY_CHECK_RET(kw2kw_group(ctx, kw, &gr));
- LY_CHECK_RET(kw2kw_group(ctx, next_kw, &next_gr));
+ LY_CHECK_RET(kw2kw_group(ctx, cur_stmt, &gr));
+ LY_CHECK_RET(kw2kw_group(ctx, next_stmt, &next_gr));
if (gr > next_gr) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INORDER_YIN, ly_stmt2str(parrent), ly_stmt2str(next_kw), ly_stmt2str(kw));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INORDER_YIN, lyplg_ext_stmt2str(parent_stmt), lyplg_ext_stmt2str(next_stmt),
+ lyplg_ext_stmt2str(cur_stmt));
return LY_EVALID;
}
@@ -3075,18 +3047,18 @@
* @brief Parse argument of extension subelement that is classic yang keyword and not another instance of extension.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] elem_type Type of element that is currently being parsed.
+ * @param[in] parent_stmt Type of parent statement.
* @param[out] arg Value to write to.
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_extension_instance_arg(struct lysp_yin_ctx *ctx, enum ly_stmt elem_type, const char **arg)
+yin_parse_extension_instance_arg(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, const char **arg)
{
enum ly_stmt child;
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- switch (elem_type) {
+ switch (parent_stmt) {
case LY_STMT_ACTION:
case LY_STMT_ANYDATA:
case LY_STMT_ANYXML:
@@ -3113,12 +3085,12 @@
case LY_STMT_TYPEDEF:
case LY_STMT_UNITS:
case LY_STMT_USES:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_AUGMENT:
case LY_STMT_DEVIATION:
case LY_STMT_REFINE:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_CONFIG:
case LY_STMT_DEFAULT:
@@ -3143,30 +3115,30 @@
case LY_STMT_VALUE:
case LY_STMT_YANG_VERSION:
case LY_STMT_YIN_ELEMENT:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_IMPORT:
case LY_STMT_INCLUDE:
case LY_STMT_BELONGS_TO:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_INPUT:
case LY_STMT_OUTPUT:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_MUST:
case LY_STMT_WHEN:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_CONDITION, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_CONDITION, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_NAMESPACE:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_URI, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_URI, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_REVISION:
case LY_STMT_REVISION_DATE:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_DATE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_DATE, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
case LY_STMT_UNIQUE:
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TAG, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TAG, arg, Y_MAYBE_STR_ARG, parent_stmt));
break;
/* argument is mapped to yin element */
case LY_STMT_CONTACT:
@@ -3175,7 +3147,7 @@
case LY_STMT_REFERENCE:
case LY_STMT_ERROR_MESSAGE:
/* there shouldn't be any attribute, argument is supposed to be first subelement */
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, parent_stmt));
/* no content */
assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
@@ -3184,21 +3156,22 @@
}
if (((ctx->xmlctx->status == LYXML_ELEM_CONTENT) && !ctx->xmlctx->ws_only) || (ctx->xmlctx->status != LYXML_ELEMENT)) {
LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_FIRT_SUBELEM,
- elem_type == LY_STMT_ERROR_MESSAGE ? "value" : "text", ly_stmt2str(elem_type));
+ parent_stmt == LY_STMT_ERROR_MESSAGE ? "value" : "text", lyplg_ext_stmt2str(parent_stmt));
return LY_EVALID;
}
/* parse child element */
- child = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len, elem_type);
- if (((elem_type == LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_VALUE)) ||
- ((elem_type != LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_TEXT))) {
+ child = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
+ ctx->xmlctx->prefix_len, parent_stmt);
+ if (((parent_stmt == LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_VALUE)) ||
+ ((parent_stmt != LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_TEXT))) {
LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
- ly_stmt2str(elem_type));
+ lyplg_ext_stmt2str(parent_stmt));
return LY_EVALID;
}
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- /* no attributes expected? TODO */
+ /* no attributes expected */
while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
@@ -3210,11 +3183,6 @@
/* load closing tag of subelement */
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-
- /* if only subelement was parsed as argument, load also closing tag TODO what? */
- /*if (ctx->xmlctx->status == LYXML_ELEMENT) {
- LY_CHECK_RET(lyxml_get_element(&ctx->xmlctx, data, &prefix, &prefix_len, &name, &name_len));
- }*/
break;
default:
LOGINT(ctx->xmlctx->ctx);
@@ -3228,12 +3196,12 @@
* @brief Parse yin element into generic structure.
*
* @param[in,out] ctx Yin parser context for XML context, logging, and to store current state.
- * @param[in] parent Identification of parent element.
+ * @param[in] parent_stmt Type of parent statement.
* @param[out] element Where the element structure should be stored.
* @return LY_ERR values.
*/
LY_ERR
-yin_parse_element_generic(struct lysp_yin_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element)
+yin_parse_element_generic(struct lysp_yin_ctx *ctx, enum ly_stmt parent_stmt, struct lysp_stmt **element)
{
LY_ERR ret = LY_SUCCESS;
struct lysp_stmt *last = NULL, *new = NULL;
@@ -3263,13 +3231,13 @@
}
(*element)->kw = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
- ctx->xmlctx->prefix_len, parent);
+ ctx->xmlctx->prefix_len, parent_stmt);
last = (*element)->child;
if ((*element)->kw == LY_STMT_NONE) {
/* unrecognized element */
LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
- ly_stmt2str(parent));
+ lyplg_ext_stmt2str(parent_stmt));
ret = LY_EVALID;
goto cleanup;
} else if ((*element)->kw != LY_STMT_EXTENSION_INSTANCE) {
@@ -3347,14 +3315,15 @@
* @brief Parse instance of extension.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] subelem The statement this extension instance is a subelement of.
- * @param[in] subelem_index Index of the keyword instance this extension instance is a subelement of
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of @p parent statement.
+ * @param[in] parent_stmt_index In case of several @p parent_stmt, index of the relevant @p parent statement.
* @param[in,out] exts Extension instance to add to.
* @return LY_ERR values.
*/
LY_ERR
-yin_parse_extension_instance(struct lysp_yin_ctx *ctx, enum ly_stmt subelem, LY_ARRAY_COUNT_TYPE subelem_index,
- struct lysp_ext_instance **exts)
+yin_parse_extension_instance(struct lysp_yin_ctx *ctx, const void *parent, enum ly_stmt parent_stmt,
+ LY_ARRAY_COUNT_TYPE parent_stmt_index, struct lysp_ext_instance **exts)
{
struct lysp_ext_instance *e;
struct lysp_stmt *last_subelem = NULL, *new_subelem = NULL;
@@ -3383,8 +3352,9 @@
LY_CHECK_RET(ly_store_prefix_data(ctx->xmlctx->ctx, e->name, strlen(e->name), LY_VALUE_XML, &ctx->xmlctx->ns,
&e->format, &e->prefix_data));
- e->parent_stmt = subelem;
- e->parent_stmt_index = subelem_index;
+ e->parent = (void *)parent;
+ e->parent_stmt = parent_stmt;
+ e->parent_stmt_index = parent_stmt_index;
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
@@ -3431,16 +3401,10 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}
} else if (ctx->xmlctx->value_len) {
- /* save text content */
- INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, e->argument);
- LY_CHECK_RET(!e->argument, LY_EMEM);
-
- /* store prefix data for the argument as well */
- LY_CHECK_RET(ly_store_prefix_data(ctx->xmlctx->ctx, e->argument, strlen(e->argument), LY_VALUE_XML,
- &ctx->xmlctx->ns, &e->format, &e->prefix_data));
-
- /* parser next */
- LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ /* invalid text content */
+ LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Extension instance \"%s\" with unexpected text content \".*s\".", ext_name,
+ (int)ctx->xmlctx->value_len, ctx->xmlctx->value);
+ return LY_EVALID;
}
e->parsed = NULL;
@@ -3454,18 +3418,19 @@
* @param[in,out] ctx Yin parser context for logging and to store current state.
* @param[in] subelem_info array of valid subelement types and meta information
* @param[in] subelem_info_size Size of subelem_info array.
- * @param[in] current_element Type of current element.
+ * @param[in] parent Current statement parent.
+ * @param[in] parent_stmt Type of @p parent statement.
* @param[out] text_content Where the text content of element should be stored if any. Text content is ignored if set to NULL.
* @param[in,out] exts Extension instance to add to. Can be set to null if element cannot have extension as subelements.
* @return LY_ERR values.
*/
LY_ERR
yin_parse_content(struct lysp_yin_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
- enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts)
+ const void *parent, enum ly_stmt parent_stmt, const char **text_content, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
enum LYXML_PARSER_STATUS next_status;
- enum ly_stmt kw = LY_STMT_NONE, last_kw = LY_STMT_NONE;
+ enum ly_stmt cur_stmt = LY_STMT_NONE, last_stmt = LY_STMT_NONE;
struct yin_subelement *subelem = NULL;
assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
@@ -3484,44 +3449,44 @@
/* current element has subelements as content */
while (ctx->xmlctx->status == LYXML_ELEMENT) {
/* match keyword */
- last_kw = kw;
- kw = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
- ctx->xmlctx->prefix_len, current_element);
+ last_stmt = cur_stmt;
+ cur_stmt = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
+ ctx->xmlctx->prefix_len, parent_stmt);
/* check if this element can be child of current element */
- subelem = get_record(kw, subelem_info_size, subelem_info);
+ subelem = get_record(cur_stmt, subelem_info_size, subelem_info);
if (!subelem) {
- if ((current_element == LY_STMT_DEVIATE) && isdevsub(kw)) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INDEV_YIN, ly_stmt2str(kw));
+ if ((parent_stmt == LY_STMT_DEVIATE) && isdevsub(cur_stmt)) {
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INDEV_YIN, lyplg_ext_stmt2str(cur_stmt));
} else {
LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len,
- ctx->xmlctx->name, ly_stmt2str(current_element));
+ ctx->xmlctx->name, lyplg_ext_stmt2str(parent_stmt));
}
ret = LY_EVALID;
goto cleanup;
}
/* relative order is required only in module and submodule sub-elements */
- if ((current_element == LY_STMT_MODULE) || (current_element == LY_STMT_SUBMODULE)) {
- ret = yin_check_relative_order(ctx, last_kw, kw, current_element);
+ if ((parent_stmt == LY_STMT_MODULE) || (parent_stmt == LY_STMT_SUBMODULE)) {
+ ret = yin_check_relative_order(ctx, last_stmt, cur_stmt, parent_stmt);
LY_CHECK_GOTO(ret, cleanup);
}
/* flag check */
if ((subelem->flags & YIN_SUBELEM_UNIQUE) && (subelem->flags & YIN_SUBELEM_PARSED)) {
/* subelement uniquenes */
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_SUBELEM_REDEF, ly_stmt2str(kw), ly_stmt2str(current_element));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_SUBELEM_REDEF, lyplg_ext_stmt2str(cur_stmt), lyplg_ext_stmt2str(parent_stmt));
return LY_EVALID;
}
if (subelem->flags & YIN_SUBELEM_FIRST) {
/* subelement is supposed to be defined as first subelement */
- ret = yin_check_subelem_first_constraint(ctx, subelem_info, subelem_info_size, current_element, subelem);
+ ret = yin_check_subelem_first_constraint(ctx, subelem_info, subelem_info_size, parent_stmt, subelem);
LY_CHECK_GOTO(ret, cleanup);
}
if (subelem->flags & YIN_SUBELEM_VER2) {
/* subelement is supported only in version 1.1 or higher */
if (PARSER_CUR_PMOD(ctx)->version < LYS_VERSION_1_1) {
- LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INSUBELEM2, ly_stmt2str(kw), ly_stmt2str(current_element));
+ LOGVAL_PARSER((struct lysp_ctx *)ctx, LY_VCODE_INSUBELEM2, lyplg_ext_stmt2str(cur_stmt), lyplg_ext_stmt2str(parent_stmt));
ret = LY_EVALID;
goto cleanup;
}
@@ -3529,10 +3494,10 @@
/* note that element was parsed for easy uniqueness check in next iterations */
subelem->flags |= YIN_SUBELEM_PARSED;
- switch (kw) {
+ switch (cur_stmt) {
/* call responsible function */
case LY_STMT_EXTENSION_INSTANCE:
- ret = yin_parse_extension_instance(ctx, current_element,
+ ret = yin_parse_extension_instance(ctx, parent, parent_stmt,
(subelem->dest) ? *((LY_ARRAY_COUNT_TYPE *)subelem->dest) : 0, exts);
break;
case LY_STMT_ACTION:
@@ -3541,16 +3506,16 @@
break;
case LY_STMT_ANYDATA:
case LY_STMT_ANYXML:
- ret = yin_parse_any(ctx, kw, (struct tree_node_meta *)subelem->dest);
+ ret = yin_parse_any(ctx, cur_stmt, (struct tree_node_meta *)subelem->dest);
break;
case LY_STMT_ARGUMENT:
- ret = yin_parse_argument(ctx, (struct yin_argument_meta *)subelem->dest, exts);
+ ret = yin_parse_argument(ctx, parent, (struct yin_argument_meta *)subelem->dest, exts);
break;
case LY_STMT_AUGMENT:
ret = yin_parse_augment(ctx, (struct tree_node_meta *)subelem->dest);
break;
case LY_STMT_BASE:
- ret = yin_parse_base(ctx, current_element, subelem->dest, exts);
+ ret = yin_parse_base(ctx, parent_stmt, subelem->dest, exts);
break;
case LY_STMT_BELONGS_TO:
ret = yin_parse_belongs_to(ctx, (struct lysp_submodule *)subelem->dest, exts);
@@ -3571,18 +3536,20 @@
case LY_STMT_DESCRIPTION:
case LY_STMT_ORGANIZATION:
case LY_STMT_REFERENCE:
- ret = yin_parse_meta(ctx, kw, (const char **)subelem->dest, exts);
+ ret = yin_parse_meta(ctx, parent, cur_stmt, (const char **)subelem->dest, exts);
break;
case LY_STMT_CONTAINER:
ret = yin_parse_container(ctx, (struct tree_node_meta *)subelem->dest);
break;
case LY_STMT_DEFAULT:
- ret = yin_parse_qname(ctx, kw, subelem, exts);
+ ret = yin_parse_qname(ctx, cur_stmt, subelem, exts);
break;
case LY_STMT_ERROR_APP_TAG:
case LY_STMT_KEY:
+ ret = yin_parse_simple_elem(ctx, parent, cur_stmt, subelem, YIN_ARG_VALUE, Y_STR_ARG, exts);
+ break;
case LY_STMT_PRESENCE:
- ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_VALUE, Y_STR_ARG, exts);
+ ret = yin_parse_simple_elem(ctx, *(const char **)subelem->dest, cur_stmt, subelem, YIN_ARG_VALUE, Y_STR_ARG, exts);
break;
case LY_STMT_DEVIATE:
ret = yin_parse_deviate(ctx, (struct lysp_deviate **)subelem->dest);
@@ -3594,7 +3561,7 @@
ret = yin_parse_enum(ctx, (struct lysp_type *)subelem->dest);
break;
case LY_STMT_ERROR_MESSAGE:
- ret = yin_parse_err_msg(ctx, (const char **)subelem->dest, exts);
+ ret = yin_parse_err_msg(ctx, parent, (const char **)subelem->dest, exts);
break;
case LY_STMT_EXTENSION:
ret = yin_parse_extension(ctx, (struct lysp_ext **)subelem->dest);
@@ -3613,24 +3580,24 @@
break;
case LY_STMT_UNIQUE:
case LY_STMT_IF_FEATURE:
- ret = yin_parse_qname(ctx, kw, subelem, exts);
+ ret = yin_parse_qname(ctx, cur_stmt, subelem, exts);
break;
case LY_STMT_UNITS:
- ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_NAME, Y_STR_ARG, exts);
+ ret = yin_parse_simple_elem(ctx, *(const char **)subelem->dest, cur_stmt, subelem, YIN_ARG_NAME, Y_STR_ARG, exts);
break;
case LY_STMT_IMPORT:
ret = yin_parse_import(ctx, (struct import_meta *)subelem->dest);
break;
case LY_STMT_INCLUDE:
- if ((current_element == LY_STMT_SUBMODULE) && (PARSER_CUR_PMOD(ctx)->version == LYS_VERSION_1_1)) {
- LOGWRN(PARSER_CTX(ctx), "YANG version 1.1 expects all includes in main module, includes in submodules (%s) are not necessary.",
- ((struct lysp_submodule *)PARSER_CUR_PMOD(ctx))->name);
+ if ((parent_stmt == LY_STMT_SUBMODULE) && (PARSER_CUR_PMOD(ctx)->version == LYS_VERSION_1_1)) {
+ LOGWRN(PARSER_CTX(ctx), "YANG version 1.1 expects all includes in main module, includes in "
+ "submodules (%s) are not necessary.", ((struct lysp_submodule *)PARSER_CUR_PMOD(ctx))->name);
}
ret = yin_parse_include(ctx, (struct include_meta *)subelem->dest);
break;
case LY_STMT_INPUT:
case LY_STMT_OUTPUT:
- ret = yin_parse_inout(ctx, kw, (struct inout_meta *)subelem->dest);
+ ret = yin_parse_inout(ctx, cur_stmt, (struct inout_meta *)subelem->dest);
break;
case LY_STMT_LEAF:
ret = yin_parse_leaf(ctx, (struct tree_node_meta *)subelem->dest);
@@ -3649,35 +3616,36 @@
break;
case LY_STMT_MAX_ELEMENTS:
case LY_STMT_MIN_ELEMENTS:
- ret = yin_parse_minmax(ctx, current_element, kw, subelem->dest);
+ ret = yin_parse_minmax(ctx, parent_stmt, cur_stmt, subelem->dest);
break;
case LY_STMT_MODIFIER:
- ret = yin_parse_modifier(ctx, (const char **)subelem->dest, exts);
+ ret = yin_parse_modifier(ctx, parent, (const char **)subelem->dest, exts);
break;
case LY_STMT_MUST:
ret = yin_parse_must(ctx, (struct lysp_restr **)subelem->dest);
break;
case LY_STMT_NAMESPACE:
- ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_URI, Y_STR_ARG, exts);
+ ret = yin_parse_simple_elem(ctx, parent, cur_stmt, subelem, YIN_ARG_URI, Y_STR_ARG, exts);
break;
case LY_STMT_NOTIFICATION:
ret = yin_parse_notification(ctx, (struct tree_node_meta *)subelem->dest);
break;
case LY_STMT_ORDERED_BY:
- ret = yin_parse_orderedby(ctx, (uint16_t *)subelem->dest, exts);
+ ret = yin_parse_orderedby(ctx, parent, (uint16_t *)subelem->dest, exts);
break;
case LY_STMT_PATH:
- ret = yin_parse_path(ctx, kw, (struct lysp_type *)subelem->dest);
+ ret = yin_parse_path(ctx, (struct lysp_type *)subelem->dest);
break;
case LY_STMT_PATTERN:
ret = yin_parse_pattern(ctx, (struct lysp_type *)subelem->dest);
break;
case LY_STMT_VALUE:
case LY_STMT_POSITION:
- ret = yin_parse_value_pos(ctx, kw, (struct lysp_type_enum *)subelem->dest);
+ ret = yin_parse_value_pos(ctx, cur_stmt, (struct lysp_type_enum *)subelem->dest);
break;
case LY_STMT_PREFIX:
- ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_VALUE, Y_IDENTIF_ARG, exts);
+ ret = yin_parse_simple_elem(ctx, *(const char **)subelem->dest, cur_stmt, subelem, YIN_ARG_VALUE,
+ Y_IDENTIF_ARG, exts);
break;
case LY_STMT_RANGE:
ret = yin_parse_range(ctx, (struct lysp_type *)subelem->dest);
@@ -3698,7 +3666,7 @@
ret = yin_parse_status(ctx, (uint16_t *)subelem->dest, exts);
break;
case LY_STMT_TYPE:
- ret = yin_parse_type(ctx, current_element, subelem);
+ ret = yin_parse_type(ctx, parent_stmt, subelem);
break;
case LY_STMT_TYPEDEF:
ret = yin_parse_typedef(ctx, (struct tree_node_meta *)subelem->dest);
@@ -3710,10 +3678,10 @@
ret = yin_parse_when(ctx, (struct lysp_when **)subelem->dest);
break;
case LY_STMT_YANG_VERSION:
- ret = yin_parse_yangversion(ctx, (uint8_t *)subelem->dest, exts);
+ ret = yin_parse_yangversion(ctx, parent, (uint8_t *)subelem->dest, exts);
break;
case LY_STMT_YIN_ELEMENT:
- ret = yin_parse_yin_element(ctx, (uint16_t *)subelem->dest, exts);
+ ret = yin_parse_yin_element(ctx, parent, (uint16_t *)subelem->dest, exts);
break;
case LY_STMT_ARG_TEXT:
case LY_STMT_ARG_VALUE:
@@ -3723,7 +3691,7 @@
LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
- ret = yin_parse_content(ctx, NULL, 0, kw, (const char **)subelem->dest, NULL);
+ ret = yin_parse_content(ctx, NULL, 0, parent, cur_stmt, (const char **)subelem->dest, NULL);
break;
default:
LOGINT(ctx->xmlctx->ctx);
@@ -3749,7 +3717,7 @@
}
/* mandatory subelements are checked only after whole element was succesfully parsed */
- LY_CHECK_RET(yin_check_subelem_mandatory_constraint(ctx, subelem_info, subelem_info_size, current_element));
+ LY_CHECK_RET(yin_check_subelem_mandatory_constraint(ctx, subelem_info, subelem_info_size, parent_stmt));
cleanup:
return ret;
@@ -3804,7 +3772,7 @@
LY_STMT_YANG_VERSION, &mod->version, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_MODULE, NULL, &mod->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, mod, LY_STMT_MODULE, NULL, &mod->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -3871,7 +3839,7 @@
LY_STMT_YANG_VERSION, &submod->version, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
- ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_SUBMODULE, NULL, &submod->exts);
+ ret = yin_parse_content(ctx, subelems, subelems_size, submod, LY_STMT_SUBMODULE, NULL, &submod->exts);
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
@@ -3920,11 +3888,11 @@
kw = yin_match_keyword(*yin_ctx, (*yin_ctx)->xmlctx->name, (*yin_ctx)->xmlctx->name_len, (*yin_ctx)->xmlctx->prefix,
(*yin_ctx)->xmlctx->prefix_len, LY_STMT_NONE);
if (kw == LY_STMT_MODULE) {
- LOGERR(ctx, LY_EDENIED, "Input data contains module in situation when a submodule is expected.");
+ LOGERR(ctx, LY_EDENIED, "Input data contains module when a submodule is expected.");
ret = LY_EINVAL;
goto cleanup;
} else if (kw != LY_STMT_SUBMODULE) {
- LOGVAL_PARSER((struct lysp_ctx *)*yin_ctx, LY_VCODE_MOD_SUBOMD, ly_stmt2str(kw));
+ LOGVAL_PARSER((struct lysp_ctx *)*yin_ctx, LY_VCODE_MOD_SUBOMD, lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
}
@@ -3950,6 +3918,7 @@
*submod = mod_p;
cleanup:
+ LOG_LOCBACK(0, 0, 0, 1);
if (ret) {
lysp_module_free(&fctx, (struct lysp_module *)mod_p);
lysp_yin_ctx_free(*yin_ctx);
@@ -3987,7 +3956,7 @@
ret = LY_EINVAL;
goto cleanup;
} else if (kw != LY_STMT_MODULE) {
- LOGVAL_PARSER((struct lysp_ctx *)*yin_ctx, LY_VCODE_MOD_SUBOMD, ly_stmt2str(kw));
+ LOGVAL_PARSER((struct lysp_ctx *)*yin_ctx, LY_VCODE_MOD_SUBOMD, lyplg_ext_stmt2str(kw));
ret = LY_EVALID;
goto cleanup;
}
@@ -4013,7 +3982,8 @@
mod->parsed = mod_p;
cleanup:
- if (ret != LY_SUCCESS) {
+ LOG_LOCBACK(0, 0, 0, 1);
+ if (ret) {
lysp_module_free(&fctx, mod_p);
lysp_yin_ctx_free(*yin_ctx);
*yin_ctx = NULL;
diff --git a/src/plugins_exts.c b/src/plugins_exts.c
index eb688d5..a09b72b 100644
--- a/src/plugins_exts.c
+++ b/src/plugins_exts.c
@@ -14,68 +14,544 @@
*/
#include "plugins_exts.h"
-#include "plugins_exts_compile.h"
-#include "plugins_exts_print.h"
+#include <assert.h>
#include <stdint.h>
+#include <stdlib.h>
#include "common.h"
+#include "dict.h"
+#include "parser_internal.h"
#include "printer_internal.h"
#include "schema_compile.h"
+#include "schema_compile_amend.h"
+#include "schema_compile_node.h"
+#include "schema_features.h"
+#include "tree_schema_internal.h"
+
+LIBYANG_API_DEF const struct lysp_module *
+lyplg_ext_parse_get_cur_pmod(const struct lysp_ctx *pctx)
+{
+ return PARSER_CUR_PMOD(pctx);
+}
+
+LIBYANG_API_DEF LY_ERR
+lyplg_ext_parse_extension_instance(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
+{
+ LY_ERR rc = LY_SUCCESS;
+ LY_ARRAY_COUNT_TYPE u;
+ struct lysp_stmt *stmt;
+
+ /* check for invalid substatements */
+ LY_LIST_FOR(ext->child, stmt) {
+ if (stmt->flags & (LYS_YIN_ATTR | LYS_YIN_ARGUMENT)) {
+ continue;
+ }
+ LY_ARRAY_FOR(ext->substmts, u) {
+ if (ext->substmts[u].stmt == stmt->kw) {
+ break;
+ }
+ }
+ if (u == LY_ARRAY_COUNT(ext->substmts)) {
+ LOGVAL(PARSER_CTX(pctx), LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s%s%s\" extension instance.",
+ stmt->stmt, ext->name, ext->argument ? " " : "", ext->argument ? ext->argument : "");
+ rc = LY_EVALID;
+ goto cleanup;
+ }
+ }
+
+ /* parse all the known statements */
+ LY_ARRAY_FOR(ext->substmts, u) {
+ LY_LIST_FOR(ext->child, stmt) {
+ if (ext->substmts[u].stmt != stmt->kw) {
+ continue;
+ }
+
+ if ((rc = lys_parse_ext_instance_stmt(pctx, &ext->substmts[u], stmt))) {
+ goto cleanup;
+ }
+ }
+ }
+
+cleanup:
+ return rc;
+}
+
+/**
+ * @brief Compile an instance extension statement.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] parsed Parsed ext instance substatement structure.
+ * @param[in] ext Compiled ext instance.
+ * @param[in] substmt Compled ext instance substatement info.
+ * @param[in,out] aug_target Optional augment target where to append all schema data nodes.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, const void *parsed, struct lysc_ext_instance *ext,
+ struct lysc_ext_substmt *substmt, struct lysc_node *aug_target)
+{
+ LY_ERR rc = LY_SUCCESS;
+ ly_bool length_restr = 0;
+ LY_DATA_TYPE basetype;
+
+ /* compilation wthout any storage */
+ if (substmt->stmt == LY_STMT_IF_FEATURE) {
+ ly_bool enabled;
+
+ /* evaluate */
+ LY_CHECK_GOTO(rc = lys_eval_iffeatures(ctx->ctx, parsed, &enabled), cleanup);
+ if (!enabled) {
+ /* it is disabled, remove the whole extension instance */
+ rc = LY_ENOT;
+ }
+ }
+
+ if (!substmt->storage || !parsed) {
+ /* nothing to store or nothing parsed to compile */
+ goto cleanup;
+ }
+
+ switch (substmt->stmt) {
+ case LY_STMT_NOTIFICATION:
+ case LY_STMT_INPUT:
+ case LY_STMT_OUTPUT:
+ case LY_STMT_ACTION:
+ case LY_STMT_RPC:
+ case LY_STMT_ANYDATA:
+ case LY_STMT_ANYXML:
+ case LY_STMT_CASE:
+ case LY_STMT_CHOICE:
+ case LY_STMT_CONTAINER:
+ case LY_STMT_LEAF:
+ case LY_STMT_LEAF_LIST:
+ case LY_STMT_LIST:
+ case LY_STMT_USES: {
+ const uint16_t flags;
+ struct lysp_node *pnodes, *pnode;
+ struct lysc_node *node;
+
+ lyplg_ext_get_storage(ext, LY_STMT_STATUS, (const void **)&flags);
+ pnodes = (struct lysp_node *)parsed;
+ if (aug_target) {
+ /* compile augmented nodes */
+ LY_CHECK_GOTO(rc = lys_compile_augment_children(ctx, NULL, 0, (struct lysp_node *)pnodes, aug_target, 0), cleanup);
+ } else {
+ /* compile nodes */
+ LY_LIST_FOR(pnodes, pnode) {
+ if (pnode->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
+ /* manual compile */
+ node = calloc(1, sizeof(struct lysc_node_action_inout));
+ LY_CHECK_ERR_GOTO(!node, LOGMEM(ctx->ctx); rc = LY_EMEM, cleanup);
+ LY_CHECK_GOTO(rc = lys_compile_node_action_inout(ctx, pnode, node), cleanup);
+ LY_CHECK_GOTO(rc = lys_compile_node_connect(ctx, NULL, node), cleanup);
+ } else {
+ /* ctx->ext substatement storage is used as the document root */
+ LY_CHECK_GOTO(rc = lys_compile_node(ctx, pnode, NULL, flags ? &flags : NULL, NULL), cleanup);
+ }
+ }
+ }
+ break;
+ }
+ case LY_STMT_ARGUMENT:
+ case LY_STMT_CONTACT:
+ case LY_STMT_DESCRIPTION:
+ case LY_STMT_ERROR_APP_TAG:
+ case LY_STMT_ERROR_MESSAGE:
+ case LY_STMT_KEY:
+ case LY_STMT_MODIFIER:
+ case LY_STMT_NAMESPACE:
+ case LY_STMT_ORGANIZATION:
+ case LY_STMT_PRESENCE:
+ case LY_STMT_REFERENCE:
+ case LY_STMT_UNITS:
+ /* just make a copy */
+ LY_CHECK_GOTO(rc = lydict_insert(ctx->ctx, parsed, 0, substmt->storage), cleanup);
+ break;
+
+ case LY_STMT_BIT:
+ basetype = LY_TYPE_BITS;
+ /* fallthrough */
+ case LY_STMT_ENUM:
+ if (substmt->stmt == LY_STMT_ENUM) {
+ basetype = LY_TYPE_ENUM;
+ }
+
+ /* compile */
+ LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, parsed, basetype, NULL, substmt->storage), cleanup);
+ break;
+
+ case LY_STMT_CONFIG: {
+ const uint16_t flags = (uintptr_t)parsed;
+
+ if (!(ctx->compile_opts & LYS_COMPILE_NO_CONFIG)) {
+ if (flags & LYS_CONFIG_MASK) {
+ /* explicitly set */
+ *(uint16_t *)substmt->storage = flags | LYS_SET_CONFIG;
+ } else if (ext->parent_stmt & LY_STMT_DATA_NODE_MASK) {
+ /* inherit */
+ *(uint16_t *)substmt->storage = ((struct lysc_node *)ext->parent)->flags & LYS_CONFIG_MASK;
+ } else {
+ /* default config */
+ *(uint16_t *)substmt->storage = LYS_CONFIG_W;
+ }
+ } /* else leave zero */
+ break;
+ }
+ case LY_STMT_MUST: {
+ const struct lysp_restr *restrs = parsed;
+ struct lysc_must *musts = *(struct lysc_must **)substmt->storage;
+
+ /* sized array */
+ COMPILE_ARRAY_GOTO(ctx, restrs, musts, lys_compile_must, rc, cleanup);
+ break;
+ }
+ case LY_STMT_WHEN: {
+ const uint16_t flags;
+ const struct lysp_when *when = parsed;
+
+ /* read compiled status */
+ lyplg_ext_get_storage(ext, LY_STMT_STATUS, (const void **)&flags);
+
+ /* compile */
+ LY_CHECK_GOTO(rc = lys_compile_when(ctx, when, flags, NULL, NULL, NULL, substmt->storage), cleanup);
+ break;
+ }
+ case LY_STMT_FRACTION_DIGITS:
+ case LY_STMT_REQUIRE_INSTANCE:
+ /* just make a copy */
+ *(uint8_t *)substmt->storage = (uintptr_t)parsed;
+ break;
+
+ case LY_STMT_MANDATORY:
+ case LY_STMT_ORDERED_BY:
+ case LY_STMT_STATUS:
+ /* just make a copy */
+ *(uint16_t *)substmt->storage = (uintptr_t)parsed;
+ break;
+
+ case LY_STMT_MAX_ELEMENTS:
+ case LY_STMT_MIN_ELEMENTS:
+ /* just make a copy */
+ *(uint32_t *)substmt->storage = (uintptr_t)parsed;
+ break;
+
+ case LY_STMT_POSITION:
+ case LY_STMT_VALUE:
+ /* just make a copy */
+ *(int64_t *)substmt->storage = (uintptr_t)parsed;
+ break;
+
+ case LY_STMT_IDENTITY:
+ /* compile */
+ LY_CHECK_GOTO(rc = lys_identity_precompile(ctx, NULL, NULL, parsed, substmt->storage), cleanup);
+ break;
+
+ case LY_STMT_LENGTH:
+ length_restr = 1;
+ /* fallthrough */
+ case LY_STMT_RANGE:
+ /* compile, use uint64 default range */
+ LY_CHECK_GOTO(rc = lys_compile_type_range(ctx, parsed, LY_TYPE_UINT64, length_restr, 0, NULL, substmt->storage),
+ cleanup);
+ break;
+
+ case LY_STMT_PATTERN:
+ /* compile */
+ LY_CHECK_GOTO(rc = lys_compile_type_patterns(ctx, parsed, NULL, substmt->storage), cleanup);
+ break;
+
+ case LY_STMT_TYPE: {
+ const uint16_t flags;
+ const char *units;
+ const struct lysp_type *ptype = parsed;
+
+ /* read compiled info */
+ lyplg_ext_get_storage(ext, LY_STMT_STATUS, (const void **)&flags);
+ lyplg_ext_get_storage(ext, LY_STMT_UNITS, (const void **)&units);
+
+ /* compile */
+ LY_CHECK_GOTO(rc = lys_compile_type(ctx, NULL, flags, ext->def->name, ptype, substmt->storage, &units, NULL), cleanup);
+ break;
+ }
+ case LY_STMT_EXTENSION_INSTANCE: {
+ struct lysp_ext_instance *extps = (struct lysp_ext_instance *)parsed;
+ struct lysc_ext_instance *exts = *(struct lysc_ext_instance **)substmt->storage;
+
+ /* compile sized array */
+ COMPILE_EXTS_GOTO(ctx, extps, exts, ext, rc, cleanup);
+ break;
+ }
+ case LY_STMT_AUGMENT:
+ case LY_STMT_GROUPING:
+ case LY_STMT_BASE:
+ case LY_STMT_BELONGS_TO:
+ case LY_STMT_DEFAULT:
+ case LY_STMT_DEVIATE:
+ case LY_STMT_DEVIATION:
+ case LY_STMT_EXTENSION:
+ case LY_STMT_FEATURE:
+ case LY_STMT_IF_FEATURE:
+ case LY_STMT_IMPORT:
+ case LY_STMT_INCLUDE:
+ case LY_STMT_MODULE:
+ case LY_STMT_PATH:
+ case LY_STMT_PREFIX:
+ case LY_STMT_REFINE:
+ case LY_STMT_REVISION:
+ case LY_STMT_REVISION_DATE:
+ case LY_STMT_SUBMODULE:
+ case LY_STMT_TYPEDEF:
+ case LY_STMT_UNIQUE:
+ case LY_STMT_YANG_VERSION:
+ case LY_STMT_YIN_ELEMENT:
+ LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Statement \"%s\" compilation is not supported.", lyplg_ext_stmt2str(substmt->stmt));
+ rc = LY_EVALID;
+ goto cleanup;
+
+ default:
+ LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Statement \"%s\" is not supported as an extension "
+ "(found in \"%s%s%s\") substatement.", lyplg_ext_stmt2str(substmt->stmt), ext->def->name,
+ ext->argument ? " " : "", ext->argument ? ext->argument : "");
+ rc = LY_EVALID;
+ goto cleanup;
+ }
+
+cleanup:
+ return rc;
+}
+
+static LY_ERR
+lys_compile_extension_instance_(struct lysc_ctx *ctx, const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext,
+ struct lysc_node *aug_target)
+{
+ LY_ERR rc = LY_SUCCESS;
+ LY_ARRAY_COUNT_TYPE u, v;
+ enum ly_stmt stmtp;
+ const void *storagep;
+ struct ly_set storagep_compiled = {0};
+
+ /* note into the compile context that we are processing extension now */
+ ctx->ext = ext;
+
+ LY_ARRAY_FOR(extp->substmts, u) {
+ stmtp = extp->substmts[u].stmt;
+ storagep = *(void **)extp->substmts[u].storage;
+
+ if (ly_set_contains(&storagep_compiled, storagep, NULL)) {
+ /* this parsed statement has already been compiled (for example, if it is a linked list of parsed nodes) */
+ continue;
+ }
+
+ LY_ARRAY_FOR(ext->substmts, v) {
+ if (stmtp != ext->substmts[v].stmt) {
+ continue;
+ }
+
+ if ((rc = lys_compile_ext_instance_stmt(ctx, storagep, ext, &ext->substmts[v], aug_target))) {
+ goto cleanup;
+ }
+
+ /* parsed substatement compiled */
+ break;
+ }
+
+ /* compiled */
+ ly_set_add(&storagep_compiled, storagep, 1, NULL);
+ }
+
+cleanup:
+ ctx->ext = NULL;
+ ly_set_erase(&storagep_compiled, NULL);
+ return rc;
+}
+
+LIBYANG_API_DEF LY_ERR
+lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext)
+{
+ LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, ext_p, ext, LY_EINVAL);
+
+ return lys_compile_extension_instance_(ctx, ext_p, ext, NULL);
+}
+
+LIBYANG_API_DEF LY_ERR
+lyplg_ext_compile_extension_instance_augment(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p,
+ struct lysc_ext_instance *ext, struct lysc_node *aug_target)
+{
+ LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, ext_p, ext, aug_target, LY_EINVAL);
+
+ return lys_compile_extension_instance_(ctx, ext_p, ext, aug_target);
+}
LIBYANG_API_DEF struct ly_ctx *
-lysc_ctx_get_ctx(const struct lysc_ctx *ctx)
+lyplg_ext_compile_get_ctx(const struct lysc_ctx *ctx)
{
return ctx->ctx;
}
LIBYANG_API_DEF uint32_t *
-lysc_ctx_get_options(const struct lysc_ctx *ctx)
+lyplg_ext_compile_get_options(const struct lysc_ctx *ctx)
{
return &((struct lysc_ctx *)ctx)->compile_opts;
}
-LIBYANG_API_DEF const char *
-lysc_ctx_get_path(const struct lysc_ctx *ctx)
-{
- return ctx->path;
-}
-
-LIBYANG_API_DEF struct ly_out **
-lys_ypr_ctx_get_out(const struct lyspr_ctx *ctx)
-{
- return &((struct lyspr_ctx *)ctx)->out;
-}
-
-LIBYANG_API_DEF uint32_t *
-lys_ypr_ctx_get_options(const struct lyspr_ctx *ctx)
-{
- return &((struct lyspr_ctx *)ctx)->options;
-}
-
-LIBYANG_API_DEF uint16_t *
-lys_ypr_ctx_get_level(const struct lyspr_ctx *ctx)
-{
- return &((struct lyspr_ctx *)ctx)->level;
-}
-
LIBYANG_API_DEF const struct lys_module *
-lysc_ctx_get_cur_mod(const struct lysc_ctx *ctx)
+lyplg_ext_compile_get_cur_mod(const struct lysc_ctx *ctx)
{
return ctx->cur_mod;
}
LIBYANG_API_DEF struct lysp_module *
-lysc_ctx_get_pmod(const struct lysc_ctx *ctx)
+lyplg_ext_compile_get_pmod(const struct lysc_ctx *ctx)
{
return ctx->pmod;
}
+LIBYANG_API_DEF struct ly_out **
+lyplg_ext_print_get_out(const struct lyspr_ctx *ctx)
+{
+ return &((struct lyspr_ctx *)ctx)->out;
+}
+
+LIBYANG_API_DEF uint32_t *
+lyplg_ext_print_get_options(const struct lyspr_ctx *ctx)
+{
+ return &((struct lyspr_ctx *)ctx)->options;
+}
+
+LIBYANG_API_DEF uint16_t *
+lyplg_ext_print_get_level(const struct lyspr_ctx *ctx)
+{
+ return &((struct lyspr_ctx *)ctx)->level;
+}
+
+LIBYANG_API_DEF const char *
+lyplg_ext_stmt2str(enum ly_stmt stmt)
+{
+ if (stmt == LY_STMT_EXTENSION_INSTANCE) {
+ return "extension instance";
+ } else {
+ return stmt_attr_info[stmt].name;
+ }
+}
+
+LIBYANG_API_DEF enum ly_stmt
+lyplg_ext_nodetype2stmt(uint16_t nodetype)
+{
+ switch (nodetype) {
+ case LYS_CONTAINER:
+ return LY_STMT_CONTAINER;
+ case LYS_CHOICE:
+ return LY_STMT_CHOICE;
+ case LYS_LEAF:
+ return LY_STMT_LEAF;
+ case LYS_LEAFLIST:
+ return LY_STMT_LEAF_LIST;
+ case LYS_LIST:
+ return LY_STMT_LIST;
+ case LYS_ANYXML:
+ return LY_STMT_ANYXML;
+ case LYS_ANYDATA:
+ return LY_STMT_ANYDATA;
+ case LYS_CASE:
+ return LY_STMT_CASE;
+ case LYS_RPC:
+ return LY_STMT_RPC;
+ case LYS_ACTION:
+ return LY_STMT_ACTION;
+ case LYS_NOTIF:
+ return LY_STMT_NOTIFICATION;
+ case LYS_USES:
+ return LY_STMT_USES;
+ case LYS_INPUT:
+ return LY_STMT_INPUT;
+ case LYS_OUTPUT:
+ return LY_STMT_OUTPUT;
+ default:
+ return LY_STMT_NONE;
+ }
+}
+
+LY_ERR
+lyplg_ext_get_storage_p(const struct lysc_ext_instance *ext, int stmt, const void ***storage_p)
+{
+ LY_ARRAY_COUNT_TYPE u;
+ enum ly_stmt match = 0;
+
+ *storage_p = NULL;
+
+ if (!(stmt & LY_STMT_NODE_MASK)) {
+ /* matching a non-node statement */
+ match = stmt;
+ }
+
+ LY_ARRAY_FOR(ext->substmts, u) {
+ if ((match && (ext->substmts[u].stmt == match)) || (!match && (ext->substmts[u].stmt & stmt))) {
+ *storage_p = ext->substmts[u].storage;
+ return LY_SUCCESS;
+ }
+ }
+
+ return LY_ENOT;
+}
+
+LIBYANG_API_DEF LY_ERR
+lyplg_ext_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage)
+{
+ LY_ERR r;
+ const void **s;
+
+ *storage = NULL;
+
+ if ((r = lyplg_ext_get_storage_p(ext, stmt, &s))) {
+ return r;
+ }
+
+ *storage = *s;
+ return LY_SUCCESS;
+}
+
+LIBYANG_API_DEF LY_ERR
+lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage)
+{
+ LY_ARRAY_COUNT_TYPE u;
+ const struct lysp_ext_instance *extp = NULL;
+ enum ly_stmt match = 0;
+
+ *storage = NULL;
+
+ /* find the parsed ext instance */
+ LY_ARRAY_FOR(ext->module->parsed->exts, u) {
+ extp = &ext->module->parsed->exts[u];
+
+ if (ext->def == extp->def->compiled) {
+ break;
+ }
+ extp = NULL;
+ }
+ assert(extp);
+
+ if (!(stmt & LY_STMT_NODE_MASK)) {
+ /* matching a non-node statement */
+ match = stmt;
+ }
+
+ /* get the substatement */
+ LY_ARRAY_FOR(extp->substmts, u) {
+ if ((match && (extp->substmts[u].stmt == match)) || (!match && (extp->substmts[u].stmt & stmt))) {
+ *storage = *(void **)extp->substmts[u].storage;
+ return LY_SUCCESS;
+ }
+ }
+
+ return LY_ENOT;
+}
+
LIBYANG_API_DEF LY_ERR
lyplg_ext_get_data(const struct ly_ctx *ctx, const struct lysc_ext_instance *ext, void **ext_data, ly_bool *ext_data_free)
{
if (!ctx->ext_clb) {
- lyplg_ext_log(ext, LY_LLERR, LY_EINVAL, NULL, "Failed to get extension data, no callback set.");
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, LY_EINVAL, "Failed to get extension data, no callback set.");
return LY_EINVAL;
}
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index 8ac2254..dd2a369 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -23,15 +23,13 @@
#include "tree_edit.h"
#include "tree_schema.h"
-#include "plugins_exts_compile.h"
-#include "plugins_exts_print.h"
-
struct ly_ctx;
struct ly_in;
struct lyd_node;
+struct lysc_ctx;
struct lysc_ext_substmt;
struct lysp_ctx;
-struct lysp_ext_instance;
+struct lyspr_ctx;
#ifdef __cplusplus
extern "C" {
@@ -86,7 +84,7 @@
* specific plugin responsible to storing data value. In case the user can recognize the id string, it can access the
* plugin specific data with the appropriate knowledge of its structure.
*
- * Logging information from an extension plugin is possible via ::lyplg_ext_log() function
+ * Logging information from an extension plugin is possible via ::lyplg_extp_log() and ::yplg_extc_log() functions.
*/
/**
@@ -106,155 +104,251 @@
#define LYPLG_EXT_API_VERSION 6
/**
- * @brief Generic test for operation statements.
+ * @brief Mask for an operation statement.
*
- * This macro matches a subset of schema nodes that maps to common ::lysc_node or ::lysp_node structures. To match all
- * such nodes, use ::LY_STMT_IS_NODE()
- *
- * This macro matches action and RPC.
+ * This mask matches action and RPC.
*/
-#define LY_STMT_IS_OP(STMT) (((STMT) == LY_STMT_ACTION) || ((STMT) == LY_STMT_RPC))
+#define LY_STMT_OP_MASK (LY_STMT_ACTION | LY_STMT_RPC)
/**
- * @brief Generic test for schema data nodes.
+ * @brief Mask for a data node statement.
*
- * This macro matches a subset of schema nodes that maps to common ::lysc_node or ::lysp_node structures. To match all
- * such nodes, use ::LY_STMT_IS_NODE()
- *
- * This macro matches anydata, anyxml, case, choice, container, leaf, leaf-list, and list.
+ * This mask matches anydata, anyxml, case, choice, container, leaf, leaf-list, and list.
*/
-#define LY_STMT_IS_DATA_NODE(STMT) (((STMT) == LY_STMT_ANYDATA) || ((STMT) == LY_STMT_ANYXML) || \
- ((STMT) == LY_STMT_CASE) || ((STMT) == LY_STMT_CHOICE) || ((STMT) == LY_STMT_CONTAINER) || \
- ((STMT) == LY_STMT_LEAF) || ((STMT) == LY_STMT_LEAF_LIST) || ((STMT) == LY_STMT_LIST))
+#define LY_STMT_DATA_NODE_MASK (LY_STMT_ANYDATA | LY_STMT_ANYXML | LY_STMT_CASE | LY_STMT_CHOICE | LY_STMT_CONTAINER |\
+ LY_STMT_LEAF | LY_STMT_LEAF_LIST | LY_STMT_LIST)
/**
- * @brief Generic test for any schema node that maps to common ::lysc_node or ::lysp_node structures.
+ * @brief Mask for a node statement.
*
- * Note that the list of statements that can appear in parsed or compiled schema trees differs (e.g. no uses in compiled tree).
- *
- * To check for some of the subsets of this test, try ::LY_STMT_IS_DATA_NODE() or ::LY_STMT_IS_OP().
- *
- * This macro matches action, anydata, anyxml, augment, case, choice, container, grouping, input, leaf, leaf-list, list,
- * notification, output, RPC and uses.
+ * This mask matches notification, input, output, action, RPC, anydata, anyxml, augment, case, choice, container,
+ * grouping, leaf, leaf-list, list, and uses.
*/
-#define LY_STMT_IS_NODE(STMT) (((STMT) >= LY_STMT_NOTIFICATION) && ((STMT) <= LY_STMT_LIST))
+#define LY_STMT_NODE_MASK 0xFFFF
/**
* @brief List of YANG statements
+ *
+ * Their description mentions what types are stored for each statement. Note that extension instance storage
+ * always stores a pointer to the type, not the type itself.
*/
enum ly_stmt {
LY_STMT_NONE = 0,
- LY_STMT_NOTIFICATION, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_notif *`.
- The RPCs/Actions and Notifications are expected in a separated lists than the rest of
- data definition nodes as it is done in generic structures of libyang. */
- LY_STMT_INPUT,
- LY_STMT_OUTPUT,
- LY_STMT_ACTION, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_action *`.
- The RPCs/Actions and Notifications are expected in a separated lists than the rest of
- data definition nodes as it is done in generic structures of libyang. */
- LY_STMT_RPC, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_action *`.
- The RPCs/Actions and Notifications are expected in a separated lists than the rest of
- data definition nodes as it is done in generic structures of libyang. */
- LY_STMT_ANYDATA, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the anydata is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_ANYXML, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the anyxml is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_AUGMENT,
- LY_STMT_CASE, /**< TODO is it possible to compile cases without the parent choice? */
- LY_STMT_CHOICE, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the choice is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_CONTAINER, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the container is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_GROUPING,
- LY_STMT_LEAF, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the leaf is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_LEAF_LIST, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the leaf-list is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_LIST, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the list is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_USES,
+ LY_STMT_NOTIFICATION = 0x0001, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_notif *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_notif *` */
+ LY_STMT_INPUT = 0x0002, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_action_inout *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_action_inout *` */
+ LY_STMT_OUTPUT = 0x0004, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_action_inout *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_action_inout *` */
+ LY_STMT_ACTION = 0x0008, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_action *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_action *` */
+ LY_STMT_RPC = 0x0010, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_action *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_action *` */
+ LY_STMT_ANYDATA = 0x0020, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_anydata *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_anydata *` */
+ LY_STMT_ANYXML = 0x0040, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_anydata *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_anydata *` */
+ LY_STMT_AUGMENT = 0x0080, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_augment *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_node *` */
+ LY_STMT_CASE = 0x0100, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_case *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_case *` */
+ LY_STMT_CHOICE = 0x0200, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_choice *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_choice *` */
+ LY_STMT_CONTAINER = 0x0400, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_container *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_container *` */
+ LY_STMT_GROUPING = 0x0800, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_grp *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_node *` */
+ LY_STMT_LEAF = 0x1000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_leaf *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_leaf *` */
+ LY_STMT_LEAF_LIST = 0x2000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_leaflist *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_leaflist *` */
+ LY_STMT_LIST = 0x4000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_list *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node_list *` */
+ LY_STMT_USES = 0x8000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_node_uses *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_node *` */
- LY_STMT_ARGUMENT,
- LY_STMT_BASE,
- LY_STMT_BELONGS_TO,
- LY_STMT_BIT,
- LY_STMT_CONFIG, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
- LY_STMT_CONTACT,
- LY_STMT_DEFAULT,
- LY_STMT_DESCRIPTION, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
- LY_STMT_DEVIATE,
- LY_STMT_DEVIATION,
- LY_STMT_ENUM,
- LY_STMT_ERROR_APP_TAG,
- LY_STMT_ERROR_MESSAGE,
- LY_STMT_EXTENSION,
- LY_STMT_EXTENSION_INSTANCE,
- LY_STMT_FEATURE,
- LY_STMT_FRACTION_DIGITS,
- LY_STMT_IDENTITY,
- LY_STMT_IF_FEATURE, /**< if-feature statements are not compiled, they are evaluated and the parent statement is
- preserved only in case the evaluation of all the if-feature statements is true.
- Therefore there is no storage expected. */
- LY_STMT_IMPORT,
- LY_STMT_INCLUDE,
- LY_STMT_KEY,
- LY_STMT_LENGTH,
- LY_STMT_MANDATORY, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
- LY_STMT_MAX_ELEMENTS,
- LY_STMT_MIN_ELEMENTS,
- LY_STMT_MODIFIER,
- LY_STMT_MODULE,
- LY_STMT_MUST,
- LY_STMT_NAMESPACE,
- LY_STMT_ORDERED_BY,
- LY_STMT_ORGANIZATION,
- LY_STMT_PATH,
- LY_STMT_PATTERN,
- LY_STMT_POSITION,
- LY_STMT_PREFIX,
- LY_STMT_PRESENCE,
- LY_STMT_RANGE,
- LY_STMT_REFERENCE, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
- LY_STMT_REFINE,
- LY_STMT_REQUIRE_INSTANCE,
- LY_STMT_REVISION,
- LY_STMT_REVISION_DATE,
- LY_STMT_STATUS, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
- LY_STMT_SUBMODULE,
- LY_STMT_TYPE, /**< in ::lysc_ext_substmt.storage stored as a pointer to `struct lysc_type *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `struct lysc_type **` */
- LY_STMT_TYPEDEF,
- LY_STMT_UNIQUE,
- LY_STMT_UNITS, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
- LY_STMT_VALUE,
- LY_STMT_WHEN,
- LY_STMT_YANG_VERSION,
- LY_STMT_YIN_ELEMENT,
+ LY_STMT_ARGUMENT = 0x10000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_ext *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_ext *` */
+ LY_STMT_BASE = 0x20000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `const char **`[]
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_ident *` */
+ LY_STMT_BELONGS_TO = 0x30000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_submodule *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_BIT = 0x40000, /**< ::lysp_ext_substmt.storage - `struct lysp_type_enum *`[]
+ ::lysp_ext_instance.parent - `struct lysp_type_enum *`
+ ::lysc_ext_substmt.storage - `struct lysc_type_bitenum_item *`[]
+ ::lysc_ext_instance.parent - `struct lysc_type_bitenum_item *` */
+ LY_STMT_CONFIG = 0x50000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `uint16_t *`
+ ::lysc_ext_substmt.storage - `uint16_t *`
+ ::lysc_ext_instance.parent - `struct lysc_node *` */
+ LY_STMT_CONTACT = 0x60000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_(sub)module *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_DEFAULT = 0x70000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_qname *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_node *`, `struct lysc_type *` (typedef) */
+ LY_STMT_DESCRIPTION = 0x80000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `const char *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - compiled parent statement */
+ LY_STMT_DEVIATE = 0x90000, /**< ::lysp_ext_substmt.storage - `struct lysp_deviate *`[]
+ ::lysp_ext_instance.parent - `struct lysp_deviate *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - not compiled */
+ LY_STMT_DEVIATION = 0xA0000, /**< ::lysp_ext_substmt.storage - `struct lysp_deviation *`[]
+ ::lysp_ext_instance.parent - `struct lysp_deviation *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_node *` */
+ LY_STMT_ENUM = 0xB0000, /**< ::lysp_ext_substmt.storage - `struct lysp_type_enum *`[]
+ ::lysp_ext_instance.parent - `struct lysp_type_enum *`
+ ::lysc_ext_substmt.storage - `struct lysc_type_bitenum_item *`[]
+ ::lysc_ext_instance.parent - `struct lysc_type_bitenum_item *` */
+ LY_STMT_ERROR_APP_TAG = 0xC0000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_restr *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - compiled restriction structure */
+ LY_STMT_ERROR_MESSAGE = 0xD0000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_restr *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - compiled restriction structure */
+ LY_STMT_EXTENSION = 0xE0000, /**< ::lysp_ext_substmt.storage - `struct lysp_ext *`[]
+ ::lysp_ext_instance.parent - `struct lysp_ext *`
+ ::lysc_ext_substmt.storage - not compiled explicitly
+ ::lysc_ext_instance.parent - `struct lysc_ext *` */
+ LY_STMT_EXTENSION_INSTANCE = 0xF0000, /**< ::lysp_ext_substmt.storage - `struct lysp_ext_instance *`[]
+ ::lysc_ext_substmt.storage - `struct lysc_ext_instance *`[] */
+ LY_STMT_FEATURE = 0x100000, /**< ::lysp_ext_substmt.storage - `struct lysp_feature *`[]
+ ::lysp_ext_instance.parent - `struct lysp_feature *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - not compiled */
+ LY_STMT_FRACTION_DIGITS = 0x110000, /**< ::lysp_ext_substmt.storage - `uint8_t *`
+ ::lysp_ext_instance.parent - `struct lysp_type *`
+ ::lysc_ext_substmt.storage - `uint8_t *`
+ ::lysc_ext_instance.parent - `struct lysc_type *` */
+ LY_STMT_IDENTITY = 0x120000, /**< ::lysp_ext_substmt.storage - `struct lysp_ident *`[]
+ ::lysp_ext_instance.parent - `struct lysp_ident *`
+ ::lysc_ext_substmt.storage - `struct lysc_ident *`[]
+ ::lysc_ext_instance.parent - `struct lysc_ident *` */
+ LY_STMT_IF_FEATURE = 0x130000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_qname *`[]
+ ::lysc_ext_substmt.storage - no storage, evaluated when compiled
+ ::lysc_ext_instance.parent - compiled parent statement */
+ LY_STMT_IMPORT = 0x140000, /**< ::lysp_ext_substmt.storage - `struct lysp_import *`[]
+ ::lysp_ext_instance.parent - `struct lysp_import *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - not compiled */
+ LY_STMT_INCLUDE = 0x150000, /**< ::lysp_ext_substmt.storage - `struct lysp_include *`[]
+ ::lysp_ext_instance.parent - `struct lysp_include *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - not compiled */
+ LY_STMT_KEY = 0x160000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_node_list *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_node_list *` */
+ LY_STMT_LENGTH = 0x170000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_restr *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_range *` */
+ LY_STMT_MANDATORY = 0x180000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `uint16_t *`
+ ::lysc_ext_substmt.storage - `uint16_t *`
+ ::lysc_ext_instance.parent - `struct lysc_node *` */
+ LY_STMT_MAX_ELEMENTS = 0x190000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `uint32_t *`
+ ::lysc_ext_substmt.storage - `uint32_t *`
+ ::lysc_ext_instance.parent - `struct lysc_node_list *` */
+ LY_STMT_MIN_ELEMENTS = 0x1A0000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `uint32_t *`
+ ::lysc_ext_substmt.storage - `uint32_t *`
+ ::lysc_ext_instance.parent - `struct lysc_node_list *` */
+ LY_STMT_MODIFIER = 0x1B0000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_restr *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_pattern *` */
+ LY_STMT_MODULE = 0x1C0000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_module *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_MUST = 0x1D0000, /**< ::lysp_ext_substmt.storage - `struct lysp_restr *`[]
+ ::lysp_ext_instance.parent - `struct lysp_restr *`
+ ::lysc_ext_substmt.storage - `struct lysc_must *`[]
+ ::lysc_ext_instance.parent - `struct lysc_must *` */
+ LY_STMT_NAMESPACE = 0x1E0000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_module *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_ORDERED_BY = 0x1F0000, /**< ::lysp_ext_substmt.storage - `uint16_t *`
+ ::lysp_ext_instance.parent - `struct lysp_node *`
+ ::lysc_ext_substmt.storage - `uint16_t *`
+ ::lysc_ext_instance.parent - `struct lysc_node *` */
+ LY_STMT_ORGANIZATION = 0x200000, /**< ::lysp_ext_substmt.storage - `const char *`
+ ::lysp_ext_instance.parent - `struct lysp_(sub)module *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_PATH = 0x210000, /**< ::lysp_ext_substmt.storage - `struct lyxp_expr *`
+ ::lysp_ext_instance.parent - `struct lysp_type *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_type *` */
+ LY_STMT_PATTERN = 0x220000, /**< ::lysp_ext_substmt.storage - `struct lysp_restr *`[]
+ ::lysp_ext_instance.parent - `struct lysp_restr *`
+ ::lysc_ext_substmt.storage - `struct lysc_pattern **`[]
+ ::lysc_ext_instance.parent - `struct lysc_pattern *` */
+ LY_STMT_POSITION = 0x230000, /**< ::lysp_ext_substmt.storage - `int64_t *`
+ ::lysp_ext_instance.parent - `struct lysp_type_enum *`
+ ::lysc_ext_substmt.storage - `int64_t *`
+ ::lysc_ext_instance.parent - `struct lysc_type_bitenum_item *` */
+ LY_STMT_PREFIX = 0x240000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `const char *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_PRESENCE = 0x250000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `const char *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_node_container *` */
+ LY_STMT_RANGE = 0x260000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_restr *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_range *` */
+ LY_STMT_REFERENCE = 0x270000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `const char *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - compiled parent statement */
+ LY_STMT_REFINE = 0x280000, /**< ::lysp_ext_substmt.storage - `struct lysp_refine *`[]
+ ::lysp_ext_instance.parent - `struct lysp_refine *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_node *` */
+ LY_STMT_REQUIRE_INSTANCE = 0x290000, /**< ::lysp_ext_substmt.storage - `uint8_t *`
+ ::lysp_ext_instance.parent - `struct lysp_type *`
+ ::lysc_ext_substmt.storage - `uint8_t *`
+ ::lysc_ext_instance.parent - `struct lysc_type *` */
+ LY_STMT_REVISION = 0x2A0000, /**< ::lysp_ext_substmt.storage - `struct lysp_revision *`[]
+ ::lysp_ext_instance.parent - `struct lysp_revision *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - not compiled */
+ LY_STMT_REVISION_DATE = 0x2B0000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `const char *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - not compiled */
+ LY_STMT_STATUS = 0x2C0000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `uint16_t *`
+ ::lysc_ext_substmt.storage - `uint16_t *`
+ ::lysc_ext_instance.parent - compiled parent statement */
+ LY_STMT_SUBMODULE = 0x2D0000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_submodule *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_TYPE = 0x2E0000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_type *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_type *` */
+ LY_STMT_TYPEDEF = 0x2F0000, /**< ::lysp_ext_substmt.storage - `struct lysp_tpdf *`[]
+ ::lysp_ext_instance.parent - `struct lysp_tpdf *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_type *` */
+ LY_STMT_UNIQUE = 0x300000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_qname *`[]
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_node_list *` */
+ LY_STMT_UNITS = 0x310000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `const char *`
+ ::lysc_ext_substmt.storage - `const char *`
+ ::lysc_ext_instance.parent - `struct lysc_node *`, `struct lysc_type *` (typedef) */
+ LY_STMT_VALUE = 0x320000, /**< ::lysp_ext_substmt.storage - `int64_t *`
+ ::lysp_ext_instance.parent - `struct lysp_type_enum *`
+ ::lysc_ext_substmt.storage - `int64_t *`
+ ::lysc_ext_instance.parent - `struct lysc_type_bitenum_item *` */
+ LY_STMT_WHEN = 0x330000, /**< ::lysp_ext_substmt.storage and ::lysp_ext_instance.parent - `struct lysp_when *`
+ ::lysc_ext_substmt.storage and ::lysc_ext_instance.parent - `struct lysc_when *` */
+ LY_STMT_YANG_VERSION = 0x340000, /**< ::lysp_ext_substmt.storage - `uint8_t *`
+ ::lysp_ext_instance.parent - `struct lysp_(sub)module *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_module *` */
+ LY_STMT_YIN_ELEMENT = 0x350000, /**< ::lysp_ext_substmt.storage - `uint16_t *`
+ ::lysp_ext_instance.parent - `struct lysp_ext *`
+ ::lysc_ext_substmt.storage - not compiled
+ ::lysc_ext_instance.parent - `struct lysc_ext *` */
/* separated from the list of statements
* the following tokens are part of the syntax and parsers have to work
@@ -287,57 +381,65 @@
};
/**
- * @brief YANG extension instance
+ * @brief Structure representing a parsed known YANG substatement in an extension instance.
+ */
+struct lysp_ext_substmt {
+ enum ly_stmt stmt; /**< parsed substatement */
+ void *storage; /**< pointer to the parsed storage of the statement according to the specific
+ lys_ext_substmt::stmt */
+};
+
+/**
+ * @brief YANG extension parsed instance.
*/
struct lysp_ext_instance {
const char *name; /**< extension identifier, including possible prefix */
const char *argument; /**< optional value of the extension's argument */
LY_VALUE_FORMAT format; /**< prefix format of the extension name/argument (::LY_VALUE_XML is YIN format) */
- struct lysp_node *parsed; /**< Simply parsed (unresolved) YANG schema tree serving as a cache.
- Only ::lys_compile_extension_instance() can set this. */
- void *prefix_data; /**< Format-specific data for prefix resolution
- (see ly_resolve_prefix()) */
+ void *prefix_data; /**< format-specific data for prefix resolution (see ly_resolve_prefix()) */
+ struct lysp_ext *def; /**< pointer to the extension definition */
- struct lysp_stmt *child; /**< list of the extension's substatements (linked list) */
+ void *parent; /**< pointer to the parent statement holding the extension instance(s), use
+ ::lysp_ext_instance#parent_stmt to access the value/structure */
+ enum ly_stmt parent_stmt; /**< type of the parent statement */
+ LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< index of the stamenet in case the parent does not point to the parent
+ statement directly and it is an array */
+ uint16_t flags; /**< ::LYS_INTERNAL value (@ref snodeflags) */
- void *parent; /**< pointer to the parent element holding the extension instance(s), use
- ::lysp_ext_instance#parent_stmt to access the schema element */
- enum ly_stmt parent_stmt; /**< value identifying placement of the extension instance */
- LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< in case the instance is in a substatement, this identifies
- the index of that substatement in its [sized array](@ref sizedarrays) (if any) */
- uint16_t flags; /**< LYS_INTERNAL value (@ref snodeflags) */
- const struct lyplg_ext_record *record; /**< extension defintion plugin record, if any */
+ const struct lyplg_ext_record *record; /**< extension definition plugin record, if any */
+ struct lysp_ext_substmt *substmts; /**< list of supported known YANG statements with the pointer to their
+ parsed data ([sized array](@ref sizedarrays)) */
+ void *parsed; /**< private plugin parsed data */
+ struct lysp_stmt *child; /**< list of generic (unknown) YANG statements */
};
/**
- * @brief Description of the extension instance substatements.
- *
- * Provided by extensions plugins to libyang to be able to correctly compile the content of extension instances.
- * Note that order of the defined records matters - just follow the values of ::ly_stmt and order the records from lower to higher values.
+ * @brief Structure representing a compiled known YANG substatement in an extension instance.
*/
struct lysc_ext_substmt {
- enum ly_stmt stmt; /**< allowed substatement */
- void *storage; /**< pointer to the storage of the compiled statement according to the specific
- lysc_ext_substmt::stmt */
+ enum ly_stmt stmt; /**< compiled substatement */
+ void *storage; /**< pointer to the compiled storage of the statement according to the specific
+ lys_ext_substmt::stmt */
};
/**
- * @brief YANG extension instance
+ * @brief YANG extension compiled instance.
*/
struct lysc_ext_instance {
- struct lysc_ext *def; /**< pointer to the extension definition */
- const char *argument; /**< optional value of the extension's argument */
- struct lys_module *module; /**< module where the extension instantiated is defined */
- struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
- struct lysc_ext_substmt *substmts; /**< list of allowed substatements with the storage to access the present
- substatements ([sized array](@ref sizedarrays)) */
- void *data; /**< private plugins's data, not used by libyang */
+ struct lysc_ext *def; /**< pointer to the extension definition */
+ const char *argument; /**< optional value of the extension's argument */
+ struct lys_module *module; /**< module where the extension instantiated is defined */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
- void *parent; /**< pointer to the parent element holding the extension instance(s), use
- ::lysc_ext_instance#parent_stmt to access the schema element */
- enum ly_stmt parent_stmt; /**< value identifying placement of the extension instance in specific statement */
- LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< in case the instance is in a substatement, this identifies
- the index of that substatement in its [sized array](@ref sizedarrays) (if any) */
+ void *parent; /**< pointer to the parent element holding the extension instance(s), use
+ ::lysc_ext_instance#parent_stmt to access the value/structure */
+ enum ly_stmt parent_stmt; /**< type of the parent statement */
+ LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< index of the stamenet in case the parent does not point to the parent
+ statement directly and it is an array */
+
+ struct lysc_ext_substmt *substmts; /**< list of supported known YANG statements with the pointer to their
+ compiled data ([sized array](@ref sizedarrays)) */
+ void *compiled; /**< private plugin compiled data */
};
/**
@@ -350,7 +452,84 @@
uint32_t plugins_extensions_apiver__ = LYPLG_EXT_API_VERSION; \
const struct lyplg_ext_record plugins_extensions__[]
-typedef LY_ERR (*lyplg_ext_parse_clb)(struct lysp_ctx *pctx, struct lysp_ext_instance *p_ext);
+/*
+ * parse
+ */
+
+/**
+ * @brief Callback for parsing extension instance substatements.
+ *
+ * All known YANG substatements can easily be parsed using ::lys_parse_extension_instance.
+ *
+ * @param[in] pctx Parse context.
+ * @param[in,out] ext Parsed extension instance data.
+ * @return LY_SUCCESS on success.
+ * @return LY_ENOT if the extension instance is not supported and should be removed.
+ * @return LY_ERR error on error.
+ */
+typedef LY_ERR (*lyplg_ext_parse_clb)(struct lysp_ctx *pctx, struct lysp_ext_instance *ext);
+
+/**
+ * @brief Log a message from an extension plugin using the parsed extension instance.
+ *
+ * @param[in] pctx Parse context to use.
+ * @param[in] ext Parsed extensiopn instance.
+ * @param[in] level Log message level (error, warning, etc.)
+ * @param[in] err_no Error type code.
+ * @param[in] format Format string to print.
+ * @param[in] ... Format variable parameters.
+ */
+LIBYANG_API_DECL void lyplg_ext_parse_log(const struct lysp_ctx *pctx, const struct lysp_ext_instance *ext,
+ LY_LOG_LEVEL level, LY_ERR err_no, const char *format, ...);
+
+/**
+ * @brief Get current parsed module from a parse context.
+ *
+ * @param[in] pctx Parse context.
+ * @return Current (local) parse mod.
+ */
+LIBYANG_API_DECL const struct lysp_module *lyplg_ext_parse_get_cur_pmod(const struct lysp_ctx *pctx);
+
+/**
+ * @brief Parse substatements of an extension instance.
+ *
+ * Uses standard libyang schema compiler to transform YANG statements into the parsed schema structures. The plugins are
+ * supposed to use this function when the extension instance's substatements can be parsed in a standard way.
+ *
+ * @param[in] pctx Parse context.
+ * @param[in,out] ext Parsed extension instance with the prepared ::lysp_ext_instance.substmts array, which will be
+ * updated by storing the parsed data.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERR error on error.
+ */
+LIBYANG_API_DECL LY_ERR lyplg_ext_parse_extension_instance(struct lysp_ctx *pctx, struct lysp_ext_instance *ext);
+
+/*
+ * compile
+ */
+
+/**
+ * @defgroup scflags Schema compile flags
+ *
+ * Flags to modify schema compilation process and change the way how the particular statements are being compiled. *
+ * @{
+ */
+#define LYS_COMPILE_GROUPING 0x01 /**< Compiling (validation) of a non-instantiated grouping.
+ In this case not all the restrictions are checked since they can
+ be valid only in the real placement of the grouping. This is
+ the case of any restriction that needs to look out of the statements
+ themselves, since the context is not known. */
+#define LYS_COMPILE_DISABLED 0x02 /**< Compiling a disabled subtree (by its if-features). Meaning
+ it will be removed at the end of compilation and should not be
+ added to any unres sets. */
+#define LYS_COMPILE_NO_CONFIG 0x04 /**< ignore config statements, neither inherit config value */
+#define LYS_COMPILE_NO_DISABLED 0x08 /**< ignore if-feature statements */
+
+#define LYS_COMPILE_RPC_INPUT (LYS_IS_INPUT | LYS_COMPILE_NO_CONFIG) /**< Internal option when compiling schema tree of RPC/action input */
+#define LYS_COMPILE_RPC_OUTPUT (LYS_IS_OUTPUT | LYS_COMPILE_NO_CONFIG) /**< Internal option when compiling schema tree of RPC/action output */
+#define LYS_COMPILE_NOTIFICATION (LYS_IS_NOTIF | LYS_COMPILE_NO_CONFIG) /**< Internal option when compiling schema tree of Notification */
+
+/** @} scflags */
/**
* @brief Callback to compile extension from the lysp_ext_instance to the lysc_ext_instance. The later structure is generally prepared
@@ -360,15 +539,141 @@
* function can be used to let the compilation to libyang following the standard rules for processing the YANG statements.
*
* @param[in] cctx Current compile context.
- * @param[in] p_ext Parsed extension instance data.
- * @param[in,out] c_ext Prepared compiled extension instance structure where an addition, extension-specific, data are
+ * @param[in] extp Parsed extension instance data.
+ * @param[in,out] ext Prepared compiled extension instance structure where an addition, extension-specific, data are
* supposed to be placed for later use (data validation or use of external tool).
* @return LY_SUCCESS in case of success.
- * @return LY_EVALID in case of non-conforming parsed data.
* @return LY_ENOT in case the extension instance is not supported and should be removed.
+ * @return LY_ERR error on error.
*/
-typedef LY_ERR (*lyplg_ext_compile_clb)(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext,
- struct lysc_ext_instance *c_ext);
+typedef LY_ERR (*lyplg_ext_compile_clb)(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp,
+ struct lysc_ext_instance *ext);
+
+/**
+ * @brief Log a message from an extension plugin using the compiled extension instance.
+ *
+ * @param[in] cctx Optional compile context to generate the path from.
+ * @param[in] ext Compiled extension instance.
+ * @param[in] level Log message level (error, warning, etc.)
+ * @param[in] err_no Error type code.
+ * @param[in] format Format string to print.
+ */
+LIBYANG_API_DECL void lyplg_ext_compile_log(const struct lysc_ctx *cctx, const struct lysc_ext_instance *ext,
+ LY_LOG_LEVEL level, LY_ERR err_no, const char *format, ...);
+
+/**
+ * @brief Log a message from an extension plugin using the compiled extension instance with an explicit error path.
+ *
+ * @param[in] path Log error path to use.
+ * @param[in] ext Compiled extension instance.
+ * @param[in] level Log message level (error, warning, etc.)
+ * @param[in] err_no Error type code.
+ * @param[in] format Format string to print.
+ */
+LIBYANG_API_DECL void lyplg_ext_compile_log_path(const char *path, const struct lysc_ext_instance *ext,
+ LY_LOG_LEVEL level, LY_ERR err_no, const char *format, ...);
+
+/**
+ * @brief YANG schema compilation context getter for libyang context.
+ *
+ * @param[in] ctx YANG schema compilation context.
+ * @return libyang context connected with the compilation context.
+ */
+LIBYANG_API_DECL struct ly_ctx *lyplg_ext_compile_get_ctx(const struct lysc_ctx *ctx);
+
+/**
+ * @brief YANG schema compilation context getter for compilation options.
+ *
+ * @param[in] ctx YANG schema compilation context.
+ * @return pointer to the compilation options to allow modifying them with @ref scflags values.
+ */
+LIBYANG_API_DECL uint32_t *lyplg_ext_compile_get_options(const struct lysc_ctx *ctx);
+
+/**
+ * @brief YANG schema compilation context getter for current module.
+ *
+ * @param[in] ctx YANG schema compilation context.
+ * @return current module.
+ */
+LIBYANG_API_DECL const struct lys_module *lyplg_ext_compile_get_cur_mod(const struct lysc_ctx *ctx);
+
+/**
+ * @brief YANG schema compilation context getter for currently processed module.
+ *
+ * @param[in] ctx YANG schema compilation context.
+ * @return Currently processed module.
+ */
+LIBYANG_API_DECL struct lysp_module *lyplg_ext_compile_get_pmod(const struct lysc_ctx *ctx);
+
+/**
+ * @brief Compile substatements of an extension instance.
+ *
+ * Uses standard libyang schema compiler to transform YANG statements into the compiled schema structures. The plugins are
+ * supposed to use this function when the extension instance's substatements are supposed to be compiled in a standard way
+ * (or if just the @ref scflags are enough to modify the compilation process).
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] extp Parsed representation of the extension instance being processed.
+ * @param[in,out] ext Compiled extension instance with the prepared ::lysc_ext_instance.substmts array, which will be updated
+ * by storing the compiled data.
+ * @return LY_SUCCESS on success.
+ * @return LY_EVALID if compilation of the substatements fails.
+ * @return LY_ENOT if the extension is disabled (by if-feature) and should be ignored.
+ */
+LIBYANG_API_DECL LY_ERR lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *extp,
+ struct lysc_ext_instance *ext);
+
+/**
+ * @brief Compile substatements of an extension instance but append all schema data nodes as augments.
+ *
+ * Similar to ::lys_compile_extension_instance().
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] extp Parsed representation of the extension instance being processed.
+ * @param[in,out] ext Compiled extension instance with the prepared ::lysc_ext_instance.substmts array, which will be updated
+ * by storing the compiled data except for schema data nodes.
+ * @param[in] aug_target Augment target node to append schema data nodes.
+ * @return LY_SUCCESS on success.
+ * @return LY_EVALID if compilation of the substatements fails.
+ * @return LY_ENOT if the extension is disabled (by if-feature) and should be ignored.
+ */
+LIBYANG_API_DECL LY_ERR lyplg_ext_compile_extension_instance_augment(struct lysc_ctx *ctx,
+ const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext, struct lysc_node *aug_target);
+
+/**
+ * @brief Find augment target in an extension.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] path Absolute-schema-nodeid representing the augment target. The first segment is expected to identify
+ * the specific extension instance.
+ * @param[out] aug_ext Optional augment target extension.
+ * @param[out] aug_target Augment target compiled schema node.
+ * @return LY_ERR value.
+ */
+LIBYANG_API_DECL LY_ERR lys_compile_extension_instance_find_augment_target(struct lysc_ctx *ctx, const char *path,
+ struct lysc_ext_instance **aug_ext, struct lysc_node **aug_target);
+
+/**
+ * @brief Update path in the compile context, which is used for logging where the compilation failed.
+ *
+ * @param[in] ctx Compile context with the path.
+ * @param[in] parent_module Module of the current node's parent to check difference with the currently processed module (taken from @p ctx).
+ * @param[in] name Name of the node to update path with. If NULL, the last segment is removed. If the format is `{keyword}`, the following
+ * call updates the segment to the form `{keyword='name'}` (to remove this compound segment, 2 calls with NULL @p name must be used).
+ */
+LIBYANG_API_DECL void lysc_update_path(struct lysc_ctx *ctx, struct lys_module *parent_module, const char *name);
+
+/**
+ * @brief Duplicate the compiled extension (definition) structure.
+ *
+ * @param[in] orig The extension structure to duplicate.
+ * @return The duplicated structure to use.
+ */
+LIBYANG_API_DECL struct lysc_ext *lysc_ext_dup(struct lysc_ext *orig);
+
+/*
+ * printer
+ */
/**
* @brief Callback to print the compiled extension instance's private data in the INFO format.
@@ -382,12 +687,46 @@
typedef LY_ERR (*lyplg_ext_schema_printer_clb)(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag);
/**
- * @brief Callback to free the extension-specific data created by its compilation.
+ * @brief YANG printer context getter for output handler.
*
- * @param[in] ctx libyang context.
- * @param[in,out] ext Compiled extension structure where the data to free are placed.
+ * @param[in] ctx YANG printer context.
+ * @return Output handler where the data are being printed. Note that the address of the handler pointer in the context is
+ * returned to allow to modify the handler.
*/
-typedef void (*lyplg_ext_free_clb)(struct ly_ctx *ctx, struct lysc_ext_instance *ext);
+LIBYANG_API_DECL struct ly_out **lyplg_ext_print_get_out(const struct lyspr_ctx *ctx);
+
+/**
+ * @brief YANG printer context getter for printer options.
+ *
+ * @param[in] ctx YANG printer context.
+ * @return pointer to the printer options to allow modifying them with @ref schemaprinterflags values.
+ */
+LIBYANG_API_DECL uint32_t *lyplg_ext_print_get_options(const struct lyspr_ctx *ctx);
+
+/**
+ * @brief YANG printer context getter for printer indentation level.
+ *
+ * @param[in] ctx YANG printer context.
+ * @return pointer to the printer's indentation level to allow modifying its value.
+ */
+LIBYANG_API_DECL uint16_t *lyplg_ext_print_get_level(const struct lyspr_ctx *ctx);
+
+/**
+ * @brief Print substatements of an extension instance
+ *
+ * Generic function to access YANG printer functions from the extension plugins (::lyplg_ext_schema_printer_clb).
+ *
+ * @param[in] ctx YANG printer context to provide output handler and other information for printing.
+ * @param[in] ext The compiled extension instance to access the extensions and substatements data.
+ * @param[in,out] flag Flag to be shared with the caller regarding the opening brackets - 0 if the '{' not yet printed,
+ * 1 otherwise.
+ */
+LIBYANG_API_DECL void lyplg_ext_print_extension_instance(struct lyspr_ctx *ctx, const struct lysc_ext_instance *ext,
+ ly_bool *flag);
+
+/*
+ * data node
+ */
/**
* @brief Callback called for all data nodes connected to the extension instance.
@@ -403,6 +742,10 @@
*/
typedef LY_ERR (*lyplg_ext_data_node_clb)(struct lysc_ext_instance *ext, struct lyd_node *node, uint32_t validate_options);
+/*
+ * snode
+ */
+
/**
* @brief Callback for getting a schema node for a new YANG instance data described by an extension instance.
* Needed only if the extension instance supports some nested standard YANG data.
@@ -425,6 +768,10 @@
const struct lysc_node *sparent, const char *prefix, size_t prefix_len, LY_VALUE_FORMAT format, void *prefix_data,
const char *name, size_t name_len, const struct lysc_node **snode);
+/*
+ * validate
+ */
+
/**
* @brief Callback for validating parsed YANG instance data described by an extension instance.
*
@@ -443,6 +790,46 @@
typedef LY_ERR (*lyplg_ext_data_validate_clb)(struct lysc_ext_instance *ext, struct lyd_node *sibling,
const struct lyd_node *dep_tree, enum lyd_type data_type, uint32_t val_opts, struct lyd_node **diff);
+/*
+ * parse free
+ */
+
+/**
+ * @brief Callback to free the extension-specific data created by its parsing.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in,out] ext Parsed extension structure to free.
+ */
+typedef void (*lyplg_ext_parse_free_clb)(const struct ly_ctx *ctx, struct lysp_ext_instance *ext);
+
+/**
+ * @brief Free the extension instance's data parsed with ::lys_parse_extension_instance().
+ *
+ * @param[in] ctx libyang context
+ * @param[in] substmts Extension instance substatements to free.
+ */
+LIBYANG_API_DECL void lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext_substmt *substmts);
+
+/*
+ * compile free
+ */
+
+/**
+ * @brief Callback to free the extension-specific data created by its compilation.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in,out] ext Compiled extension structure to free.
+ */
+typedef void (*lyplg_ext_compile_free_clb)(const struct ly_ctx *ctx, struct lysc_ext_instance *ext);
+
+/**
+ * @brief Free the extension instance's data compiled with ::lys_compile_extension_instance().
+ *
+ * @param[in] ctx libyang context
+ * @param[in] substmts Extension instance substatements to free.
+ */
+LIBYANG_API_DECL void lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext_substmt *substmts);
+
/**
* @brief Extension plugin implementing various aspects of a YANG extension
*/
@@ -453,13 +840,15 @@
lyplg_ext_compile_clb compile; /**< callback to compile extension instance from the parsed data */
lyplg_ext_schema_printer_clb sprinter; /**< callback to print the compiled content (info format) of the extension
instance */
- lyplg_ext_free_clb free; /**< free the extension-specific data created by its compilation */
lyplg_ext_data_node_clb node; /**< callback to validate most relevant data instance for the extension
instance */
lyplg_ext_data_snode_clb snode; /**< callback to get schema node for nested YANG data */
lyplg_ext_data_validate_clb validate; /**< callback to validate parsed data instances according to the extension
definition */
+
+ lyplg_ext_parse_free_clb pfree; /**< free the extension-specific data created by its parsing */
+ lyplg_ext_compile_free_clb cfree; /**< free the extension-specific data created by its compilation */
};
struct lyplg_ext_record {
@@ -482,7 +871,7 @@
* @param[in] stmt The statement identifier to stringify.
* @return Constant string representation of the given @p stmt.
*/
-LIBYANG_API_DECL const char *ly_stmt2str(enum ly_stmt stmt);
+LIBYANG_API_DECL const char *lyplg_ext_stmt2str(enum ly_stmt stmt);
/**
* @brief Convert nodetype to statement identifier
@@ -490,16 +879,31 @@
* @param[in] nodetype Nodetype to convert.
* @return Statement identifier representing the given @p nodetype.
*/
-LIBYANG_API_DECL enum ly_stmt lys_nodetype2stmt(uint16_t nodetype);
+LIBYANG_API_DECL enum ly_stmt lyplg_ext_nodetype2stmt(uint16_t nodetype);
/**
- * @brief Free the extension instance's data compiled with ::lys_compile_extension_instance().
+ * @brief Get compiled ext instance storage for a specific statement.
*
- * @param[in] ctx libyang context
- * @param[in] substmts The sized array of extension instance's substatements. The whole array is freed except the storage
- * places which are expected to be covered by the extension plugin.
+ * @param[in] ext Compiled ext instance.
+ * @param[in] stmt Compiled statement. Can be a mask when the first match is returned, it is expected the storage is
+ * the same for all the masked statements.
+ * @param[out] storage Compiled ext instance substatement storage, NULL if was not compiled.
+ * @return LY_SUCCESS on success.
+ * @return LY_ENOT if the substatement is not supported.
*/
-LIBYANG_API_DECL void lyplg_ext_instance_substatements_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts);
+LIBYANG_API_DECL LY_ERR lyplg_ext_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage);
+
+/**
+ * @brief Get parsed ext instance storage for a specific statement.
+ *
+ * @param[in] ext Compiled ext instance.
+ * @param[in] stmt Parsed statement. Can be a mask when the first match is returned, it is expected the storage is
+ * the same for all the masked statements.
+ * @param[out] storage Parsed ext instance substatement storage, NULL if was not parsed.
+ * @return LY_SUCCESS on success.
+ * @return LY_ENOT if the substatement is not supported.
+ */
+LIBYANG_API_DECL LY_ERR lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage);
/**
* @brief Get specific run-time extension instance data from a callback set by ::ly_ctx_set_ext_data_clb().
@@ -522,33 +926,20 @@
* @return LY_SUCCESS on success.
* @return LY_ERR error on error.
*/
-LIBYANG_API_DECL LY_ERR lyd_insert_ext(struct lyd_node *parent, struct lyd_node *first);
-
-/**
- * @brief Provide a log message from an extension plugin.
- *
- * @param[in] ext Compiled extension structure providing generic information about the extension/plugin causing the message.
- * @param[in] level Log message level (error, warning, etc.)
- * @param[in] err_no Error type code.
- * @param[in] path Path relevant to the message.
- * @param[in] format Format string to print.
- */
-LIBYANG_API_DECL void lyplg_ext_log(const struct lysc_ext_instance *ext, LY_LOG_LEVEL level, LY_ERR err_no, const char *path,
- const char *format, ...);
+LIBYANG_API_DECL LY_ERR lyplg_ext_insert(struct lyd_node *parent, struct lyd_node *first);
/**
* @brief Expand parent-reference xpath expressions
*
- * @param ext[in] context allocated for extension
- * @param refs[out] set of lysc nodes matching parent-refernce xpaths
+ * @param[in] ext Context allocated for extension.
+ * @param[out] refs Set of schema node matching parent-reference XPaths.
* @return LY_ERR value.
*/
LIBYANG_API_DECL LY_ERR lyplg_ext_schema_mount_get_parent_ref(const struct lysc_ext_instance *ext, struct ly_set **refs);
/**
- * @brief Allocate a new context for a particular instance of the
- * yangmnt:mount-point extension. Caller is responsible for destroying
- * the resulting context.
+ * @brief Allocate a new context for a particular instance of the yangmnt:mount-point extension.
+ * Caller is responsible for destroying the resulting context.
*
* @param[in] ext Compiled extension instance.
* @param[out] ctx A context with modules loaded from the list found in
@@ -557,22 +948,6 @@
*/
LIBYANG_API_DECL LY_ERR lyplg_ext_schema_mount_create_context(const struct lysc_ext_instance *ext, struct ly_ctx **ctx);
-/**
- * @brief Get pointer to the storage of the specified substatement in the given extension instance.
- *
- * The function simplifies access into the ::lysc_ext_instance.substmts sized array.
- *
- * @param[in] ext Compiled extension instance to process.
- * @param[in] substmt Extension substatement to search for.
- * @param[out] instance_p Pointer where the storage of the @p substmt will be provided. The specific type returned depends
- * on the @p substmt and can be found in the documentation of each ::ly_stmt value. Also note that some of the substatements
- * (::lysc_node based or flags) can share the storage with other substatements. In case the pointer is NULL, still the return
- * code can be used to at least know if the substatement is allowed for the extension.
- * @return LY_SUCCESS if the @p substmt found.
- * @return LY_ENOT in case the @p ext is not able to store (does not allow) the specified @p substmt.
- */
-LIBYANG_API_DECL LY_ERR lysc_ext_substmt(const struct lysc_ext_instance *ext, enum ly_stmt substmt, void **instance_p);
-
/** @} pluginsExtensions */
#ifdef __cplusplus
diff --git a/src/plugins_exts/metadata.c b/src/plugins_exts/metadata.c
index f6e1580..fc49e2c 100644
--- a/src/plugins_exts/metadata.c
+++ b/src/plugins_exts/metadata.c
@@ -1,9 +1,10 @@
/**
* @file metadata.c
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief libyang extension plugin - Metadata (RFC 7952)
*
- * Copyright (c) 2019 CESNET, z.s.p.o.
+ * Copyright (c) 2019 - 2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -21,93 +22,150 @@
#include "libyang.h"
#include "plugins_exts.h"
-/**
- * @brief Representation of the compiled metadata substatements - simplify storage for the items available via
- * ::lysc_ext_substmt.
- */
-struct lyext_metadata {
- struct lysc_type *type; /**< type of the metadata (mandatory) */
+struct lysp_ext_metadata {
+ struct lysp_type *type; /**< type of the metadata (mandatory) */
const char *units; /**< units of the leaf's type */
- struct lysc_iffeature *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
+ struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
const char *dsc; /**< description */
const char *ref; /**< reference */
uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values are allowed */
};
+struct lysc_ext_metadata {
+ struct lysc_type *type; /**< type of the metadata (mandatory) */
+ const char *units; /**< units of the leaf's type */
+ const char *dsc; /**< description */
+ const char *ref; /**< reference */
+ uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values are allowed */
+};
+
+/**
+ * @brief Parse annotation extension instances.
+ *
+ * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
+ */
+static LY_ERR
+annotation_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
+{
+ LY_ERR r;
+ struct lysp_ext_metadata *ann_pdata;
+ struct lysp_module *pmod;
+ LY_ARRAY_COUNT_TYPE u;
+
+ /* annotations can appear only at the top level of a YANG module or submodule */
+ if ((ext->parent_stmt != LY_STMT_MODULE) && (ext->parent_stmt != LY_STMT_SUBMODULE)) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s is allowed only at the top level of a YANG module or "
+ "submodule, but it is placed in \"%s\" statement.", ext->name, lyplg_ext_stmt2str(ext->parent_stmt));
+ return LY_EVALID;
+ }
+
+ pmod = ext->parent;
+
+ /* check for duplication */
+ LY_ARRAY_FOR(pmod->exts, u) {
+ if ((&pmod->exts[u] != ext) && (pmod->exts[u].name == ext->name) && !strcmp(pmod->exts[u].argument, ext->argument)) {
+ /* duplication of the same annotation extension in a single module */
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s is instantiated multiple times.", ext->name);
+ return LY_EVALID;
+ }
+ }
+
+ /* parse annotation substatements */
+ ext->parsed = ann_pdata = calloc(1, sizeof *ann_pdata);
+ if (!ann_pdata) {
+ goto emem;
+ }
+ LY_ARRAY_CREATE_GOTO(lyplg_extp_cur_pmod(pctx)->mod->ctx, ext->substmts, 6, r, emem);
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_IF_FEATURE;
+ ext->substmts[0].storage = &ann_pdata->iffeatures;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_UNITS;
+ ext->substmts[1].storage = &ann_pdata->units;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_STATUS;
+ ext->substmts[2].storage = &ann_pdata->flags;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[3].stmt = LY_STMT_TYPE;
+ ext->substmts[3].storage = &ann_pdata->type;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[4].stmt = LY_STMT_DESCRIPTION;
+ ext->substmts[4].storage = &ann_pdata->dsc;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[5].stmt = LY_STMT_REFERENCE;
+ ext->substmts[5].storage = &ann_pdata->ref;
+
+ if ((r = lyplg_ext_parse_extension_instance(pctx, ext))) {
+ return r;
+ }
+
+ /* check for mandatory substatements */
+ if (!ann_pdata->type) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Missing mandatory keyword \"type\" as a child of \"%s %s\".",
+ ext->name, ext->argument);
+ return LY_EVALID;
+ }
+
+ return LY_SUCCESS;
+
+emem:
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
+ return LY_EMEM;
+}
+
/**
* @brief Compile annotation extension instances.
*
* Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
*/
static LY_ERR
-annotation_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
+annotation_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext)
{
LY_ERR ret;
- struct lyext_metadata *annotation;
- struct lysc_module *mod_c;
- LY_ARRAY_COUNT_TYPE u;
-
- /* annotations can appear only at the top level of a YANG module or submodule */
- if ((c_ext->parent_stmt != LY_STMT_MODULE) && (c_ext->parent_stmt != LY_STMT_SUBMODULE)) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension %s is allowed only at the top level of a YANG module or submodule, but it is placed in \"%s\" statement.",
- p_ext->name, ly_stmt2str(c_ext->parent_stmt));
- return LY_EVALID;
- }
- /* check mandatory argument */
- if (!c_ext->argument) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension %s is instantiated without mandatory argument representing metadata name.", p_ext->name);
- return LY_EVALID;
- }
-
- mod_c = (struct lysc_module *)c_ext->parent;
-
- /* check for duplication */
- LY_ARRAY_FOR(mod_c->exts, u) {
- if ((&mod_c->exts[u] != c_ext) && (mod_c->exts[u].def == c_ext->def) && !strcmp(mod_c->exts[u].argument, c_ext->argument)) {
- /* duplication of the same annotation extension in a single module */
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx), "Extension %s is instantiated multiple times.", p_ext->name);
- return LY_EVALID;
- }
- }
+ struct lysc_ext_metadata *ann_cdata;
/* compile annotation substatements */
- c_ext->data = annotation = calloc(1, sizeof *annotation);
- if (!annotation) {
+ ext->compiled = ann_cdata = calloc(1, sizeof *ann_cdata);
+ if (!ann_cdata) {
goto emem;
}
- LY_ARRAY_CREATE_GOTO(lysc_ctx_get_ctx(cctx), c_ext->substmts, 6, ret, emem);
+ LY_ARRAY_CREATE_GOTO(lysc_ctx_get_ctx(cctx), ext->substmts, 6, ret, emem);
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[ANNOTATION_SUBSTMT_IFF].stmt = LY_STMT_IF_FEATURE;
- c_ext->substmts[ANNOTATION_SUBSTMT_IFF].storage = &annotation->iffeatures;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_IF_FEATURE;
+ ext->substmts[0].storage = NULL;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[ANNOTATION_SUBSTMT_UNITS].stmt = LY_STMT_UNITS;
- c_ext->substmts[ANNOTATION_SUBSTMT_UNITS].storage = &annotation->units;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_UNITS;
+ ext->substmts[1].storage = &ann_cdata->units;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[ANNOTATION_SUBSTMT_STATUS].stmt = LY_STMT_STATUS;
- c_ext->substmts[ANNOTATION_SUBSTMT_STATUS].storage = &annotation->flags;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_STATUS;
+ ext->substmts[2].storage = &ann_cdata->flags;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[ANNOTATION_SUBSTMT_TYPE].stmt = LY_STMT_TYPE;
- c_ext->substmts[ANNOTATION_SUBSTMT_TYPE].storage = &annotation->type;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[3].stmt = LY_STMT_TYPE;
+ ext->substmts[3].storage = &ann_cdata->type;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[ANNOTATION_SUBSTMT_DSC].stmt = LY_STMT_DESCRIPTION;
- c_ext->substmts[ANNOTATION_SUBSTMT_DSC].storage = &annotation->dsc;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[4].stmt = LY_STMT_DESCRIPTION;
+ ext->substmts[4].storage = &ann_cdata->dsc;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[ANNOTATION_SUBSTMT_REF].stmt = LY_STMT_REFERENCE;
- c_ext->substmts[ANNOTATION_SUBSTMT_REF].storage = &annotation->ref;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[5].stmt = LY_STMT_REFERENCE;
+ ext->substmts[5].storage = &ann_cdata->ref;
- ret = lys_compile_extension_instance(cctx, p_ext, c_ext);
+ ret = lyplg_ext_compile_extension_instance(cctx, extp, ext);
return ret;
emem:
- lyplg_ext_log(c_ext, LY_LLERR, LY_EMEM, lysc_ctx_get_path(cctx), "Memory allocation failed (%s()).", __func__);
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
return LY_EMEM;
}
@@ -117,27 +175,43 @@
* Implementation of ::lyplg_ext_schema_printer_clb set as ::lyext_plugin::sprinter
*/
static LY_ERR
-annotation_schema_printer(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag)
+annotation_sprinter(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag)
{
- lysc_print_extension_instance(ctx, ext, flag);
+ lyplg_ext_print_extension_instance(ctx, ext, flag);
return LY_SUCCESS;
}
/**
- * @brief Free annotation extension instances' data.
+ * @brief Free parsed annotation extension instance data.
*
- * Implementation of ::lyplg_ext_free_clb callback set as ::lyext_plugin::free.
+ * Implementation of ::lyplg_ext_parse_free_clb callback set as ::lyext_plugin::pfree.
*/
static void
-annotation_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
+annotation_pfree(const struct ly_ctx *ctx, struct lysp_ext_instance *ext)
{
if (!ext->substmts) {
return;
}
- lyplg_ext_instance_substatements_free(ctx, ext->substmts);
- free(ext->data);
+ lyplg_ext_pfree_instance_substatements(ctx, ext->substmts);
+ free(ext->parsed);
+}
+
+/**
+ * @brief Free compiled annotation extension instance data.
+ *
+ * Implementation of ::lyplg_ext_compile_free_clb callback set as ::lyext_plugin::cfree.
+ */
+static void
+annotation_cfree(const struct ly_ctx *ctx, struct lysc_ext_instance *ext)
+{
+ if (!ext->substmts) {
+ return;
+ }
+
+ lyplg_ext_cfree_instance_substatements(ctx, ext->substmts);
+ free(ext->compiled);
}
/**
@@ -153,13 +227,15 @@
.revision = "2016-08-05",
.name = "annotation",
- .plugin.id = "libyang 2 - metadata, version 1",
- .plugin.compile = &annotation_compile,
- .plugin.sprinter = &annotation_schema_printer,
- .plugin.free = annotation_free,
+ .plugin.id = "ly2 metadata v1",
+ .plugin.parse = annotation_parse,
+ .plugin.compile = annotation_compile,
+ .plugin.sprinter = annotation_sprinter,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = annotation_pfree,
+ .plugin.cfree = annotation_cfree,
},
{0} /* terminating zeroed record */
};
diff --git a/src/plugins_exts/metadata.h b/src/plugins_exts/metadata.h
index 6387e1f..59ea2bf 100644
--- a/src/plugins_exts/metadata.h
+++ b/src/plugins_exts/metadata.h
@@ -23,13 +23,6 @@
extern "C" {
#endif
-#define ANNOTATION_SUBSTMT_IFF 0 /**< index for the LY_STMT_IF_FEATURE substatement in annotation's ::lysc_ext_instance.substmts */
-#define ANNOTATION_SUBSTMT_UNITS 1 /**< index for the LY_STMT_UNITS substatement in annotation's ::lysc_ext_instance.substmts */
-#define ANNOTATION_SUBSTMT_STATUS 2 /**< index for the LY_STMT_STATUS substatement in annotation's ::lysc_ext_instance.substmts */
-#define ANNOTATION_SUBSTMT_TYPE 3 /**< index for the LY_STMT_TYPE substatement in annotation's ::lysc_ext_instance.substmts */
-#define ANNOTATION_SUBSTMT_DSC 4 /**< index for the LY_STMT_DSC substatement in annotation's ::lysc_ext_instance.substmts */
-#define ANNOTATION_SUBSTMT_REF 5 /**< index for the LY_STMT_REF substatement in annotation's ::lysc_ext_instance.substmts */
-
/**
* @brief Metadata structure.
*
diff --git a/src/plugins_exts/nacm.c b/src/plugins_exts/nacm.c
index a83e32b..7323cd2 100644
--- a/src/plugins_exts/nacm.c
+++ b/src/plugins_exts/nacm.c
@@ -1,9 +1,10 @@
/**
* @file nacm.c
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief libyang extension plugin - NACM (RFC 6536)
*
- * Copyright (c) 2019 CESNET, z.s.p.o.
+ * Copyright (c) 2019 - 2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -16,11 +17,12 @@
#include <stdlib.h>
#include <string.h>
+#include "compat.h"
#include "libyang.h"
#include "plugins_exts.h"
struct nacm_dfs_arg {
- struct lysc_ext_instance *c_ext;
+ struct lysc_ext_instance *ext;
struct lysc_node *parent;
};
@@ -39,7 +41,7 @@
if ((node != arg->parent) && !(node->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
/* check that the node does not have its own NACM extension instance */
LY_ARRAY_FOR(node->exts, u) {
- if (node->exts[u].def == arg->c_ext->def) {
+ if (node->exts[u].def == arg->ext->def) {
/* the child already have its own NACM flag, so skip the subtree */
*dfs_continue = 1;
return LY_SUCCESS;
@@ -49,99 +51,99 @@
/* duplicate this one to inherit it to the child */
LY_ARRAY_NEW_GOTO(node->module->ctx, node->exts, inherited, ret, emem);
- inherited->def = lysc_ext_dup(arg->c_ext->def);
+ inherited->def = lysc_ext_dup(arg->ext->def);
inherited->parent = node;
- inherited->parent_stmt = lys_nodetype2stmt(node->nodetype);
- if (arg->c_ext->argument) {
- LY_ERR ret;
-
- if ((ret = lydict_insert(node->module->ctx, arg->c_ext->argument, strlen(arg->c_ext->argument),
- &inherited->argument))) {
+ inherited->parent_stmt = lyplg_ext_nodetype2stmt(node->nodetype);
+ if (arg->ext->argument) {
+ if ((ret = lydict_insert(node->module->ctx, arg->ext->argument, 0, &inherited->argument))) {
return ret;
}
}
/* TODO duplicate extension instances */
- inherited->data = arg->c_ext->data;
+ inherited->compiled = arg->ext->compiled;
}
return LY_SUCCESS;
emem:
- lyplg_ext_log(arg->c_ext, LY_LLERR, LY_EMEM, NULL, "Memory allocation failed (%s()).", __func__);
+ lyplg_ext_compile_log(NULL, arg->ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
return ret;
}
/**
- * @brief Compile NAMC's extension instances.
+ * @brief Parse NACM extension instances.
*
- * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
+ * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
*/
static LY_ERR
-nacm_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
+nacm_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
{
- LY_ERR ret;
- struct lysc_node *parent = NULL;
+ struct lysp_node *parent = NULL;
LY_ARRAY_COUNT_TYPE u;
- struct nacm_dfs_arg dfs_arg;
-
- static const uint8_t nacm_deny_all = 1;
- static const uint8_t nacm_deny_write = 2;
-
- /* store the NACM flag */
- if (!strcmp(c_ext->def->name, "default-deny-write")) {
- c_ext->data = (void *)&nacm_deny_write;
- } else if (!strcmp(c_ext->def->name, "default-deny-all")) {
- c_ext->data = (void *)&nacm_deny_all;
- } else {
- return LY_EINT;
- }
/* check that the extension is instantiated at an allowed place - data node */
- if (!LY_STMT_IS_NODE(c_ext->parent_stmt)) {
- lyplg_ext_log(c_ext, LY_LLWRN, 0, lysc_ctx_get_path(cctx),
- "Extension %s is allowed only in a data nodes, but it is placed in \"%s\" statement.",
- p_ext->name, ly_stmt2str(c_ext->parent_stmt));
+ if (!(ext->parent_stmt & LY_STMT_NODE_MASK)) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLWRN, 0, "Extension %s is allowed only in a data nodes, but it is placed in "
+ "\"%s\" statement.", ext->name, lyplg_ext_stmt2str(ext->parent_stmt));
return LY_ENOT;
- } else {
- parent = (struct lysc_node *)c_ext->parent;
- if (!(parent->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_CHOICE | LYS_ANYDATA |
- LYS_CASE | LYS_RPC | LYS_ACTION | LYS_NOTIF))) {
- /* note LYS_AUGMENT and LYS_USES is not in the list since they are not present in the compiled tree. Instead, libyang
- * passes all their extensions to their children nodes */
-invalid_parent:
- lyplg_ext_log(c_ext, LY_LLWRN, 0, lysc_ctx_get_path(cctx),
- "Extension %s is not allowed in %s statement.", p_ext->name, lys_nodetype2str(parent->nodetype));
- return LY_ENOT;
- }
- if ((c_ext->data == (void *)&nacm_deny_write) && (parent->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))) {
- goto invalid_parent;
- }
+ }
+
+ parent = ext->parent;
+ if (!(parent->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_CHOICE | LYS_ANYDATA |
+ LYS_CASE | LYS_RPC | LYS_ACTION | LYS_NOTIF)) || (!strcmp(strchr(ext->name, ':') + 1, "default-deny-write") &&
+ (parent->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)))) {
+ /* note LYS_AUGMENT and LYS_USES is not in the list since they are not present in the compiled tree. Instead, libyang
+ * passes all their extensions to their children nodes */
+ lyplg_ext_parse_log(pctx, ext, LY_LLWRN, 0, "Extension %s is not allowed in %s statement.", ext->name,
+ lys_nodetype2str(parent->nodetype));
+ return LY_ENOT;
}
/* check for duplication */
LY_ARRAY_FOR(parent->exts, u) {
- if ((&parent->exts[u] != c_ext) && parent->exts[u].def->plugin &&
- (parent->exts[u].def->plugin->compile == c_ext->def->plugin->compile)) {
+ if ((&parent->exts[u] != ext) && parent->exts[u].record && (parent->exts[u].record->plugin.id == ext->record->plugin.id)) {
/* duplication of a NACM extension on a single node
* We check for all NACM plugins since we want to catch even the situation that there is default-deny-all
* AND default-deny-write */
- if (parent->exts[u].def == c_ext->def) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension %s is instantiated multiple times.", p_ext->name);
+ if (parent->exts[u].name == ext->name) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s is instantiated multiple times.", ext->name);
} else {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID,
"Extension nacm:default-deny-write is mixed with nacm:default-deny-all.");
}
return LY_EVALID;
}
}
- /* inherit the extension instance to all the children nodes */
- dfs_arg.c_ext = c_ext;
- dfs_arg.parent = parent;
- ret = lysc_tree_dfs_full(parent, nacm_inherit_clb, &dfs_arg);
+ return LY_SUCCESS;
+}
- return ret;
+/**
+ * @brief Compile NACM extension instances.
+ *
+ * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
+ */
+static LY_ERR
+nacm_compile(struct lysc_ctx *UNUSED(cctx), const struct lysp_ext_instance *UNUSED(extp), struct lysc_ext_instance *ext)
+{
+ struct nacm_dfs_arg dfs_arg;
+
+ static const uint8_t nacm_deny_all = 1;
+ static const uint8_t nacm_deny_write = 2;
+
+ /* store the NACM flag */
+ if (!strcmp(ext->def->name, "default-deny-write")) {
+ ext->compiled = (void *)&nacm_deny_write;
+ } else if (!strcmp(ext->def->name, "default-deny-all")) {
+ ext->compiled = (void *)&nacm_deny_all;
+ } else {
+ return LY_EINT;
+ }
+
+ /* inherit the extension instance to all the children nodes */
+ dfs_arg.ext = ext;
+ dfs_arg.parent = ext->parent;
+ return lysc_tree_dfs_full(ext->parent, nacm_inherit_clb, &dfs_arg);
}
/**
@@ -157,49 +159,57 @@
.revision = "2012-02-22",
.name = "default-deny-write",
- .plugin.id = "libyang 2 - NACM, version 1",
- .plugin.compile = &nacm_compile,
+ .plugin.id = "ly2 NACM v1",
+ .plugin.parse = nacm_parse,
+ .plugin.compile = nacm_compile,
.plugin.sprinter = NULL,
- .plugin.free = NULL,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = NULL,
+ .plugin.cfree = NULL
}, {
.module = "ietf-netconf-acm",
.revision = "2018-02-14",
.name = "default-deny-write",
- .plugin.id = "libyang 2 - NACM, version 1",
- .plugin.compile = &nacm_compile,
+ .plugin.id = "ly2 NACM v1",
+ .plugin.parse = nacm_parse,
+ .plugin.compile = nacm_compile,
.plugin.sprinter = NULL,
- .plugin.free = NULL,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = NULL,
+ .plugin.cfree = NULL
}, {
.module = "ietf-netconf-acm",
.revision = "2012-02-22",
.name = "default-deny-all",
- .plugin.id = "libyang 2 - NACM, version 1",
- .plugin.compile = &nacm_compile,
+ .plugin.id = "ly2 NACM v1",
+ .plugin.parse = nacm_parse,
+ .plugin.compile = nacm_compile,
.plugin.sprinter = NULL,
- .plugin.free = NULL,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = NULL,
+ .plugin.cfree = NULL
}, {
.module = "ietf-netconf-acm",
.revision = "2018-02-14",
.name = "default-deny-all",
- .plugin.id = "libyang 2 - NACM, version 1",
- .plugin.compile = &nacm_compile,
+ .plugin.id = "ly2 NACM v1",
+ .plugin.parse = nacm_parse,
+ .plugin.compile = nacm_compile,
.plugin.sprinter = NULL,
- .plugin.free = NULL,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = NULL,
+ .plugin.cfree = NULL
},
{0} /* terminating zeroed item */
};
diff --git a/src/plugins_exts/schema_mount.c b/src/plugins_exts/schema_mount.c
index 042bebb..04679aa 100644
--- a/src/plugins_exts/schema_mount.c
+++ b/src/plugins_exts/schema_mount.c
@@ -21,6 +21,7 @@
#include <string.h>
#include "common.h"
+#include "compat.h"
#include "dict.h"
#include "libyang.h"
#include "log.h"
@@ -56,68 +57,95 @@
} inln; /**< inline mount points */
};
-#define EXT_LOGERR_MEM_RET(ext) \
- lyplg_ext_log(ext, LY_LLERR, LY_EMEM, NULL, "Memory allocation failed (%s:%d).", __FILE__, __LINE__); \
+#define EXT_LOGERR_MEM_RET(cctx, ext) \
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s:%d).", __FILE__, __LINE__); \
return LY_EMEM
-#define EXT_LOGERR_MEM_GOTO(ext, rc, label) \
- lyplg_ext_log(ext, LY_LLERR, LY_EMEM, NULL, "Memory allocation failed (%s:%d).", __FILE__, __LINE__); \
+#define EXT_LOGERR_MEM_GOTO(cctx, ext, rc, label) \
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s:%d).", __FILE__, __LINE__); \
rc = LY_EMEM; \
goto label
-#define EXT_LOGERR_INT_RET(ext) \
- lyplg_ext_log(ext, LY_LLERR, LY_EINT, NULL, "Internal error (%s:%d).", __FILE__, __LINE__); \
+#define EXT_LOGERR_INT_RET(cctx, ext) \
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EINT, "Internal error (%s:%d).", __FILE__, __LINE__); \
return LY_EINT
/**
- * @brief Check if given mount point is unique among its' siblings
+ * @brief Check if given mount point is unique among its siblings
*
- * @param cctx Compilation context.
- * @param c_ext Compiled extension instance for checking uniqueness.
- * @param p_ext Extension instance of the mount-point for comparison.
+ * @param[in] pctx Parse context.
+ * @param[in] ext Parsed extension instance.
* @return LY_SUCCESS if is unique;
* @return LY_EINVAL otherwise.
*/
static LY_ERR
-schema_mount_compile_unique_mp(struct lysc_ctx *cctx, const struct lysc_ext_instance *c_ext,
- const struct lysp_ext_instance *p_ext)
+schema_mount_parse_unique_mp(struct lysp_ctx *pctx, const struct lysp_ext_instance *ext)
{
- struct lysc_ext_instance *exts;
+ struct lysp_ext_instance *exts;
LY_ARRAY_COUNT_TYPE u;
- struct lysc_node *parent;
+ struct lysp_node *parent;
- /* check if it is the only instance of the mount-point among its' siblings */
- parent = (struct lysc_node *)c_ext->parent;
+ /* check if it is the only instance of the mount-point among its siblings */
+ parent = ext->parent;
exts = parent->exts;
LY_ARRAY_FOR(exts, u) {
- if (&exts[u] == c_ext) {
+ if (&exts[u] == ext) {
continue;
}
- if (!strcmp(exts[u].def->module->name, "ietf-yang-schema-mount") && !strcmp(exts[u].def->name, "mount-point")) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx), "Multiple extension \"%s\" instances.",
- p_ext->name);
+ if (!strcmp(exts[u].name, ext->name)) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Multiple extension \"%s\" instances.", ext->name);
return LY_EINVAL;
}
}
return LY_SUCCESS;
}
+/**
+ * @brief Schema mount parse.
+ * Checks if it can be a valid extension instance for yang schema mount.
+ *
+ * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
+ */
+static LY_ERR
+schema_mount_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
+{
+ /* check YANG version 1.1 */
+ if (lyplg_ext_parse_get_cur_pmod(pctx)->version != LYS_VERSION_1_1) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension \"%s\" instance not allowed in YANG version 1 module.",
+ ext->name);
+ return LY_EINVAL;
+ }
+
+ /* check parent nodetype */
+ if ((ext->parent_stmt != LY_STMT_CONTAINER) && (ext->parent_stmt != LY_STMT_LIST)) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension \"%s\" instance allowed only in container or list statement.",
+ ext->name);
+ return LY_EINVAL;
+ }
+
+ /* check uniqueness */
+ if (schema_mount_parse_unique_mp(pctx, ext)) {
+ return LY_EINVAL;
+ }
+
+ /* nothing to actually parse */
+ return LY_SUCCESS;
+}
+
struct lyplg_ext_sm_shared_cb_data {
const struct lysc_ext_instance *ext;
struct lyplg_ext_sm_shared *sm_shared;
};
static LY_ERR
-schema_mount_compile_mod_dfs_cb(struct lysc_node *node, void *data, ly_bool *dfs_continue)
+schema_mount_compile_mod_dfs_cb(struct lysc_node *node, void *data, ly_bool *UNUSED(dfs_continue))
{
struct lyplg_ext_sm_shared_cb_data *cb_data = data;
struct lyplg_ext_sm *sm_data;
struct lysc_ext_instance *exts;
LY_ARRAY_COUNT_TYPE u;
- (void)dfs_continue;
-
if (node == cb_data->ext->parent) {
/* parent of the current compiled extension, skip */
return LY_SUCCESS;
@@ -129,7 +157,7 @@
if (!strcmp(exts[u].def->module->name, "ietf-yang-schema-mount") && !strcmp(exts[u].def->name, "mount-point") &&
(exts[u].argument == cb_data->ext->argument)) {
/* same mount point, break the DFS search */
- sm_data = exts[u].data;
+ sm_data = exts[u].compiled;
cb_data->sm_shared = sm_data->shared;
return LY_EEXIST;
}
@@ -164,56 +192,33 @@
* Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
*/
static LY_ERR
-schema_mount_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
+schema_mount_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *UNUSED(extp), struct lysc_ext_instance *ext)
{
- const struct lys_module *cur_mod;
const struct lysc_node *node;
struct lyplg_ext_sm *sm_data;
- assert(!strcmp(p_ext->name, "yangmnt:mount-point"));
-
- /* check YANG version 1.1 */
- cur_mod = lysc_ctx_get_cur_mod(cctx);
- if (cur_mod->parsed->version != LYS_VERSION_1_1) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension \"%s\" instance not allowed in YANG version 1 module.", p_ext->name);
- return LY_EINVAL;
- }
-
- /* check parent nodetype */
- if ((p_ext->parent_stmt != LY_STMT_CONTAINER) && (p_ext->parent_stmt != LY_STMT_LIST)) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension \"%s\" instance allowed only in container or list statement.", p_ext->name);
- return LY_EINVAL;
- }
-
- /* check uniqueness */
- if (schema_mount_compile_unique_mp(cctx, c_ext, p_ext)) {
- return LY_EINVAL;
- }
-
/* init internal data */
sm_data = calloc(1, sizeof *sm_data);
if (!sm_data) {
- EXT_LOGERR_MEM_RET(c_ext);
+ EXT_LOGERR_MEM_RET(cctx, ext);
}
- c_ext->data = sm_data;
+ ext->compiled = sm_data;
/* find the owner module */
- node = c_ext->parent;
+ node = ext->parent;
while (node->parent) {
node = node->parent;
}
/* reuse/init shared schema */
- sm_data->shared = schema_mount_compile_find_shared(node->module, c_ext);
+ sm_data->shared = schema_mount_compile_find_shared(node->module, ext);
if (sm_data->shared) {
++sm_data->shared->ref_count;
} else {
sm_data->shared = calloc(1, sizeof *sm_data->shared);
if (!sm_data->shared) {
free(sm_data);
- EXT_LOGERR_MEM_RET(c_ext);
+ EXT_LOGERR_MEM_RET(cctx, ext);
}
pthread_mutex_init(&sm_data->shared->lock, NULL);
sm_data->shared->ref_count = 1;
@@ -242,7 +247,7 @@
/* find the mount point */
if (asprintf(&path, "/ietf-yang-schema-mount:schema-mounts/mount-point[module='%s'][label='%s']", ext->module->name,
ext->argument) == -1) {
- EXT_LOGERR_MEM_RET(ext);
+ EXT_LOGERR_MEM_RET(NULL, ext);
}
r = ext_data ? lyd_find_path(ext_data, path, 0, &mpoint) : LY_ENOTFOUND;
free(path);
@@ -264,7 +269,7 @@
/* check schema-ref */
if (lyd_find_path(mpoint, "shared-schema", 0, NULL)) {
if (lyd_find_path(mpoint, "inline", 0, NULL)) {
- EXT_LOGERR_INT_RET(ext);
+ EXT_LOGERR_INT_RET(NULL, ext);
}
*shared = 0;
} else {
@@ -308,7 +313,7 @@
/* create the context based on the data */
if ((rc = ly_ctx_new_yldata(sdirs, ext_data, ly_ctx_get_options(ext->module->ctx), ext_ctx))) {
- lyplg_ext_log(ext, LY_LLERR, rc, NULL, "Failed to create context for the schema-mount data.");
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, rc, "Failed to create context for the schema-mount data.");
goto cleanup;
}
@@ -348,7 +353,7 @@
schema_mount_get_ctx_shared(struct lysc_ext_instance *ext, const struct lyd_node *ext_data, ly_bool config,
const struct ly_ctx **ext_ctx)
{
- struct lyplg_ext_sm *sm_data = ext->data;
+ struct lyplg_ext_sm *sm_data = ext->compiled;
LY_ERR ret = LY_SUCCESS, r;
struct lyd_node *node = NULL;
struct ly_ctx *new_ctx = NULL;
@@ -369,13 +374,14 @@
}
}
if (!content_id) {
- lyplg_ext_log(ext, LY_LLERR, LY_EVALID, NULL, "Missing \"content-id\" or \"module-set-id\" in ietf-yang-library data.");
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, LY_EVALID,
+ "Missing \"content-id\" or \"module-set-id\" in ietf-yang-library data.");
return LY_EVALID;
}
/* LOCK */
if ((r = pthread_mutex_lock(&sm_data->shared->lock))) {
- lyplg_ext_log(ext, LY_LLERR, LY_ESYS, NULL, "Mutex lock failed (%s).", strerror(r));
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, LY_ESYS, "Mutex lock failed (%s).", strerror(r));
return LY_ESYS;
}
@@ -389,7 +395,7 @@
if (i < sm_data->shared->schema_count) {
/* schema exists already */
if (strcmp(content_id, sm_data->shared->schemas[i].content_id)) {
- lyplg_ext_log(ext, LY_LLERR, LY_EVALID, "/ietf-yang-library:yang-library/content-id",
+ lyplg_ext_compile_log_path("/ietf-yang-library:yang-library/content-id", ext, LY_LLERR, LY_EVALID,
"Shared-schema yang-library content-id \"%s\" differs from \"%s\" used previously.",
content_id, sm_data->shared->schemas[i].content_id);
ret = LY_EVALID;
@@ -406,7 +412,7 @@
mem = realloc(sm_data->shared->schemas, (i + 1) * sizeof *sm_data->shared->schemas);
if (!mem) {
ly_ctx_destroy(new_ctx);
- EXT_LOGERR_MEM_GOTO(ext, ret, cleanup);
+ EXT_LOGERR_MEM_GOTO(NULL, ext, ret, cleanup);
}
sm_data->shared->schemas = mem;
++sm_data->shared->schema_count;
@@ -440,7 +446,7 @@
schema_mount_get_ctx_inline(struct lysc_ext_instance *ext, const struct lyd_node *ext_data, ly_bool config,
const struct ly_ctx **ext_ctx)
{
- struct lyplg_ext_sm *sm_data = ext->data;
+ struct lyplg_ext_sm *sm_data = ext->compiled;
LY_ERR r;
struct ly_ctx *new_ctx = NULL;
uint32_t i;
@@ -459,7 +465,7 @@
mem = realloc(sm_data->inln.schemas, (i + 1) * sizeof *sm_data->inln.schemas);
if (!mem) {
ly_ctx_destroy(new_ctx);
- EXT_LOGERR_MEM_RET(ext);
+ EXT_LOGERR_MEM_RET(NULL, ext);
}
sm_data->inln.schemas = mem;
++sm_data->inln.schema_count;
@@ -497,7 +503,7 @@
LY_LIST_FOR(ext_data, iter) {
if (iter->flags & LYD_NEW) {
/* must be validated for the parent-reference prefix data to be stored */
- lyplg_ext_log(ext, LY_LLERR, LY_EINVAL, NULL, "Provided ext data have not been validated.");
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, LY_EINVAL, "Provided ext data have not been validated.");
ret = LY_EINVAL;
goto cleanup;
}
@@ -566,7 +572,7 @@
/* get all parent references of this mount point */
if (asprintf(&path, "/ietf-yang-schema-mount:schema-mounts/mount-point[module='%s'][label='%s']"
"/shared-schema/parent-reference", ext->module->name, ext->argument) == -1) {
- EXT_LOGERR_MEM_GOTO(ext, ret, cleanup);
+ EXT_LOGERR_MEM_GOTO(NULL, ext, ret, cleanup);
}
if ((ret = lyd_find_xpath(ext_data, path, set))) {
goto cleanup;
@@ -603,7 +609,7 @@
if (!ext_data) {
/* we expect the same ext data as before and there must be some for data to be parsed */
- lyplg_ext_log(ext, LY_LLERR, LY_EINVAL, NULL, "No ext data provided.");
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, LY_EINVAL, "No ext data provided.");
ret = LY_EINVAL;
goto cleanup;
}
@@ -625,7 +631,8 @@
LYD_VALUE_GET(&term->value, xp_val);
if ((ret = lyd_find_xpath4(ctx_node, ctx_node, lyxp_get_expr(xp_val->exp), xp_val->format, xp_val->prefix_data,
NULL, &par_set))) {
- lyplg_ext_log(ext, LY_LLERR, ret, NULL, "Parent reference \"%s\" evaluation failed.", lyxp_get_expr(xp_val->exp));
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, ret, "Parent reference \"%s\" evaluation failed.",
+ lyxp_get_expr(xp_val->exp));
goto cleanup;
}
@@ -759,7 +766,7 @@
if (!sibling) {
/* some data had to be parsed for this callback to be called */
- EXT_LOGERR_INT_RET(ext);
+ EXT_LOGERR_INT_RET(NULL, ext);
}
/* get operational data with ietf-yang-library and ietf-yang-schema-mount data */
@@ -770,7 +777,7 @@
LY_LIST_FOR(ext_data, iter) {
if (iter->flags & LYD_NEW) {
/* must be validated for the parent-reference prefix data to be stored */
- lyplg_ext_log(ext, LY_LLERR, LY_EINVAL, NULL, "Provided ext data have not been validated.");
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, LY_EINVAL, "Provided ext data have not been validated.");
ret = LY_EINVAL;
goto cleanup;
}
@@ -821,15 +828,15 @@
LY_LIST_FOR(sibling, iter) {
iter->flags |= LYD_EXT;
}
- lyd_insert_ext(orig_parent, sibling);
+ lyplg_ext_insert(orig_parent, sibling);
if (ret) {
/* log the error in the original context */
err = ly_err_first(LYD_CTX(sibling));
if (!err) {
- lyplg_ext_log(ext, LY_LLERR, ret, NULL, "Unknown validation error (err code %d).", ret);
+ lyplg_ext_compile_log(NULL, ext, LY_LLERR, ret, "Unknown validation error (err code %d).", ret);
} else {
- lyplg_ext_log(ext, LY_LLERR, err->no, err->path, "%s", err->msg);
+ lyplg_ext_compile_log_path(err->path, ext, LY_LLERR, err->no, "%s", err->msg);
}
goto cleanup;
}
@@ -845,7 +852,7 @@
if ((ret = lyd_dup_single(lyd_parent(sibling), NULL, LYD_DUP_WITH_PARENTS | LYD_DUP_NO_META, &diff_parent))) {
goto cleanup;
}
- if ((ret = lyd_insert_ext(diff_parent, ext_diff))) {
+ if ((ret = lyplg_ext_insert(diff_parent, ext_diff))) {
goto cleanup;
}
ext_diff = NULL;
@@ -876,14 +883,14 @@
}
/**
- * @brief Schema mount free.
+ * @brief Schema mount compile free.
*
- * Implementation of ::lyplg_ext_free_clb callback set as ::lyext_plugin::free.
+ * Implementation of ::lyplg_ext_compile_free_clb callback set as ::lyext_plugin::cfree.
*/
static void
-schema_mount_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
+schema_mount_cfree(const struct ly_ctx *ctx, struct lysc_ext_instance *ext)
{
- struct lyplg_ext_sm *sm_data = ext->data;
+ struct lyplg_ext_sm *sm_data = ext->compiled;
uint32_t i;
if (!sm_data) {
@@ -957,13 +964,15 @@
.revision = "2019-01-14",
.name = "mount-point",
- .plugin.id = "libyang 2 - Schema Mount, version 1",
- .plugin.compile = &schema_mount_compile,
+ .plugin.id = "ly2 schema mount v1",
+ .plugin.parse = schema_mount_parse,
+ .plugin.compile = schema_mount_compile,
.plugin.sprinter = NULL,
- .plugin.free = &schema_mount_free,
.plugin.node = NULL,
- .plugin.snode = &schema_mount_snode,
- .plugin.validate = &schema_mount_validate
+ .plugin.snode = schema_mount_snode,
+ .plugin.validate = schema_mount_validate,
+ .plugin.pfree = NULL,
+ .plugin.cfree = schema_mount_cfree
},
{0} /* terminating zeroed item */
};
diff --git a/src/plugins_exts/structure.c b/src/plugins_exts/structure.c
index 12c548c..3a0bf8a 100644
--- a/src/plugins_exts/structure.c
+++ b/src/plugins_exts/structure.c
@@ -1,7 +1,7 @@
/**
* @file structure.c
* @author Michal Vasko <mvasko@cesnet.cz>
- * @brief libyang extension plugin - strcture (RFC 8791)
+ * @brief libyang extension plugin - structure (RFC 8791)
*
* Copyright (c) 2022 CESNET, z.s.p.o.
*
@@ -20,16 +20,31 @@
#include "libyang.h"
#include "plugins_exts.h"
-struct lysc_ext_instance_structure {
- struct lysc_must *musts;
+struct lysp_ext_instance_structure {
+ struct lysp_restr *musts;
uint16_t flags;
const char *dsc;
const char *ref;
struct lysp_tpdf *typedefs;
struct lysp_node_grp *groupings;
+ struct lysp_node *child;
+};
+
+struct lysc_ext_instance_structure {
+ struct lysc_must *musts;
+ uint16_t flags;
+ const char *dsc;
+ const char *ref;
struct lysc_node *child;
};
+struct lysp_ext_instance_augment_structure {
+ uint16_t flags;
+ const char *dsc;
+ const char *ref;
+ struct lysp_node *child;
+};
+
struct lysc_ext_instance_augment_structure {
uint16_t flags;
const char *dsc;
@@ -37,116 +52,206 @@
};
/**
+ * @brief Parse structure extension instances.
+ *
+ * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
+ */
+static LY_ERR
+structure_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
+{
+ LY_ERR rc;
+ LY_ARRAY_COUNT_TYPE u;
+ struct lysp_module *pmod;
+ struct lysp_ext_instance_structure *struct_pdata;
+
+ /* structure can appear only at the top level of a YANG module or submodule */
+ if ((ext->parent_stmt != LY_STMT_MODULE) && (ext->parent_stmt != LY_STMT_SUBMODULE)) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID,
+ "Extension %s must not be used as a non top-level statement in \"%s\" statement.", ext->name,
+ lyplg_ext_stmt2str(ext->parent_stmt));
+ return LY_EVALID;
+ }
+
+ pmod = ext->parent;
+
+ /* check for duplication */
+ LY_ARRAY_FOR(pmod->exts, u) {
+ if ((&pmod->exts[u] != ext) && (pmod->exts[u].name == ext->name) && !strcmp(pmod->exts[u].argument, ext->argument)) {
+ /* duplication of the same structure extension in a single module */
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s is instantiated multiple times.", ext->name);
+ return LY_EVALID;
+ }
+ }
+
+ /* allocate the storage */
+ struct_pdata = calloc(1, sizeof *struct_pdata);
+ if (!struct_pdata) {
+ goto emem;
+ }
+ ext->parsed = struct_pdata;
+ LY_ARRAY_CREATE_GOTO(lyplg_extp_cur_pmod(pctx)->mod->ctx, ext->substmts, 14, rc, emem);
+
+ /* parse substatements */
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_MUST;
+ ext->substmts[0].storage = &struct_pdata->musts;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_STATUS;
+ ext->substmts[1].storage = &struct_pdata->flags;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
+ ext->substmts[2].storage = &struct_pdata->dsc;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[3].stmt = LY_STMT_REFERENCE;
+ ext->substmts[3].storage = &struct_pdata->ref;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[4].stmt = LY_STMT_TYPEDEF;
+ ext->substmts[4].storage = &struct_pdata->typedefs;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[5].stmt = LY_STMT_GROUPING;
+ ext->substmts[5].storage = &struct_pdata->groupings;
+
+ /* data-def-stmt */
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[6].stmt = LY_STMT_CONTAINER;
+ ext->substmts[6].storage = &struct_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[7].stmt = LY_STMT_LEAF;
+ ext->substmts[7].storage = &struct_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
+ ext->substmts[8].storage = &struct_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[9].stmt = LY_STMT_LIST;
+ ext->substmts[9].storage = &struct_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[10].stmt = LY_STMT_CHOICE;
+ ext->substmts[10].storage = &struct_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[11].stmt = LY_STMT_ANYDATA;
+ ext->substmts[11].storage = &struct_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[12].stmt = LY_STMT_ANYXML;
+ ext->substmts[12].storage = &struct_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[13].stmt = LY_STMT_USES;
+ ext->substmts[13].storage = &struct_pdata->child;
+
+ rc = lyplg_ext_parse_extension_instance(pctx, ext);
+ return rc;
+
+emem:
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
+ return LY_EMEM;
+}
+
+/**
* @brief Compile structure extension instances.
*
* Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
*/
static LY_ERR
-structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
+structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext)
{
LY_ERR rc;
- LY_ARRAY_COUNT_TYPE u;
struct lysc_module *mod_c;
const struct lysc_node *child;
- struct lysc_ext_instance_structure *struct_data;
- uint32_t prev_options = *lysc_ctx_get_options(cctx);
+ struct lysc_ext_instance_structure *struct_cdata;
+ uint32_t prev_options = *lyplg_ext_compile_get_options(cctx);
- /* structure can appear only at the top level of a YANG module or submodule */
- if ((c_ext->parent_stmt != LY_STMT_MODULE) && (c_ext->parent_stmt != LY_STMT_SUBMODULE)) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension %s must not be used as a non top-level statement in \"%s\" statement.",
- p_ext->name, ly_stmt2str(c_ext->parent_stmt));
- return LY_EVALID;
- }
+ mod_c = ext->parent;
- mod_c = (struct lysc_module *)c_ext->parent;
-
- /* check identifier namespace */
- LY_ARRAY_FOR(mod_c->exts, u) {
- if ((&mod_c->exts[u] != c_ext) && (mod_c->exts[u].def == c_ext->def) && !strcmp(mod_c->exts[u].argument, c_ext->argument)) {
- /* duplication of the same structure extension in a single module */
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx), "Extension %s is instantiated multiple times.", p_ext->name);
- return LY_EVALID;
- }
- }
+ /* check identifier namespace with the compiled nodes */
LY_LIST_FOR(mod_c->data, child) {
- if (!strcmp(child->name, c_ext->argument)) {
+ if (!strcmp(child->name, ext->argument)) {
/* identifier collision */
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx), "Extension %s collides "
- "with a %s with the same identifier.", p_ext->name, lys_nodetype2str(child->nodetype));
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID, "Extension %s collides with a %s with the same identifier.",
+ extp->name, lys_nodetype2str(child->nodetype));
return LY_EVALID;
}
}
/* allocate the storage */
- struct_data = calloc(1, sizeof *struct_data);
- if (!struct_data) {
+ struct_cdata = calloc(1, sizeof *struct_cdata);
+ if (!struct_cdata) {
goto emem;
}
- c_ext->data = struct_data;
+ ext->compiled = struct_cdata;
/* compile substatements */
- LY_ARRAY_CREATE_GOTO(cctx->ctx, c_ext->substmts, 14, rc, emem);
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[0].stmt = LY_STMT_MUST;
- c_ext->substmts[0].storage = &struct_data->musts;
+ LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 14, rc, emem);
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_MUST;
+ ext->substmts[0].storage = &struct_cdata->musts;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[1].stmt = LY_STMT_STATUS;
- c_ext->substmts[1].storage = &struct_data->flags;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_STATUS;
+ ext->substmts[1].storage = &struct_cdata->flags;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
- c_ext->substmts[2].storage = &struct_data->dsc;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
+ ext->substmts[2].storage = &struct_cdata->dsc;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[3].stmt = LY_STMT_REFERENCE;
- c_ext->substmts[3].storage = &struct_data->ref;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[3].stmt = LY_STMT_REFERENCE;
+ ext->substmts[3].storage = &struct_cdata->ref;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[4].stmt = LY_STMT_TYPEDEF;
- c_ext->substmts[4].storage = &struct_data->typedefs;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[4].stmt = LY_STMT_TYPEDEF;
+ ext->substmts[4].storage = NULL;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[5].stmt = LY_STMT_GROUPING;
- c_ext->substmts[5].storage = &struct_data->groupings;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[5].stmt = LY_STMT_GROUPING;
+ ext->substmts[5].storage = NULL;
/* data-def-stmt */
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[6].stmt = LY_STMT_CONTAINER;
- c_ext->substmts[6].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[6].stmt = LY_STMT_CONTAINER;
+ ext->substmts[6].storage = &struct_cdata->child;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[7].stmt = LY_STMT_LEAF;
- c_ext->substmts[7].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[7].stmt = LY_STMT_LEAF;
+ ext->substmts[7].storage = &struct_cdata->child;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
- c_ext->substmts[8].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
+ ext->substmts[8].storage = &struct_cdata->child;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[9].stmt = LY_STMT_LIST;
- c_ext->substmts[9].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[9].stmt = LY_STMT_LIST;
+ ext->substmts[9].storage = &struct_cdata->child;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[10].stmt = LY_STMT_CHOICE;
- c_ext->substmts[10].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[10].stmt = LY_STMT_CHOICE;
+ ext->substmts[10].storage = &struct_cdata->child;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[11].stmt = LY_STMT_ANYDATA;
- c_ext->substmts[11].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[11].stmt = LY_STMT_ANYDATA;
+ ext->substmts[11].storage = &struct_cdata->child;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[12].stmt = LY_STMT_ANYXML;
- c_ext->substmts[12].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[12].stmt = LY_STMT_ANYXML;
+ ext->substmts[12].storage = &struct_cdata->child;
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[13].stmt = LY_STMT_USES;
- c_ext->substmts[13].storage = &struct_data->child;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[13].stmt = LY_STMT_USES;
+ ext->substmts[13].storage = &struct_cdata->child;
- *lysc_ctx_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
- rc = lys_compile_extension_instance(cctx, p_ext, c_ext);
- *lysc_ctx_get_options(cctx) = prev_options;
+ *lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
+ rc = lyplg_ext_compile_extension_instance(cctx, extp, ext);
+ *lyplg_ext_compile_get_options(cctx) = prev_options;
if (rc) {
return rc;
}
@@ -154,134 +259,7 @@
return LY_SUCCESS;
emem:
- lyplg_ext_log(c_ext, LY_LLERR, LY_EMEM, lysc_ctx_get_path(cctx), "Memory allocation failed (%s()).", __func__);
- return LY_EMEM;
-}
-
-/**
- * @brief Compile augment-structure extension instances.
- *
- * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
- */
-static LY_ERR
-structure_aug_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
-{
- LY_ERR rc;
- struct lysp_stmt *stmt;
- struct lysc_node *aug_target;
- struct lysc_ext_instance *target_ext;
- struct lysc_ext_instance_structure *target_data;
- struct lysc_ext_instance_augment_structure *aug_data;
- uint32_t prev_options = *lysc_ctx_get_options(cctx), i;
-
- /* augment-structure can appear only at the top level of a YANG module or submodule */
- if ((c_ext->parent_stmt != LY_STMT_MODULE) && (c_ext->parent_stmt != LY_STMT_SUBMODULE)) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension %s must not be used as a non top-level statement in \"%s\" statement.",
- p_ext->name, ly_stmt2str(c_ext->parent_stmt));
- return LY_EVALID;
- }
-
- /* augment-structure must define some data-def-stmt */
- LY_LIST_FOR(p_ext->child, stmt) {
- if (LY_STMT_IS_DATA_NODE(stmt->kw)) {
- break;
- }
- }
- if (!stmt) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension %s does not define any data-def-stmt statements.", p_ext->name);
- return LY_EVALID;
- }
-
- /* find the target struct ext instance */
- if ((rc = lys_compile_extension_instance_find_augment_target(cctx, p_ext->argument, &target_ext, &aug_target))) {
- return rc;
- }
-
- /* check target_ext */
- if (strcmp(target_ext->def->name, "structure") || strcmp(target_ext->def->module->name, "ietf-yang-structure-ext")) {
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
- "Extension %s can only target extension instances of \"ietf-yang-structure-ext:structure\".", p_ext->name);
- return LY_EVALID;
- }
- target_data = target_ext->data;
-
- /* allocate the storage */
- aug_data = calloc(1, sizeof *aug_data);
- if (!aug_data) {
- goto emem;
- }
- c_ext->data = aug_data;
-
- /* compile substatements */
- LY_ARRAY_CREATE_GOTO(cctx->ctx, c_ext->substmts, 12, rc, emem);
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[0].stmt = LY_STMT_STATUS;
- c_ext->substmts[0].storage = &aug_data->flags;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[1].stmt = LY_STMT_DESCRIPTION;
- c_ext->substmts[1].storage = &aug_data->dsc;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[2].stmt = LY_STMT_REFERENCE;
- c_ext->substmts[2].storage = &aug_data->ref;
-
- /* data-def-stmt */
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[3].stmt = LY_STMT_CONTAINER;
- c_ext->substmts[3].storage = &target_data->child;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[4].stmt = LY_STMT_LEAF;
- c_ext->substmts[4].storage = &target_data->child;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[5].stmt = LY_STMT_LEAF_LIST;
- c_ext->substmts[5].storage = &target_data->child;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[6].stmt = LY_STMT_LIST;
- c_ext->substmts[6].storage = &target_data->child;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[7].stmt = LY_STMT_CHOICE;
- c_ext->substmts[7].storage = &target_data->child;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[8].stmt = LY_STMT_ANYDATA;
- c_ext->substmts[8].storage = &target_data->child;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[9].stmt = LY_STMT_ANYXML;
- c_ext->substmts[9].storage = &target_data->child;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[10].stmt = LY_STMT_USES;
- c_ext->substmts[10].storage = &target_data->child;
-
- /* case */
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[11].stmt = LY_STMT_CASE;
- c_ext->substmts[11].storage = &target_data->child;
-
- *lysc_ctx_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
- rc = lys_compile_extension_instance_augment(cctx, p_ext, c_ext, aug_target);
- *lysc_ctx_get_options(cctx) = prev_options;
- if (rc) {
- return rc;
- }
-
- /* data-def-statements are now part of the target extension (do not print nor free them) */
- for (i = 0; i < 9; ++i) {
- LY_ARRAY_DECREMENT(c_ext->substmts);
- }
-
- return LY_SUCCESS;
-
-emem:
- lyplg_ext_log(c_ext, LY_LLERR, LY_EMEM, lysc_ctx_get_path(cctx), "Memory allocation failed (%s()).", __func__);
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
return LY_EMEM;
}
@@ -291,22 +269,239 @@
* Implementation of ::lyplg_ext_schema_printer_clb set as ::lyext_plugin::sprinter
*/
static LY_ERR
-structure_schema_printer(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag)
+structure_sprinter(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag)
{
- lysc_print_extension_instance(ctx, ext, flag);
+ lyplg_ext_print_extension_instance(ctx, ext, flag);
return LY_SUCCESS;
}
/**
- * @brief Free structure extension instances' data.
+ * @brief Free parsed structure extension instance data.
*
- * Implementation of ::lyplg_clb_free_clb callback set as lyext_plugin::free.
+ * Implementation of ::lyplg_clb_parse_free_clb callback set as lyext_plugin::pfree.
*/
static void
-structure_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
+structure_pfree(const struct ly_ctx *ctx, struct lysp_ext_instance *ext)
{
- lyplg_ext_instance_substatements_free(ctx, ext->substmts);
- free(ext->data);
+ lyplg_ext_pfree_instance_substatements(ctx, ext->substmts);
+ free(ext->parsed);
+}
+
+/**
+ * @brief Free compiled structure extension instance data.
+ *
+ * Implementation of ::lyplg_clb_compile_free_clb callback set as lyext_plugin::cfree.
+ */
+static void
+structure_cfree(const struct ly_ctx *ctx, struct lysc_ext_instance *ext)
+{
+ lyplg_ext_cfree_instance_substatements(ctx, ext->substmts);
+ free(ext->compiled);
+}
+
+/**
+ * @brief Parse augment-structure extension instances.
+ *
+ * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
+ */
+static LY_ERR
+structure_aug_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
+{
+ LY_ERR rc;
+ struct lysp_stmt *stmt;
+ struct lysp_ext_instance_augment_structure *aug_pdata;
+
+ /* augment-structure can appear only at the top level of a YANG module or submodule */
+ if ((ext->parent_stmt != LY_STMT_MODULE) && (ext->parent_stmt != LY_STMT_SUBMODULE)) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID,
+ "Extension %s must not be used as a non top-level statement in \"%s\" statement.", ext->name,
+ lyplg_ext_stmt2str(ext->parent_stmt));
+ return LY_EVALID;
+ }
+
+ /* augment-structure must define some data-def-stmt */
+ LY_LIST_FOR(ext->child, stmt) {
+ if (stmt->kw & LY_STMT_DATA_NODE_MASK) {
+ break;
+ }
+ }
+ if (!stmt) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s does not define any data-def-stmt statements.",
+ ext->name);
+ return LY_EVALID;
+ }
+
+ /* allocate the storage */
+ aug_pdata = calloc(1, sizeof *aug_pdata);
+ if (!aug_pdata) {
+ goto emem;
+ }
+ ext->parsed = aug_pdata;
+ LY_ARRAY_CREATE_GOTO(lyplg_extp_cur_pmod(pctx)->mod->ctx, ext->substmts, 12, rc, emem);
+
+ /* parse substatements */
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_STATUS;
+ ext->substmts[0].storage = &aug_pdata->flags;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_DESCRIPTION;
+ ext->substmts[1].storage = &aug_pdata->dsc;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_REFERENCE;
+ ext->substmts[2].storage = &aug_pdata->ref;
+
+ /* data-def-stmt */
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[3].stmt = LY_STMT_CONTAINER;
+ ext->substmts[3].storage = &aug_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[4].stmt = LY_STMT_LEAF;
+ ext->substmts[4].storage = &aug_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[5].stmt = LY_STMT_LEAF_LIST;
+ ext->substmts[5].storage = &aug_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[6].stmt = LY_STMT_LIST;
+ ext->substmts[6].storage = &aug_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[7].stmt = LY_STMT_CHOICE;
+ ext->substmts[7].storage = &aug_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[8].stmt = LY_STMT_ANYDATA;
+ ext->substmts[8].storage = &aug_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[9].stmt = LY_STMT_ANYXML;
+ ext->substmts[9].storage = &aug_pdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[10].stmt = LY_STMT_USES;
+ ext->substmts[10].storage = &aug_pdata->child;
+
+ /* case */
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[11].stmt = LY_STMT_CASE;
+ ext->substmts[11].storage = &aug_pdata->child;
+
+ rc = lyplg_ext_parse_extension_instance(pctx, ext);
+ return rc;
+
+emem:
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
+ return LY_EMEM;
+}
+
+/**
+ * @brief Compile augment-structure extension instances.
+ *
+ * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
+ */
+static LY_ERR
+structure_aug_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext)
+{
+ LY_ERR rc;
+ struct lysc_node *aug_target;
+ struct lysc_ext_instance *target_ext;
+ struct lysc_ext_instance_structure *target_cdata;
+ struct lysc_ext_instance_augment_structure *aug_cdata;
+ uint32_t prev_options = *lyplg_ext_compile_get_options(cctx), i;
+
+ /* find the target struct ext instance */
+ if ((rc = lys_compile_extension_instance_find_augment_target(cctx, extp->argument, &target_ext, &aug_target))) {
+ return rc;
+ }
+
+ /* check target_ext */
+ if (strcmp(target_ext->def->name, "structure") || strcmp(target_ext->def->module->name, "ietf-yang-structure-ext")) {
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID,
+ "Extension %s can only target extension instances of \"ietf-yang-structure-ext:structure\".", extp->name);
+ return LY_EVALID;
+ }
+ target_cdata = target_ext->compiled;
+
+ /* allocate the storage */
+ aug_cdata = calloc(1, sizeof *aug_cdata);
+ if (!aug_cdata) {
+ goto emem;
+ }
+ ext->compiled = aug_cdata;
+
+ /* compile substatements */
+ LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 12, rc, emem);
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_STATUS;
+ ext->substmts[0].storage = &aug_cdata->flags;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_DESCRIPTION;
+ ext->substmts[1].storage = &aug_cdata->dsc;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_REFERENCE;
+ ext->substmts[2].storage = &aug_cdata->ref;
+
+ /* data-def-stmt */
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[3].stmt = LY_STMT_CONTAINER;
+ ext->substmts[3].storage = &target_cdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[4].stmt = LY_STMT_LEAF;
+ ext->substmts[4].storage = &target_cdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[5].stmt = LY_STMT_LEAF_LIST;
+ ext->substmts[5].storage = &target_cdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[6].stmt = LY_STMT_LIST;
+ ext->substmts[6].storage = &target_cdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[7].stmt = LY_STMT_CHOICE;
+ ext->substmts[7].storage = &target_cdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[8].stmt = LY_STMT_ANYDATA;
+ ext->substmts[8].storage = &target_cdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[9].stmt = LY_STMT_ANYXML;
+ ext->substmts[9].storage = &target_cdata->child;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[10].stmt = LY_STMT_USES;
+ ext->substmts[10].storage = &target_cdata->child;
+
+ /* case */
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[11].stmt = LY_STMT_CASE;
+ ext->substmts[11].storage = &target_cdata->child;
+
+ *lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
+ rc = lyplg_ext_compile_extension_instance_augment(cctx, extp, ext, aug_target);
+ *lyplg_ext_compile_get_options(cctx) = prev_options;
+ if (rc) {
+ return rc;
+ }
+
+ /* data-def-statements are now part of the target extension (do not print nor free them) */
+ for (i = 0; i < 9; ++i) {
+ LY_ARRAY_DECREMENT(ext->substmts);
+ }
+
+ return LY_SUCCESS;
+
+emem:
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
+ return LY_EMEM;
}
/**
@@ -322,26 +517,30 @@
.revision = "2020-06-17",
.name = "structure",
- .plugin.id = "libyang 2 - structure, version 1",
+ .plugin.id = "ly2 structure v1",
+ .plugin.parse = structure_parse,
.plugin.compile = structure_compile,
- .plugin.sprinter = structure_schema_printer,
- .plugin.free = structure_free,
+ .plugin.sprinter = structure_sprinter,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = structure_pfree,
+ .plugin.cfree = structure_cfree
},
{
.module = "ietf-yang-structure-ext",
.revision = "2020-06-17",
.name = "augment-structure",
- .plugin.id = "libyang 2 - structure, version 1",
+ .plugin.id = "ly2 structure v1",
+ .plugin.parse = structure_aug_parse,
.plugin.compile = structure_aug_compile,
- .plugin.sprinter = structure_schema_printer,
- .plugin.free = structure_free,
+ .plugin.sprinter = structure_sprinter,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = NULL,
+ .plugin.cfree = structure_cfree
},
{0} /* terminating zeroed record */
};
diff --git a/src/plugins_exts/yangdata.c b/src/plugins_exts/yangdata.c
index 939709b..32229d7 100644
--- a/src/plugins_exts/yangdata.c
+++ b/src/plugins_exts/yangdata.c
@@ -1,9 +1,10 @@
/**
* @file yangdata.c
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief libyang extension plugin - yang-data (RFC 8040)
*
- * Copyright (c) 2021 CESNET, z.s.p.o.
+ * Copyright (c) 2021 - 2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -19,15 +20,61 @@
#include "libyang.h"
#include "plugins_exts.h"
+static void yangdata_cfree(const struct ly_ctx *ctx, struct lysc_ext_instance *ext);
+
/**
- * @brief Free yang-data extension instances' data.
+ * @brief Parse yang-data extension instances.
*
- * Implementation of ::lyplg_clb_free_clb callback set as lyext_plugin::free.
+ * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
*/
-static void
-yangdata_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
+static LY_ERR
+yangdata_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
{
- lyplg_ext_instance_substatements_free(ctx, ext->substmts);
+ LY_ERR ret;
+ LY_ARRAY_COUNT_TYPE u;
+ struct lysp_module *pmod;
+
+ /* yang-data can appear only at the top level of a YANG module or submodule */
+ if ((ext->parent_stmt != LY_STMT_MODULE) && (ext->parent_stmt != LY_STMT_SUBMODULE)) {
+ lyplg_ext_parse_log(pctx, ext, LY_LLWRN, 0, "Extension %s is ignored since it appears as a non top-level statement "
+ "in \"%s\" statement.", ext->name, lyplg_ext_stmt2str(ext->parent_stmt));
+ return LY_ENOT;
+ }
+
+ pmod = ext->parent;
+
+ /* check for duplication */
+ LY_ARRAY_FOR(pmod->exts, u) {
+ if ((&pmod->exts[u] != ext) && (pmod->exts[u].name == ext->name) && !strcmp(pmod->exts[u].argument, ext->argument)) {
+ /* duplication of the same yang-data extension in a single module */
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s is instantiated multiple times.", ext->name);
+ return LY_EVALID;
+ }
+ }
+
+ /* parse yang-data substatements */
+ LY_ARRAY_CREATE_GOTO(lyplg_extp_cur_pmod(pctx)->mod->ctx, ext->substmts, 3, ret, emem);
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_CONTAINER;
+ ext->substmts[0].storage = &ext->parsed;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_CHOICE;
+ ext->substmts[1].storage = &ext->parsed;
+
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_USES;
+ ext->substmts[2].storage = &ext->parsed;
+
+ if ((ret = lyplg_ext_parse_extension_instance(pctx, ext))) {
+ return ret;
+ }
+
+ return LY_SUCCESS;
+
+emem:
+ lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
+ return LY_EMEM;
}
/**
@@ -36,109 +83,84 @@
* Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
*/
static LY_ERR
-yangdata_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
+yangdata_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext)
{
LY_ERR ret;
- LY_ARRAY_COUNT_TYPE u;
- struct lysc_module *mod_c;
const struct lysc_node *child;
ly_bool valid = 1;
- uint32_t prev_options = *lysc_ctx_get_options(cctx);
+ uint32_t prev_options = *lyplg_ext_compile_get_options(cctx);
- /* yang-data can appear only at the top level of a YANG module or submodule */
- if ((c_ext->parent_stmt != LY_STMT_MODULE) && (c_ext->parent_stmt != LY_STMT_SUBMODULE)) {
- lyplg_ext_log(c_ext, LY_LLWRN, 0, lysc_ctx_get_path(cctx),
- "Extension %s is ignored since it appears as a non top-level statement in \"%s\" statement.",
- p_ext->name, ly_stmt2str(c_ext->parent_stmt));
- return LY_ENOT;
- }
+ /* compile yangg-data substatements */
+ LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 3, ret, emem);
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[0].stmt = LY_STMT_CONTAINER;
+ ext->substmts[0].storage = &ext->compiled;
- mod_c = (struct lysc_module *)c_ext->parent;
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[1].stmt = LY_STMT_CHOICE;
+ ext->substmts[1].storage = &ext->compiled;
- /* check for duplication */
- LY_ARRAY_FOR(mod_c->exts, u) {
- if ((&mod_c->exts[u] != c_ext) && (mod_c->exts[u].def == c_ext->def) && !strcmp(mod_c->exts[u].argument, c_ext->argument)) {
- /* duplication of the same yang-data extension in a single module */
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx), "Extension %s is instantiated multiple times.", p_ext->name);
- return LY_EVALID;
- }
- }
+ LY_ARRAY_INCREMENT(ext->substmts);
+ ext->substmts[2].stmt = LY_STMT_USES;
+ ext->substmts[2].storage = &ext->compiled;
- /* compile annotation substatements
- * To let the compilation accept different statements possibly leading to the container top-level node, there are 3
- * allowed substatements pointing to a single storage. But when compiled, the substaments list is compressed just to
- * a single item providing the schema tree. */
- LY_ARRAY_CREATE_GOTO(cctx->ctx, c_ext->substmts, 3, ret, emem);
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[0].stmt = LY_STMT_CONTAINER;
- c_ext->substmts[0].storage = &c_ext->data;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[1].stmt = LY_STMT_CHOICE;
- c_ext->substmts[1].storage = &c_ext->data;
-
- LY_ARRAY_INCREMENT(c_ext->substmts);
- c_ext->substmts[2].stmt = LY_STMT_USES;
- c_ext->substmts[2].storage = &c_ext->data;
-
- *lysc_ctx_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
- ret = lys_compile_extension_instance(cctx, p_ext, c_ext);
- *lysc_ctx_get_options(cctx) = prev_options;
- LY_ARRAY_DECREMENT(c_ext->substmts);
- LY_ARRAY_DECREMENT(c_ext->substmts);
+ *lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
+ ret = lyplg_ext_compile_extension_instance(cctx, extp, ext);
+ *lyplg_ext_compile_get_options(cctx) = prev_options;
if (ret) {
return ret;
}
/* check that we have really just a single container data definition in the top */
- child = *(struct lysc_node **)c_ext->substmts[0].storage;
+ child = ext->compiled;
if (!child) {
valid = 0;
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID,
"Extension %s is instantiated without any top level data node, but exactly one container data node is expected.",
- p_ext->name);
+ extp->name);
} else if (child->next) {
valid = 0;
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID,
"Extension %s is instantiated with multiple top level data nodes, but only a single container data node is allowed.",
- p_ext->name);
+ extp->name);
} else if (child->nodetype == LYS_CHOICE) {
/* all the choice's case are expected to result to a single container node */
+ struct lysc_module *mod_c = ext->parent;
const struct lysc_node *snode = NULL;
while ((snode = lys_getnext(snode, child, mod_c, 0))) {
if (snode->next) {
valid = 0;
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID,
"Extension %s is instantiated with multiple top level data nodes (inside a single choice's case), "
- "but only a single container data node is allowed.", p_ext->name);
+ "but only a single container data node is allowed.", extp->name);
break;
} else if (snode->nodetype != LYS_CONTAINER) {
valid = 0;
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID,
"Extension %s is instantiated with %s top level data node (inside a choice), "
- "but only a single container data node is allowed.", p_ext->name, lys_nodetype2str(snode->nodetype));
+ "but only a single container data node is allowed.", extp->name, lys_nodetype2str(snode->nodetype));
break;
}
}
} else if (child->nodetype != LYS_CONTAINER) {
/* via uses */
valid = 0;
- lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID,
"Extension %s is instantiated with %s top level data node, but only a single container data node is allowed.",
- p_ext->name, lys_nodetype2str(child->nodetype));
+ extp->name, lys_nodetype2str(child->nodetype));
}
if (!valid) {
- yangdata_free(lysc_ctx_get_ctx(cctx), c_ext);
- c_ext->data = c_ext->substmts = NULL;
+ yangdata_cfree(lyplg_ext_compile_get_ctx(cctx), ext);
+ ext->compiled = ext->substmts = NULL;
return LY_EVALID;
}
return LY_SUCCESS;
emem:
- lyplg_ext_log(c_ext, LY_LLERR, LY_EMEM, lysc_ctx_get_path(cctx), "Memory allocation failed (%s()).", __func__);
+ lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
return LY_EMEM;
}
@@ -150,11 +172,33 @@
static LY_ERR
yangdata_schema_printer(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag)
{
- lysc_print_extension_instance(ctx, ext, flag);
+ lyplg_ext_print_extension_instance(ctx, ext, flag);
return LY_SUCCESS;
}
/**
+ * @brief Free parsed yang-data extension instance data.
+ *
+ * Implementation of ::lyplg_clb_parse_free_clb callback set as lyext_plugin::pfree.
+ */
+static void
+yangdata_pfree(const struct ly_ctx *ctx, struct lysp_ext_instance *ext)
+{
+ lyplg_ext_pfree_instance_substatements(ctx, ext->substmts);
+}
+
+/**
+ * @brief Free compiled yang-data extension instance data.
+ *
+ * Implementation of ::lyplg_clb_compile_free_clb callback set as lyext_plugin::cfree.
+ */
+static void
+yangdata_cfree(const struct ly_ctx *ctx, struct lysc_ext_instance *ext)
+{
+ lyplg_ext_cfree_instance_substatements(ctx, ext->substmts);
+}
+
+/**
* @brief Plugin descriptions for the yang-data extension
*
* Note that external plugins are supposed to use:
@@ -167,13 +211,15 @@
.revision = "2017-01-26",
.name = "yang-data",
- .plugin.id = "libyang 2 - yang-data, version 1",
+ .plugin.id = "ly2 yang-data v1",
+ .plugin.parse = yangdata_parse,
.plugin.compile = yangdata_compile,
.plugin.sprinter = yangdata_schema_printer,
- .plugin.free = yangdata_free,
.plugin.node = NULL,
.plugin.snode = NULL,
- .plugin.validate = NULL
+ .plugin.validate = NULL,
+ .plugin.pfree = yangdata_pfree,
+ .plugin.cfree = yangdata_cfree
},
{0} /* terminating zeroed record */
};
diff --git a/src/plugins_exts_compile.h b/src/plugins_exts_compile.h
deleted file mode 100644
index 0fbe43b..0000000
--- a/src/plugins_exts_compile.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * @file plugins_exts_compile.h
- * @author Radek Krejci <rkrejci@cesnet.cz>
- * @brief libyang support for YANG extensions implementation - schema compilation related items.
- *
- * Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
- *
- * This source code is licensed under BSD 3-Clause License (the "License").
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-
-#ifndef LY_PLUGINS_EXTS_COMPILE_H_
-#define LY_PLUGINS_EXTS_COMPILE_H_
-
-#include <stdint.h>
-
-#include "log.h"
-#include "tree_schema.h"
-
-struct ly_ctx;
-struct lysc_ctx;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup pluginsExtensionsCompile Plugins: Extensions compilation support
- * @ingroup pluginsExtensions
- *
- * Helper functions to implement extension plugin's compile callback.
- *
- * @{
- */
-
-/**
- * @defgroup scflags Schema compile flags
- *
- * Flags to modify schema compilation process and change the way how the particular statements are being compiled. *
- * @{
- */
-#define LYS_COMPILE_GROUPING 0x01 /**< Compiling (validation) of a non-instantiated grouping.
- In this case not all the restrictions are checked since they can
- be valid only in the real placement of the grouping. This is
- the case of any restriction that needs to look out of the statements
- themselves, since the context is not known. */
-#define LYS_COMPILE_DISABLED 0x02 /**< Compiling a disabled subtree (by its if-features). Meaning
- it will be removed at the end of compilation and should not be
- added to any unres sets. */
-#define LYS_COMPILE_NO_CONFIG 0x04 /**< ignore config statements, neither inherit config value */
-#define LYS_COMPILE_NO_DISABLED 0x08 /**< ignore if-feature statements */
-
-#define LYS_COMPILE_RPC_INPUT (LYS_IS_INPUT | LYS_COMPILE_NO_CONFIG) /**< Internal option when compiling schema tree of RPC/action input */
-#define LYS_COMPILE_RPC_OUTPUT (LYS_IS_OUTPUT | LYS_COMPILE_NO_CONFIG) /**< Internal option when compiling schema tree of RPC/action output */
-#define LYS_COMPILE_NOTIFICATION (LYS_IS_NOTIF | LYS_COMPILE_NO_CONFIG) /**< Internal option when compiling schema tree of Notification */
-
-/** @} scflags */
-
-/**
- * @brief YANG schema compilation context for use in ::lyplg_ext_compile_clb callback implementation.
- *
- * The structure stores complex information connected with the schema compilation process. In the most simple case,
- * the callback is just supposed to pass the provided callback to ::lys_compile_extension_instance() functions.
- *
- * To access various items from the context, use some of the following lysc_ctx_get_* getters.
- */
-struct lysc_ctx;
-
-/**
- * @brief YANG schema compilation context getter for libyang context.
- * @param[in] ctx YANG schema compilation context.
- * @return libyang context connected with the compilation context.
- */
-LIBYANG_API_DECL struct ly_ctx *lysc_ctx_get_ctx(const struct lysc_ctx *ctx);
-
-/**
- * @brief YANG schema compilation context getter for compilation options.
- * @param[in] ctx YANG schema compilation context.
- * @return pointer to the compilation options to allow modifying them with @ref scflags values.
- */
-LIBYANG_API_DECL uint32_t *lysc_ctx_get_options(const struct lysc_ctx *ctx);
-
-/**
- * @brief YANG schema compilation context getter for path being currently processed.
- * @param[in] ctx YANG schema compilation context.
- * @return path identifying the place in schema being currently processed by the schema compiler.
- */
-LIBYANG_API_DECL const char *lysc_ctx_get_path(const struct lysc_ctx *ctx);
-
-/**
- * @brief YANG schema compilation context getter for current module.
- * @param[in] ctx YANG schema compilation context.
- * @return current module.
- */
-LIBYANG_API_DECL const struct lys_module *lysc_ctx_get_cur_mod(const struct lysc_ctx *ctx);
-
-/**
- * @brief YANG schema compilation context getter for currently processed module.
- * @param[in] ctx YANG schema compilation context.
- * @return Currently processed module.
- */
-LIBYANG_API_DECL struct lysp_module *lysc_ctx_get_pmod(const struct lysc_ctx *ctx);
-
-/**
- * @brief Compile substatements of an extension instance.
- *
- * Uses standard libyang schema compiler to transform YANG statements into the compiled schema structures. The plugins are
- * supposed to use this function when the extension instance's substatements are supposed to be compiled in a standard way
- * (or if just the @ref scflags are enough to modify the compilation process).
- *
- * @param[in] ctx Compile context.
- * @param[in] ext_p Parsed representation of the extension instance being processed.
- * @param[in,out] ext Compiled extension instance with the prepared ::lysc_ext_instance.substmts array, which will be updated
- * by storing the compiled data.
- * @return LY_SUCCESS on success.
- * @return LY_EVALID if compilation of the substatements fails.
- * @return LY_ENOT if the extension is disabled (by if-feature) and should be ignored.
- */
-LIBYANG_API_DECL LY_ERR lys_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p,
- struct lysc_ext_instance *ext);
-
-/**
- * @brief Compile substatements of an extension instance but append all schema data nodes as augments.
- *
- * Similar to ::lys_compile_extension_instance().
- *
- * @param[in] ctx Compile context.
- * @param[in] ext_p Parsed representation of the extension instance being processed.
- * @param[in,out] ext Compiled extension instance with the prepared ::lysc_ext_instance.substmts array, which will be updated
- * by storing the compiled data except for schema data nodes.
- * @param[in] aug_target Augment target node to append schema data nodes.
- * @return LY_SUCCESS on success.
- * @return LY_EVALID if compilation of the substatements fails.
- * @return LY_ENOT if the extension is disabled (by if-feature) and should be ignored.
- */
-LIBYANG_API_DECL LY_ERR lys_compile_extension_instance_augment(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p,
- struct lysc_ext_instance *ext, struct lysc_node *aug_target);
-
-/**
- * @brief Find augment target in an extension.
- *
- * @param[in] ctx Compile context.
- * @param[in] path Absolute-schema-nodeid representing the augment target. The first segment is expected to identify
- * the specific extension instance.
- * @param[out] aug_ext Optional augment target extension.
- * @param[out] aug_target Augment target compiled schema node.
- * @return LY_ERR value.
- */
-LIBYANG_API_DECL LY_ERR lys_compile_extension_instance_find_augment_target(struct lysc_ctx *ctx, const char *path,
- struct lysc_ext_instance **aug_ext, struct lysc_node **aug_target);
-
-/**
- * @brief Update path in the compile context, which is used for logging where the compilation failed.
- *
- * @param[in] ctx Compile context with the path.
- * @param[in] parent_module Module of the current node's parent to check difference with the currently processed module (taken from @p ctx).
- * @param[in] name Name of the node to update path with. If NULL, the last segment is removed. If the format is `{keyword}`, the following
- * call updates the segment to the form `{keyword='name'}` (to remove this compound segment, 2 calls with NULL @p name must be used).
- */
-LIBYANG_API_DECL void lysc_update_path(struct lysc_ctx *ctx, struct lys_module *parent_module, const char *name);
-
-/**
- * @brief Duplicate the compiled extension (definition) structure.
- *
- * @param[in] orig The extension structure to duplicate.
- * @return The duplicated structure to use.
- */
-LIBYANG_API_DECL struct lysc_ext *lysc_ext_dup(struct lysc_ext *orig);
-
-/** @} extensions */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LY_PLUGINS_EXTS_COMPILE_H_ */
diff --git a/src/plugins_exts_print.h b/src/plugins_exts_print.h
deleted file mode 100644
index aed3b36..0000000
--- a/src/plugins_exts_print.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * @file plugins_exts_print.h
- * @author Radek Krejci <rkrejci@cesnet.cz>
- * @brief libyang support for YANG extensions implementation - schema print related items.
- *
- * Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
- *
- * This source code is licensed under BSD 3-Clause License (the "License").
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-
-#ifndef LY_PLUGINS_EXTS_PRINT_H_
-#define LY_PLUGINS_EXTS_PRINT_H_
-
-#include <stdint.h>
-
-#include "config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup pluginsExtensionsPrint Plugins: Extensions printer support
- * @ingroup pluginsExtensions
- *
- * Helper functions to implement extension plugin's sprinter callback.
- *
- * @{
- */
-
-/**
- * @brief YANG printer context for use in ::lyplg_ext_schema_printer_clb callback implementation.
- *
- * The structure provides basic information how the compiled schema is supposed to be printed and where. In the most simple
- * case, the provided context is just passed into ::lysc_print_extension_instance() function which handles printing the
- * extension's substatements in the standard way.
- *
- * To access various items from the context, use some of the following lys_ypr_ctx_get_* getters.
- */
-struct lyspr_ctx;
-
-/**
- * @brief YANG printer context getter for output handler.
- * @param[in] ctx YANG printer context.
- * @return Output handler where the data are being printed. Note that the address of the handler pointer in the context is
- * returned to allow to modify the handler.
- */
-LIBYANG_API_DECL struct ly_out **lys_ypr_ctx_get_out(const struct lyspr_ctx *ctx);
-
-/**
- * @brief YANG printer context getter for printer options.
- * @param[in] ctx YANG printer context.
- * @return pointer to the printer options to allow modifying them with @ref schemaprinterflags values.
- */
-LIBYANG_API_DECL uint32_t *lys_ypr_ctx_get_options(const struct lyspr_ctx *ctx);
-
-/**
- * @brief YANG printer context getter for printer indentation level.
- * @param[in] ctx YANG printer context.
- * @return pointer to the printer's indentation level to allow modifying its value.
- */
-LIBYANG_API_DECL uint16_t *lys_ypr_ctx_get_level(const struct lyspr_ctx *ctx);
-
-/**
- * @brief Print substatements of an extension instance
- *
- * Generic function to access YANG printer functions from the extension plugins (::lyplg_ext_schema_printer_clb).
- *
- * @param[in] ctx YANG printer context to provide output handler and other information for printing.
- * @param[in] ext The compiled extension instance to access the extensions and substatements data.
- * @param[in, out] flag Flag to be shared with the caller regarding the opening brackets - 0 if the '{' not yet printed,
- * 1 otherwise.
- */
-LIBYANG_API_DECL void lysc_print_extension_instance(struct lyspr_ctx *ctx, const struct lysc_ext_instance *ext, ly_bool *flag);
-
-/** @} pluginsExtensionsPrint */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LY_PLUGINS_EXTS_PRINT_H_ */
diff --git a/src/printer_yang.c b/src/printer_yang.c
index 01ffa34..4cab943 100644
--- a/src/printer_yang.c
+++ b/src/printer_yang.c
@@ -28,7 +28,6 @@
#include "out.h"
#include "out_internal.h"
#include "plugins_exts.h"
-#include "plugins_exts_print.h"
#include "plugins_types.h"
#include "printer_internal.h"
#include "printer_schema.h"
@@ -246,22 +245,15 @@
{
struct lysp_stmt *stmt;
ly_bool child_presence;
- struct lysp_ext *ext_def;
if ((ext->flags & LYS_INTERNAL) || (ext->parent_stmt != substmt) || (ext->parent_stmt_index != substmt_index)) {
return;
}
- lysp_ext_find_definition(pctx->module->ctx, ext, NULL, &ext_def);
- if (!ext_def) {
- return;
- }
-
ypr_open(pctx->out, flag);
- if (ext_def->argname) {
+ if (ext->def->argname) {
ly_print_(pctx->out, "%*s%s \"", INDENT, ext->name);
- lysp_ext_instance_resolve_argument(pctx->module->ctx, ext, ext_def);
ypr_encode(pctx->out, ext->argument, -1);
ly_print_(pctx->out, "\"");
} else {
@@ -606,7 +598,7 @@
text = ((restr->arg.str[0] != LYSP_RESTR_PATTERN_NACK) && (restr->arg.str[0] != LYSP_RESTR_PATTERN_ACK)) ?
restr->arg.str : restr->arg.str + 1;
singleline = strchr(text, '\n') ? 0 : 1;
- ypr_text(pctx, ly_stmt2str(stmt), text, singleline, 0);
+ ypr_text(pctx, lyplg_ext_stmt2str(stmt), text, singleline, 0);
LEVEL++;
yprp_extension_instances(pctx, stmt, 0, restr->exts, &inner_flag);
@@ -1124,7 +1116,7 @@
ly_print_(pctx->out, "\n%*s%s {\n", INDENT, inout->name);
LEVEL++;
- yprc_extension_instances(pctx, lys_nodetype2stmt(inout->nodetype), 0, inout->exts, NULL);
+ yprc_extension_instances(pctx, lyplg_ext_nodetype2stmt(inout->nodetype), 0, inout->exts, NULL);
LY_ARRAY_FOR(inout->musts, u) {
yprc_must(pctx, &inout->musts[u], NULL);
}
@@ -1219,7 +1211,7 @@
ly_print_(pctx->out, "%*s%s %s", INDENT, action->parent ? "action" : "rpc", action->name);
LEVEL++;
- yprp_extension_instances(pctx, lys_nodetype2stmt(action->nodetype), 0, action->exts, &flag);
+ yprp_extension_instances(pctx, lyplg_ext_nodetype2stmt(action->nodetype), 0, action->exts, &flag);
yprp_iffeatures(pctx, action->iffeatures, action->exts, &flag);
ypr_status(pctx, action->flags, action->exts, &flag);
ypr_description(pctx, action->dsc, action->exts, &flag);
@@ -1258,7 +1250,7 @@
ly_print_(pctx->out, "%*s%s %s", INDENT, action->parent ? "action" : "rpc", action->name);
LEVEL++;
- yprc_extension_instances(pctx, lys_nodetype2stmt(action->nodetype), 0, action->exts, &flag);
+ yprc_extension_instances(pctx, lyplg_ext_nodetype2stmt(action->nodetype), 0, action->exts, &flag);
ypr_status(pctx, action->flags, action->exts, &flag);
ypr_description(pctx, action->dsc, action->exts, &flag);
ypr_reference(pctx, action->ref, action->exts, &flag);
@@ -1276,7 +1268,7 @@
ly_print_(pctx->out, "%*s%s %s%s", INDENT, lys_nodetype2str(node->nodetype), node->name, flag ? "" : " {\n");
LEVEL++;
- yprp_extension_instances(pctx, lys_nodetype2stmt(node->nodetype), 0, node->exts, flag);
+ yprp_extension_instances(pctx, lyplg_ext_nodetype2stmt(node->nodetype), 0, node->exts, flag);
yprp_when(pctx, lysp_node_when(node), flag);
yprp_iffeatures(pctx, node->iffeatures, node->exts, flag);
}
@@ -1290,7 +1282,7 @@
ly_print_(pctx->out, "%*s%s %s%s", INDENT, lys_nodetype2str(node->nodetype), node->name, flag ? "" : " {\n");
LEVEL++;
- yprc_extension_instances(pctx, lys_nodetype2stmt(node->nodetype), 0, node->exts, flag);
+ yprc_extension_instances(pctx, lyplg_ext_nodetype2stmt(node->nodetype), 0, node->exts, flag);
when = lysc_node_when(node);
LY_ARRAY_FOR(when, u) {
@@ -2456,7 +2448,7 @@
}
LIBYANG_API_DEF void
-lysc_print_extension_instance(struct lyspr_ctx *ctx_generic, const struct lysc_ext_instance *ext, ly_bool *flag)
+lyplg_ext_print_extension_instance(struct lyspr_ctx *ctx_generic, const struct lysc_ext_instance *ext, ly_bool *flag)
{
struct lys_ypr_ctx *pctx = (struct lys_ypr_ctx *)ctx_generic;
LY_ARRAY_COUNT_TYPE u, v;
@@ -2536,7 +2528,7 @@
/* TODO support other substatements */
default:
LOGWRN(pctx->module->ctx, "Statement \"%s\" is not supported for an extension printer.",
- ly_stmt2str(ext->substmts[u].stmt));
+ lyplg_ext_stmt2str(ext->substmts[u].stmt));
break;
}
}
diff --git a/src/printer_yin.c b/src/printer_yin.c
index 88f9178..db54819 100644
--- a/src/printer_yin.c
+++ b/src/printer_yin.c
@@ -129,27 +129,17 @@
{
struct lysp_stmt *stmt;
int8_t inner_flag;
- struct lysp_ext *ext_def;
if ((ext->flags & LYS_INTERNAL) || (ext->parent_stmt != substmt) || (ext->parent_stmt_index != substmt_index)) {
return;
}
- lysp_ext_find_definition(pctx->module->ctx, ext, NULL, &ext_def);
- if (!ext_def) {
- return;
- }
-
ypr_close_parent(pctx, flag);
inner_flag = 0;
- if (ext_def->argname) {
- lysp_ext_instance_resolve_argument(pctx->module->ctx, ext, ext_def);
- }
-
- ypr_open(pctx, ext->name, (ext_def->flags & LYS_YINELEM_TRUE) ? NULL : ext_def->argname, ext->argument, inner_flag);
+ ypr_open(pctx, ext->name, (ext->def->flags & LYS_YINELEM_TRUE) ? NULL : ext->def->argname, ext->argument, inner_flag);
LEVEL++;
- if (ext_def->flags & LYS_YINELEM_TRUE) {
+ if (ext->def->flags & LYS_YINELEM_TRUE) {
const char *prefix, *name, *id;
size_t prefix_len, name_len;
@@ -158,9 +148,9 @@
/* we need to use the same namespace as for the extension instance element */
id = ext->name;
ly_parse_nodeid(&id, &prefix, &prefix_len, &name, &name_len);
- ly_print_(pctx->out, "%*s<%.*s:%s>", INDENT, (int)prefix_len, prefix, ext_def->argname);
+ ly_print_(pctx->out, "%*s<%.*s:%s>", INDENT, (int)prefix_len, prefix, ext->def->argname);
lyxml_dump_text(pctx->out, ext->argument, 0);
- ly_print_(pctx->out, "</%.*s:%s>\n", (int)prefix_len, prefix, ext_def->argname);
+ ly_print_(pctx->out, "</%.*s:%s>\n", (int)prefix_len, prefix, ext->def->argname);
}
LY_LIST_FOR(ext->child, stmt) {
if (stmt->flags & (LYS_YIN_ATTR | LYS_YIN_ARGUMENT)) {
@@ -425,7 +415,7 @@
return;
}
- ly_print_(pctx->out, "%*s<%s %s=\"", INDENT, ly_stmt2str(stmt), attr);
+ ly_print_(pctx->out, "%*s<%s %s=\"", INDENT, lyplg_ext_stmt2str(stmt), attr);
lyxml_dump_text(pctx->out,
(restr->arg.str[0] != LYSP_RESTR_PATTERN_NACK && restr->arg.str[0] != LYSP_RESTR_PATTERN_ACK) ?
restr->arg.str : &restr->arg.str[1], 1);
@@ -450,7 +440,7 @@
ypr_reference(pctx, restr->ref, restr->exts, &inner_flag);
LEVEL--;
- ypr_close(pctx, ly_stmt2str(stmt), inner_flag);
+ ypr_close(pctx, lyplg_ext_stmt2str(stmt), inner_flag);
}
static void
@@ -657,7 +647,7 @@
ypr_open(pctx, inout->name, NULL, NULL, *flag);
LEVEL++;
- yprp_extension_instances(pctx, lys_nodetype2stmt(inout->nodetype), 0, inout->exts, NULL);
+ yprp_extension_instances(pctx, lyplg_ext_nodetype2stmt(inout->nodetype), 0, inout->exts, NULL);
LY_ARRAY_FOR(inout->musts, u) {
yprp_restr(pctx, &inout->musts[u], LY_STMT_MUST, "condition", NULL);
}
@@ -727,7 +717,7 @@
ypr_open(pctx, action->parent ? "action" : "rpc", "name", action->name, flag);
LEVEL++;
- yprp_extension_instances(pctx, lys_nodetype2stmt(action->nodetype), 0, action->exts, &flag);
+ yprp_extension_instances(pctx, lyplg_ext_nodetype2stmt(action->nodetype), 0, action->exts, &flag);
yprp_iffeatures(pctx, action->iffeatures, action->exts, &flag);
ypr_status(pctx, action->flags, action->exts, &flag);
ypr_description(pctx, action->dsc, action->exts, &flag);
@@ -756,7 +746,7 @@
ypr_open(pctx, lys_nodetype2str(node->nodetype), "name", node->name, *flag);
LEVEL++;
- yprp_extension_instances(pctx, lys_nodetype2stmt(node->nodetype), 0, node->exts, flag);
+ yprp_extension_instances(pctx, lyplg_ext_nodetype2stmt(node->nodetype), 0, node->exts, flag);
yprp_when(pctx, lysp_node_when(node), flag);
yprp_iffeatures(pctx, node->iffeatures, node->exts, flag);
}
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 5264095..f6f1b49 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -34,7 +34,6 @@
#include "path.h"
#include "plugins.h"
#include "plugins_exts.h"
-#include "plugins_exts_compile.h"
#include "plugins_internal.h"
#include "plugins_types.h"
#include "schema_compile_amend.h"
@@ -50,37 +49,43 @@
/**
* @brief Fill in the prepared compiled extensions definition structure according to the parsed extension definition.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] extp Parsed extension instance.
+ * @param[out] ext Compiled extension definition.
+ * @return LY_ERR value.
*/
static LY_ERR
-lys_compile_extension(struct lysc_ctx *ctx, const struct lys_module *ext_mod, struct lysp_ext *ext_p,
- const struct lyplg_ext_record *record, struct lysc_ext **ext)
+lys_compile_extension(struct lysc_ctx *ctx, struct lysp_ext_instance *extp, struct lysc_ext **ext)
{
LY_ERR ret = LY_SUCCESS;
+ struct lysp_ext *ep = extp->def;
- if (!ext_p->compiled) {
+ if (!ep->compiled) {
lysc_update_path(ctx, NULL, "{extension}");
- lysc_update_path(ctx, NULL, ext_p->name);
+ lysc_update_path(ctx, NULL, ep->name);
/* compile the extension definition */
- *ext = ext_p->compiled = calloc(1, sizeof **ext);
+ *ext = ep->compiled = calloc(1, sizeof **ext);
(*ext)->refcount = 1;
- DUP_STRING_GOTO(ctx->ctx, ext_p->name, (*ext)->name, ret, done);
- DUP_STRING_GOTO(ctx->ctx, ext_p->argname, (*ext)->argname, ret, done);
- (*ext)->module = (struct lys_module *)ext_mod;
+ DUP_STRING_GOTO(ctx->ctx, ep->name, (*ext)->name, ret, cleanup);
+ DUP_STRING_GOTO(ctx->ctx, ep->argname, (*ext)->argname, ret, cleanup);
+ LY_CHECK_GOTO(ret = lysp_ext_find_definition(ctx->ctx, extp, (const struct lys_module **)&(*ext)->module, NULL),
+ cleanup);
/* compile nested extensions */
- COMPILE_EXTS_GOTO(ctx, ext_p->exts, (*ext)->exts, *ext, ret, done);
+ COMPILE_EXTS_GOTO(ctx, ep->exts, (*ext)->exts, *ext, ret, cleanup);
lysc_update_path(ctx, NULL, NULL);
lysc_update_path(ctx, NULL, NULL);
/* find extension definition plugin */
- (*ext)->plugin = record ? (struct lyplg_ext *)&record->plugin : NULL;
+ (*ext)->plugin = extp->record ? (struct lyplg_ext *)&extp->record->plugin : NULL;
}
- *ext = ext_p->compiled;
+ *ext = ep->compiled;
-done:
+cleanup:
if (ret) {
lysc_update_path(ctx, NULL, NULL);
lysc_update_path(ctx, NULL, NULL);
@@ -89,34 +94,29 @@
}
LY_ERR
-lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext, void *parent,
- const struct lys_module *ext_mod)
+lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *extp, struct lysc_ext_instance *ext, void *parent)
{
LY_ERR ret = LY_SUCCESS;
- struct lysp_ext *ext_def;
- ext->parent_stmt = ext_p->parent_stmt;
- ext->parent_stmt_index = ext_p->parent_stmt_index;
+ DUP_STRING_GOTO(ctx->ctx, extp->argument, ext->argument, ret, cleanup);
ext->module = ctx->cur_mod;
ext->parent = parent;
+ ext->parent_stmt = extp->parent_stmt;
+ ext->parent_stmt_index = extp->parent_stmt_index;
- lysc_update_path(ctx, LY_STMT_IS_NODE(ext->parent_stmt) ? ((struct lysc_node *)ext->parent)->module : NULL, "{extension}");
- lysc_update_path(ctx, NULL, ext_p->name);
+ lysc_update_path(ctx, (ext->parent_stmt & LY_STMT_NODE_MASK) ? ((struct lysc_node *)ext->parent)->module : NULL,
+ "{extension}");
+ lysc_update_path(ctx, NULL, extp->name);
- LY_CHECK_GOTO(ret = lysp_ext_find_definition(ctx->ctx, ext_p, &ext_mod, &ext_def), cleanup);
- LY_CHECK_GOTO(ret = lys_compile_extension(ctx, ext_mod, ext_def, ext_p->record, &ext->def), cleanup);
+ /* compile extension if not already */
+ LY_CHECK_GOTO(ret = lys_compile_extension(ctx, extp, &ext->def), cleanup);
- if (ext_def->argname) {
- LY_CHECK_GOTO(ret = lysp_ext_instance_resolve_argument(ctx->ctx, ext_p, ext_def), cleanup);
- }
-
- DUP_STRING_GOTO(ctx->ctx, ext_p->argument, ext->argument, ret, cleanup);
-
+ /* compile */
if (ext->def->plugin && ext->def->plugin->compile) {
if (ext->argument) {
lysc_update_path(ctx, ext->module, ext->argument);
}
- ret = ext->def->plugin->compile(ctx, ext_p, ext);
+ ret = ext->def->plugin->compile(ctx, extp, ext);
if (ret == LY_ENOT) {
lysc_ext_instance_free(&ctx->free_ctx, ext);
}
@@ -139,38 +139,6 @@
return orig;
}
-LIBYANG_API_DEF LY_ERR
-lysc_ext_substmt(const struct lysc_ext_instance *ext, enum ly_stmt substmt, void **instance_p)
-{
- LY_ARRAY_COUNT_TYPE u;
-
- if (instance_p) {
- *instance_p = NULL;
- }
-
- LY_ARRAY_FOR(ext->substmts, u) {
- if (LY_STMT_IS_DATA_NODE(substmt)) {
- if (!LY_STMT_IS_DATA_NODE(ext->substmts[u].stmt)) {
- continue;
- }
- } else if (LY_STMT_IS_OP(substmt)) {
- if (!LY_STMT_IS_OP(ext->substmts[u].stmt)) {
- continue;
- }
- } else if (ext->substmts[u].stmt != substmt) {
- continue;
- }
-
- /* match */
- if (instance_p) {
- *instance_p = ext->substmts[u].storage;
- }
- return LY_SUCCESS;
- }
-
- return LY_ENOT;
-}
-
static void
lysc_unres_must_free(struct lysc_unres_must *m)
{
@@ -251,21 +219,7 @@
LOG_LOCSET(NULL, NULL, ctx->path, NULL);
}
-/**
- * @brief Compile information from the identity statement
- *
- * The backlinks to the identities derived from this one are supposed to be filled later via ::lys_compile_identity_bases().
- *
- * @param[in] ctx_sc Compile context - alternative to the combination of @p ctx and @p parsed_mod.
- * @param[in] ctx libyang context.
- * @param[in] parsed_mod Module with the identities.
- * @param[in] identities_p Array of the parsed identity definitions to precompile.
- * @param[in,out] identities Pointer to the storage of the (pre)compiled identities array where the new identities are
- * supposed to be added. The storage is supposed to be initiated to NULL when the first parsed identities are going
- * to be processed.
- * @return LY_ERR value.
- */
-static LY_ERR
+LY_ERR
lys_identity_precompile(struct lysc_ctx *ctx_sc, struct ly_ctx *ctx, struct lysp_module *parsed_mod,
const struct lysp_ident *identities_p, struct lysc_ident **identities)
{
@@ -445,6 +399,7 @@
/**
* @brief For the given array of identities, set the backlinks from all their base identities.
+ *
* @param[in] ctx Compile context, not only for logging but also to get the current module to resolve prefixes.
* @param[in] idents_p Array of identities definitions from the parsed schema structure.
* @param[in,out] idents Array of referencing identities to which the backlinks are supposed to be set.
@@ -479,259 +434,6 @@
return LY_SUCCESS;
}
-const void *
-lys_compile_ext_instance_get_storage(const struct lysc_ext_instance *ext, enum ly_stmt stmt)
-{
- LY_ARRAY_COUNT_TYPE u;
-
- LY_ARRAY_FOR(ext->substmts, u) {
- if (ext->substmts[u].stmt == stmt) {
- return ext->substmts[u].storage;
- }
- }
- return NULL;
-}
-
-/**
- * @brief Store (parse/compile) an instance extension statement.
- *
- * @param[in] ctx Compile context.
- * @param[in] ext_p Parsed ext instance.
- * @param[in] ext Compiled ext instance.
- * @param[in] substmt Compled ext instance substatement info.
- * @param[in] stmt Parsed statement to process.
- * @param[in,out] aug_target Optional augment target where to append all schema data nodes.
- * @return LY_ERR value.
- */
-static LY_ERR
-lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext,
- struct lysc_ext_substmt *substmt, struct lysp_stmt *stmt, struct lysc_node *aug_target)
-{
- LY_ERR rc = LY_SUCCESS;
- struct lysf_ctx fctx = {.ctx = ctx->ctx};
- struct lysp_restr *restrs = NULL;
- struct lysp_qname *qname = NULL;
- struct lysp_type *ptype = NULL;
-
- if (!substmt->storage) {
- /* nothing to store (parse/compile) */
- goto cleanup;
- }
-
- switch (stmt->kw) {
- case LY_STMT_ACTION:
- case LY_STMT_ANYDATA:
- case LY_STMT_ANYXML:
- case LY_STMT_CONTAINER:
- case LY_STMT_CHOICE:
- case LY_STMT_LEAF:
- case LY_STMT_LEAF_LIST:
- case LY_STMT_LIST:
- case LY_STMT_NOTIFICATION:
- case LY_STMT_RPC:
- case LY_STMT_USES: {
- struct lysp_node **pnodes_p, *pnode = NULL;
- const uint16_t *flags = lys_compile_ext_instance_get_storage(ext, LY_STMT_STATUS);
-
- /* parse the node */
- LY_CHECK_GOTO(rc = lysp_stmt_parse(ctx, stmt, (void **)&pnode, NULL), cleanup);
-
- /* store it together with all the parsed schema nodes */
- pnodes_p = &((struct lysp_ext_instance *)ext_p)->parsed;
- while (*pnodes_p) {
- pnodes_p = &(*pnodes_p)->next;
- }
- *pnodes_p = pnode;
-
- if (aug_target) {
- /* augment nodes */
- ((struct lysp_ext_instance *)ext_p)->flags |= LYS_EXT_PARSED_AUGMENT;
-
- /* compile augmented nodes */
- LY_CHECK_GOTO(rc = lys_compile_augment_children(ctx, NULL, 0, pnode, aug_target, 0), cleanup);
- } else {
- /* compile nodes, ctx->ext substatement storage is used as the document root */
- LY_CHECK_GOTO(rc = lys_compile_node(ctx, pnode, NULL, flags, NULL), cleanup);
- }
- break;
- }
- case LY_STMT_GROUPING: {
- struct lysp_node_grp **groupings_p, *grp = NULL;
-
- /* parse the grouping */
- LY_CHECK_GOTO(rc = lysp_stmt_parse(ctx, stmt, (void **)&grp, NULL), cleanup);
-
- /* store it with all the other groupings */
- groupings_p = substmt->storage;
- while (*groupings_p) {
- groupings_p = &(*groupings_p)->next;
- }
- *groupings_p = grp;
- break;
- }
- case LY_STMT_CONTACT:
- case LY_STMT_DESCRIPTION:
- case LY_STMT_ERROR_APP_TAG:
- case LY_STMT_ERROR_MESSAGE:
- case LY_STMT_KEY:
- case LY_STMT_NAMESPACE:
- case LY_STMT_ORGANIZATION:
- case LY_STMT_PRESENCE:
- case LY_STMT_REFERENCE:
- case LY_STMT_UNITS: {
- const char **str_p;
-
- /* single item */
- str_p = substmt->storage;
- if (*str_p) {
- LOGVAL(ctx->ctx, LY_VCODE_DUPSTMT, stmt->stmt);
- rc = LY_EVALID;
- goto cleanup;
- }
-
- /* called instead of lysp_stmt_parse() to skip validation and not parse nested ext instances */
- LY_CHECK_GOTO(rc = lydict_insert(ctx->ctx, stmt->arg, 0, str_p), cleanup);
- break;
- }
- case LY_STMT_MUST: {
- struct lysc_must **musts_p, *must;
-
- /* parse */
- LY_CHECK_GOTO(rc = lysp_stmt_parse(ctx, stmt, (void **)&restrs, NULL), cleanup);
-
- /* sized array */
- musts_p = substmt->storage;
- LY_ARRAY_NEW_GOTO(ctx->ctx, *musts_p, must, rc, cleanup);
-
- /* compile */
- LY_CHECK_GOTO(rc = lys_compile_must(ctx, restrs, must), cleanup);
- break;
- }
- case LY_STMT_IF_FEATURE: {
- ly_bool enabled;
-
- LY_CHECK_GOTO(rc = lysp_stmt_parse(ctx, stmt, (void **)&qname, NULL), cleanup);
- LY_CHECK_GOTO(rc = lys_eval_iffeatures(ctx->ctx, qname, &enabled), cleanup);
- if (!enabled) {
- /* it is disabled, remove the whole extension instance */
- return LY_ENOT;
- }
- break;
- }
- case LY_STMT_STATUS:
- /* result needs to be a pointer to pointer */
- LY_CHECK_GOTO(rc = lysp_stmt_parse(ctx, stmt, &substmt->storage, NULL), cleanup);
- break;
-
- case LY_STMT_TYPEDEF:
- /* parse */
- LY_CHECK_GOTO(rc = lysp_stmt_parse(ctx, stmt, substmt->storage, NULL), cleanup);
- break;
-
- case LY_STMT_TYPE: {
- struct lysc_type **type_p;
- const uint16_t *flags = lys_compile_ext_instance_get_storage(ext, LY_STMT_STATUS);
- const char **units = (void *)lys_compile_ext_instance_get_storage(ext, LY_STMT_UNITS);
-
- /* single item */
- type_p = substmt->storage;
- if (*type_p) {
- LOGVAL(ctx->ctx, LY_VCODE_DUPSTMT, stmt->stmt);
- rc = LY_EVALID;
- goto cleanup;
- }
-
- LY_CHECK_GOTO(rc = lysp_stmt_parse(ctx, stmt, (void **)&ptype, NULL), cleanup);
- LY_CHECK_GOTO(rc = lys_compile_type(ctx, NULL, flags ? *flags : 0, ext_p->name, ptype, type_p,
- (units && !*units) ? units : NULL, NULL), cleanup);
- break;
- }
- /* TODO support other substatements (parse stmt to lysp and then compile lysp to lysc),
- * also note that in many statements their extensions are not taken into account */
- default:
- LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Statement \"%s\" is not supported as an extension "
- "(found in \"%s%s%s\") substatement.", stmt->stmt, ext_p->name, ext_p->argument ? " " : "",
- ext_p->argument ? ext_p->argument : "");
- rc = LY_EVALID;
- goto cleanup;
- }
-
-cleanup:
- FREE_ARRAY(&fctx, restrs, lysp_restr_free);
- FREE_ARRAY(ctx->ctx, qname, lysp_qname_free);
- lysp_type_free(&ctx->free_ctx, ptype);
- free(ptype);
- return rc;
-}
-
-static LY_ERR
-lys_compile_extension_instance_(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext,
- struct lysc_node *aug_target)
-{
- LY_ERR rc = LY_SUCCESS;
- LY_ARRAY_COUNT_TYPE u;
- struct lysp_stmt *stmt;
-
- /* check for invalid substatements */
- for (stmt = ext_p->child; stmt; stmt = stmt->next) {
- if (stmt->flags & (LYS_YIN_ATTR | LYS_YIN_ARGUMENT)) {
- continue;
- }
- LY_ARRAY_FOR(ext->substmts, u) {
- if (ext->substmts[u].stmt == stmt->kw) {
- break;
- }
- }
- if (u == LY_ARRAY_COUNT(ext->substmts)) {
- LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s%s%s\" extension instance.",
- stmt->stmt, ext_p->name, ext_p->argument ? " " : "", ext_p->argument ? ext_p->argument : "");
- rc = LY_EVALID;
- goto cleanup;
- }
- }
-
- /* TODO store inherited data, e.g. status first, but mark them somehow to allow to overwrite them and not detect duplicity */
-
- /* note into the compile context that we are processing extension now */
- ctx->ext = ext;
-
- /* keep order of the processing the same as the order in the defined substmts,
- * the order is important for some of the statements depending on others (e.g. type needs status and units) */
-
- LY_ARRAY_FOR(ext->substmts, u) {
- for (stmt = ext_p->child; stmt; stmt = stmt->next) {
- if (ext->substmts[u].stmt != stmt->kw) {
- continue;
- }
-
- if ((rc = lys_compile_ext_instance_stmt(ctx, ext_p, ext, &ext->substmts[u], stmt, aug_target))) {
- goto cleanup;
- }
- }
- }
-
-cleanup:
- ctx->ext = NULL;
- return rc;
-}
-
-LIBYANG_API_DEF LY_ERR
-lys_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext)
-{
- LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, ext_p, ext, LY_EINVAL);
-
- return lys_compile_extension_instance_(ctx, ext_p, ext, NULL);
-}
-
-LIBYANG_API_DEF LY_ERR
-lys_compile_extension_instance_augment(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p,
- struct lysc_ext_instance *ext, struct lysc_node *aug_target)
-{
- LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, ext_p, ext, aug_target, LY_EINVAL);
-
- return lys_compile_extension_instance_(ctx, ext_p, ext, aug_target);
-}
-
/**
* @brief Check when for cyclic dependencies.
*
@@ -1857,7 +1559,7 @@
LY_CHECK_GOTO(ret = lys_compile_node(&ctx, pnode, NULL, 0, NULL), cleanup);
}
- /* extension instances */
+ /* module extension instances */
COMPILE_EXTS_GOTO(&ctx, sp->exts, mod_c->exts, mod_c, ret, cleanup);
/* the same for submodules */
diff --git a/src/schema_compile.h b/src/schema_compile.h
index 5d60c26..df58571 100644
--- a/src/schema_compile.h
+++ b/src/schema_compile.h
@@ -170,6 +170,16 @@
} \
}
+#define DUP_ARRAY2(CTX, PMOD, ORIG_ARRAY, NEW_ARRAY, DUP_FUNC) \
+ if (ORIG_ARRAY) { \
+ LY_ARRAY_COUNT_TYPE __u; \
+ LY_ARRAY_CREATE_RET(CTX, NEW_ARRAY, LY_ARRAY_COUNT(ORIG_ARRAY), LY_EMEM); \
+ LY_ARRAY_FOR(ORIG_ARRAY, __u) { \
+ LY_ARRAY_INCREMENT(NEW_ARRAY); \
+ LY_CHECK_RET(DUP_FUNC(CTX, PMOD, &(NEW_ARRAY)[__u], &(ORIG_ARRAY)[__u])); \
+ } \
+ }
+
#define COMPILE_OP_ARRAY_GOTO(CTX, ARRAY_P, ARRAY_C, PARENT, FUNC, USES_STATUS, RET, GOTO) \
if (ARRAY_P) { \
LY_ARRAY_COUNT_TYPE __u = (ARRAY_C) ? LY_ARRAY_COUNT(ARRAY_C) : 0; \
@@ -203,7 +213,7 @@
LY_ARRAY_CREATE_GOTO((CTX)->ctx, EXT_C, __u + LY_ARRAY_COUNT(EXTS_P), RET, GOTO); \
LY_ARRAY_FOR(EXTS_P, __u) { \
LY_ARRAY_INCREMENT(EXT_C); \
- RET = lys_compile_ext(CTX, &(EXTS_P)[__u], &(EXT_C)[LY_ARRAY_COUNT(EXT_C) - 1], PARENT, NULL); \
+ RET = lys_compile_ext(CTX, &(EXTS_P)[__u], &(EXT_C)[LY_ARRAY_COUNT(EXT_C) - 1], PARENT); \
if (RET == LY_ENOT) { \
LY_ARRAY_DECREMENT(EXT_C); \
RET = LY_SUCCESS; \
@@ -217,16 +227,31 @@
* @brief Fill in the prepared compiled extension instance structure according to the parsed extension instance.
*
* @param[in] ctx Compilation context.
- * @param[in] ext_p Parsed extension instance.
+ * @param[in] extp Parsed extension instance.
* @param[in,out] ext Prepared compiled extension instance.
* @param[in] parent Extension instance parent.
- * @param[in] ext_mod Optional module with the extension instance extension definition, set only for internal annotations.
* @return LY_SUCCESS on success.
* @return LY_ENOT if the extension is disabled and should be ignored.
* @return LY_ERR on error.
*/
-LY_ERR lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext, void *parent,
- const struct lys_module *ext_mod);
+LY_ERR lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *extp, struct lysc_ext_instance *ext, void *parent);
+
+/**
+ * @brief Compile information from the identity statement
+ *
+ * The backlinks to the identities derived from this one are supposed to be filled later via ::lys_compile_identity_bases().
+ *
+ * @param[in] ctx_sc Compile context - alternative to the combination of @p ctx and @p parsed_mod.
+ * @param[in] ctx libyang context.
+ * @param[in] parsed_mod Module with the identities.
+ * @param[in] identities_p Array of the parsed identity definitions to precompile.
+ * @param[in,out] identities Pointer to the storage of the (pre)compiled identities array where the new identities are
+ * supposed to be added. The storage is supposed to be initiated to NULL when the first parsed identities are going
+ * to be processed.
+ * @return LY_ERR value.
+ */
+LY_ERR lys_identity_precompile(struct lysc_ctx *ctx_sc, struct ly_ctx *ctx, struct lysp_module *parsed_mod,
+ const struct lysp_ident *identities_p, struct lysc_ident **identities);
/**
* @brief Find and process the referenced base identities from another identity or identityref
@@ -246,15 +271,6 @@
struct lysc_ident *ident, struct lysc_ident ***bases);
/**
- * @brief Get compiled ext instance storage for a specific statement.
- *
- * @param[in] ext Compiled ext instance.
- * @param[in] stmt Stored statement.
- * @return Compiled ext instance substatement storage, NULL if substaement not supported or not stored.
- */
-const void *lys_compile_ext_instance_get_storage(const struct lysc_ext_instance *ext, enum ly_stmt stmt);
-
-/**
* @brief Perform a complet compilation of identites in a module and all its submodules.
*
* @param[in] mod Module to process.
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 6876ea4..66e6a3d 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -26,7 +26,6 @@
#include "common.h"
#include "dict.h"
#include "log.h"
-#include "plugins_exts_compile.h"
#include "schema_compile.h"
#include "schema_compile_node.h"
#include "schema_features.h"
@@ -343,26 +342,40 @@
}
static LY_ERR
-lysp_ext_dup(const struct ly_ctx *ctx, struct lysp_ext_instance *ext, const struct lysp_ext_instance *orig_ext)
+lysp_ext_dup(const struct ly_ctx *ctx, const struct lysp_module *pmod, struct lysp_ext_instance *ext,
+ const struct lysp_ext_instance *orig_ext)
{
- DUP_STRING_RET(ctx, orig_ext->name, ext->name);
- DUP_STRING_RET(ctx, orig_ext->argument, ext->argument);
- ext->format = orig_ext->format;
- ext->parsed = NULL;
- LY_CHECK_RET(ly_dup_prefix_data(ctx, orig_ext->format, orig_ext->prefix_data, &ext->prefix_data));
+ LY_ERR ret = LY_SUCCESS;
+ struct ly_set pmods = {0};
+ struct lysp_ctx pctx = {.parsed_mods = &pmods};
- ext->child = NULL;
- LY_CHECK_RET(lysp_ext_children_dup(ctx, &ext->child, orig_ext->child));
+ DUP_STRING_GOTO(ctx, orig_ext->name, ext->name, ret, cleanup);
+ DUP_STRING_GOTO(ctx, orig_ext->argument, ext->argument, ret, cleanup);
+ ext->format = orig_ext->format;
+ LY_CHECK_GOTO(ret = ly_dup_prefix_data(ctx, orig_ext->format, orig_ext->prefix_data, &ext->prefix_data), cleanup);
+ ext->def = orig_ext->def;
ext->parent = orig_ext->parent;
ext->parent_stmt = orig_ext->parent_stmt;
ext->parent_stmt_index = orig_ext->parent_stmt_index;
ext->flags = orig_ext->flags;
- return LY_SUCCESS;
+ ext->record = orig_ext->record;
+
+ LY_CHECK_GOTO(ret = lysp_ext_children_dup(ctx, &ext->child, orig_ext->child), cleanup);
+ if (ext->record && ext->record->plugin.parse) {
+ /* parse again */
+ LY_CHECK_GOTO(ret = ly_set_add(&pmods, pmod, 1, NULL), cleanup);
+ LY_CHECK_GOTO(ret = ext->record->plugin.parse(&pctx, ext), cleanup);
+ }
+
+cleanup:
+ ly_set_erase(&pmods, NULL);
+ return ret;
}
static LY_ERR
-lysp_restr_dup(const struct ly_ctx *ctx, struct lysp_restr *restr, const struct lysp_restr *orig_restr)
+lysp_restr_dup(const struct ly_ctx *ctx, const struct lysp_module *pmod, struct lysp_restr *restr,
+ const struct lysp_restr *orig_restr)
{
LY_ERR ret = LY_SUCCESS;
@@ -373,7 +386,7 @@
DUP_STRING(ctx, orig_restr->eapptag, restr->eapptag, ret);
DUP_STRING(ctx, orig_restr->dsc, restr->dsc, ret);
DUP_STRING(ctx, orig_restr->ref, restr->ref, ret);
- DUP_ARRAY(ctx, orig_restr->exts, restr->exts, lysp_ext_dup);
+ DUP_ARRAY2(ctx, pmod, orig_restr->exts, restr->exts, lysp_ext_dup);
}
return ret;
@@ -406,7 +419,8 @@
}
static LY_ERR
-lysp_type_enum_dup(const struct ly_ctx *ctx, struct lysp_type_enum *enm, const struct lysp_type_enum *orig_enm)
+lysp_type_enum_dup(const struct ly_ctx *ctx, const struct lysp_module *pmod, struct lysp_type_enum *enm,
+ const struct lysp_type_enum *orig_enm)
{
LY_ERR ret = LY_SUCCESS;
@@ -415,14 +429,15 @@
DUP_STRING(ctx, orig_enm->ref, enm->ref, ret);
enm->value = orig_enm->value;
DUP_ARRAY(ctx, orig_enm->iffeatures, enm->iffeatures, lysp_qname_dup);
- DUP_ARRAY(ctx, orig_enm->exts, enm->exts, lysp_ext_dup);
+ DUP_ARRAY2(ctx, pmod, orig_enm->exts, enm->exts, lysp_ext_dup);
enm->flags = orig_enm->flags;
return ret;
}
static LY_ERR
-lysp_type_dup(const struct ly_ctx *ctx, struct lysp_type *type, const struct lysp_type *orig_type)
+lysp_type_dup(const struct ly_ctx *ctx, const struct lysp_module *pmod, struct lysp_type *type,
+ const struct lysp_type *orig_type)
{
LY_ERR ret = LY_SUCCESS;
@@ -434,22 +449,22 @@
if (orig_type->range) {
type->range = calloc(1, sizeof *type->range);
LY_CHECK_ERR_RET(!type->range, LOGMEM(ctx), LY_EMEM);
- LY_CHECK_RET(lysp_restr_dup(ctx, type->range, orig_type->range));
+ LY_CHECK_RET(lysp_restr_dup(ctx, pmod, type->range, orig_type->range));
}
if (orig_type->length) {
type->length = calloc(1, sizeof *type->length);
LY_CHECK_ERR_RET(!type->length, LOGMEM(ctx), LY_EMEM);
- LY_CHECK_RET(lysp_restr_dup(ctx, type->length, orig_type->length));
+ LY_CHECK_RET(lysp_restr_dup(ctx, pmod, type->length, orig_type->length));
}
- DUP_ARRAY(ctx, orig_type->patterns, type->patterns, lysp_restr_dup);
- DUP_ARRAY(ctx, orig_type->enums, type->enums, lysp_type_enum_dup);
- DUP_ARRAY(ctx, orig_type->bits, type->bits, lysp_type_enum_dup);
+ DUP_ARRAY2(ctx, pmod, orig_type->patterns, type->patterns, lysp_restr_dup);
+ DUP_ARRAY2(ctx, pmod, orig_type->enums, type->enums, lysp_type_enum_dup);
+ DUP_ARRAY2(ctx, pmod, orig_type->bits, type->bits, lysp_type_enum_dup);
LY_CHECK_GOTO(ret = lyxp_expr_dup(ctx, orig_type->path, 0, 0, &type->path), done);
DUP_ARRAY(ctx, orig_type->bases, type->bases, lysp_string_dup);
- DUP_ARRAY(ctx, orig_type->types, type->types, lysp_type_dup);
- DUP_ARRAY(ctx, orig_type->exts, type->exts, lysp_ext_dup);
+ DUP_ARRAY2(ctx, pmod, orig_type->types, type->types, lysp_type_dup);
+ DUP_ARRAY2(ctx, pmod, orig_type->exts, type->exts, lysp_ext_dup);
type->pmod = orig_type->pmod;
type->compiled = orig_type->compiled;
@@ -463,20 +478,22 @@
}
static LY_ERR
-lysp_when_dup(const struct ly_ctx *ctx, struct lysp_when *when, const struct lysp_when *orig_when)
+lysp_when_dup(const struct ly_ctx *ctx, const struct lysp_module *pmod, struct lysp_when *when,
+ const struct lysp_when *orig_when)
{
LY_ERR ret = LY_SUCCESS;
DUP_STRING(ctx, orig_when->cond, when->cond, ret);
DUP_STRING(ctx, orig_when->dsc, when->dsc, ret);
DUP_STRING(ctx, orig_when->ref, when->ref, ret);
- DUP_ARRAY(ctx, orig_when->exts, when->exts, lysp_ext_dup);
+ DUP_ARRAY2(ctx, pmod, orig_when->exts, when->exts, lysp_ext_dup);
return ret;
}
static LY_ERR
-lysp_node_common_dup(const struct ly_ctx *ctx, struct lysp_node *node, const struct lysp_node *orig)
+lysp_node_common_dup(const struct ly_ctx *ctx, const struct lysp_module *pmod, struct lysp_node *node,
+ const struct lysp_node *orig)
{
LY_ERR ret = LY_SUCCESS;
@@ -488,20 +505,21 @@
DUP_STRING(ctx, orig->dsc, node->dsc, ret);
DUP_STRING(ctx, orig->ref, node->ref, ret);
DUP_ARRAY(ctx, orig->iffeatures, node->iffeatures, lysp_qname_dup);
- DUP_ARRAY(ctx, orig->exts, node->exts, lysp_ext_dup);
+ DUP_ARRAY2(ctx, pmod, orig->exts, node->exts, lysp_ext_dup);
return ret;
}
-#define DUP_PWHEN(CTX, ORIG, NEW) \
+#define DUP_PWHEN(CTX, PMOD, ORIG, NEW) \
if (ORIG) { \
NEW = calloc(1, sizeof *NEW); \
LY_CHECK_ERR_RET(!NEW, LOGMEM(CTX), LY_EMEM); \
- LY_CHECK_RET(lysp_when_dup(CTX, NEW, ORIG)); \
+ LY_CHECK_RET(lysp_when_dup(CTX, PMOD, NEW, ORIG)); \
}
static LY_ERR
-lysp_node_dup(const struct ly_ctx *ctx, struct lysp_node *node, const struct lysp_node *orig)
+lysp_node_dup(const struct ly_ctx *ctx, const struct lysp_module *pmod, struct lysp_node *node,
+ const struct lysp_node *orig)
{
LY_ERR ret = LY_SUCCESS;
struct lysp_node_container *cont;
@@ -529,7 +547,7 @@
LYS_RPC | LYS_ACTION | LYS_NOTIF));
/* common part */
- LY_CHECK_RET(lysp_node_common_dup(ctx, node, orig));
+ LY_CHECK_RET(lysp_node_common_dup(ctx, pmod, node, orig));
/* specific part */
switch (node->nodetype) {
@@ -537,8 +555,8 @@
cont = (struct lysp_node_container *)node;
orig_cont = (const struct lysp_node_container *)orig;
- DUP_PWHEN(ctx, orig_cont->when, cont->when);
- DUP_ARRAY(ctx, orig_cont->musts, cont->musts, lysp_restr_dup);
+ DUP_PWHEN(ctx, pmod, orig_cont->when, cont->when);
+ DUP_ARRAY2(ctx, pmod, orig_cont->musts, cont->musts, lysp_restr_dup);
DUP_STRING(ctx, orig_cont->presence, cont->presence, ret);
/* we do not need the rest */
break;
@@ -546,9 +564,9 @@
leaf = (struct lysp_node_leaf *)node;
orig_leaf = (const struct lysp_node_leaf *)orig;
- DUP_PWHEN(ctx, orig_leaf->when, leaf->when);
- DUP_ARRAY(ctx, orig_leaf->musts, leaf->musts, lysp_restr_dup);
- LY_CHECK_RET(lysp_type_dup(ctx, &leaf->type, &orig_leaf->type));
+ DUP_PWHEN(ctx, pmod, orig_leaf->when, leaf->when);
+ DUP_ARRAY2(ctx, pmod, orig_leaf->musts, leaf->musts, lysp_restr_dup);
+ LY_CHECK_RET(lysp_type_dup(ctx, pmod, &leaf->type, &orig_leaf->type));
DUP_STRING(ctx, orig_leaf->units, leaf->units, ret);
LY_CHECK_RET(lysp_qname_dup(ctx, &leaf->dflt, &orig_leaf->dflt));
break;
@@ -556,9 +574,9 @@
llist = (struct lysp_node_leaflist *)node;
orig_llist = (const struct lysp_node_leaflist *)orig;
- DUP_PWHEN(ctx, orig_llist->when, llist->when);
- DUP_ARRAY(ctx, orig_llist->musts, llist->musts, lysp_restr_dup);
- LY_CHECK_RET(lysp_type_dup(ctx, &llist->type, &orig_llist->type));
+ DUP_PWHEN(ctx, pmod, orig_llist->when, llist->when);
+ DUP_ARRAY2(ctx, pmod, orig_llist->musts, llist->musts, lysp_restr_dup);
+ LY_CHECK_RET(lysp_type_dup(ctx, pmod, &llist->type, &orig_llist->type));
DUP_STRING(ctx, orig_llist->units, llist->units, ret);
DUP_ARRAY(ctx, orig_llist->dflts, llist->dflts, lysp_qname_dup);
llist->min = orig_llist->min;
@@ -568,8 +586,8 @@
list = (struct lysp_node_list *)node;
orig_list = (const struct lysp_node_list *)orig;
- DUP_PWHEN(ctx, orig_list->when, list->when);
- DUP_ARRAY(ctx, orig_list->musts, list->musts, lysp_restr_dup);
+ DUP_PWHEN(ctx, pmod, orig_list->when, list->when);
+ DUP_ARRAY2(ctx, pmod, orig_list->musts, list->musts, lysp_restr_dup);
DUP_STRING(ctx, orig_list->key, list->key, ret);
/* we do not need these arrays */
DUP_ARRAY(ctx, orig_list->uniques, list->uniques, lysp_qname_dup);
@@ -580,7 +598,7 @@
choice = (struct lysp_node_choice *)node;
orig_choice = (const struct lysp_node_choice *)orig;
- DUP_PWHEN(ctx, orig_choice->when, choice->when);
+ DUP_PWHEN(ctx, pmod, orig_choice->when, choice->when);
/* we do not need children */
LY_CHECK_RET(lysp_qname_dup(ctx, &choice->dflt, &orig_choice->dflt));
break;
@@ -588,7 +606,7 @@
cas = (struct lysp_node_case *)node;
orig_cas = (const struct lysp_node_case *)orig;
- DUP_PWHEN(ctx, orig_cas->when, cas->when);
+ DUP_PWHEN(ctx, pmod, orig_cas->when, cas->when);
/* we do not need children */
break;
case LYS_ANYDATA:
@@ -596,8 +614,8 @@
any = (struct lysp_node_anydata *)node;
orig_any = (const struct lysp_node_anydata *)orig;
- DUP_PWHEN(ctx, orig_any->when, any->when);
- DUP_ARRAY(ctx, orig_any->musts, any->musts, lysp_restr_dup);
+ DUP_PWHEN(ctx, pmod, orig_any->when, any->when);
+ DUP_ARRAY2(ctx, pmod, orig_any->musts, any->musts, lysp_restr_dup);
break;
case LYS_RPC:
case LYS_ACTION:
@@ -613,14 +631,14 @@
action_inout = (struct lysp_node_action_inout *)node;
orig_action_inout = (const struct lysp_node_action_inout *)orig;
- DUP_ARRAY(ctx, orig_action_inout->musts, action_inout->musts, lysp_restr_dup);
+ DUP_ARRAY2(ctx, pmod, orig_action_inout->musts, action_inout->musts, lysp_restr_dup);
/* we do not need the rest */
break;
case LYS_NOTIF:
notif = (struct lysp_node_notif *)node;
orig_notif = (const struct lysp_node_notif *)orig;
- DUP_ARRAY(ctx, orig_notif->musts, notif->musts, lysp_restr_dup);
+ DUP_ARRAY2(ctx, pmod, orig_notif->musts, notif->musts, lysp_restr_dup);
/* we do not need the rest */
break;
default:
@@ -634,13 +652,15 @@
* @brief Duplicate a single parsed node. Only attributes that are used in compilation are copied.
*
* @param[in] ctx libyang context.
+ * @param[in] pmod Current parsed module.
* @param[in] pnode Node to duplicate.
* @param[in] with_links Whether to also copy any links (child, parent pointers).
* @param[out] dup_p Duplicated parsed node.
* @return LY_ERR value.
*/
static LY_ERR
-lysp_dup_single(const struct ly_ctx *ctx, const struct lysp_node *pnode, ly_bool with_links, struct lysp_node **dup_p)
+lysp_dup_single(const struct ly_ctx *ctx, const struct lysp_module *pmod, const struct lysp_node *pnode,
+ ly_bool with_links, struct lysp_node **dup_p)
{
LY_ERR ret = LY_SUCCESS;
void *mem = NULL;
@@ -688,7 +708,7 @@
LOGINT_RET(ctx);
}
LY_CHECK_ERR_GOTO(!mem, LOGMEM(ctx); ret = LY_EMEM, cleanup);
- LY_CHECK_GOTO(ret = lysp_node_dup(ctx, mem, pnode), cleanup);
+ LY_CHECK_GOTO(ret = lysp_node_dup(ctx, pmod, mem, pnode), cleanup);
if (with_links) {
/* copy also parent, child, action, and notification pointers */
@@ -743,18 +763,29 @@
*
* @param[in] ctx Compile context.
* @param[in] rfn Refine to apply.
+ * @param[in] rfn_pmod Local module fo the refine.
* @param[in,out] target Refine target.
* @return LY_ERR value.
*/
static LY_ERR
-lys_apply_refine(struct lysc_ctx *ctx, struct lysp_refine *rfn, struct lysp_node *target)
+lys_apply_refine(struct lysc_ctx *ctx, struct lysp_refine *rfn, const struct lysp_module *rfn_pmod, struct lysp_node *target)
{
LY_ERR ret = LY_SUCCESS;
+ struct lys_module *orig_mod = ctx->cur_mod;
+ struct lysp_module *orig_pmod = ctx->pmod;
LY_ARRAY_COUNT_TYPE u;
struct lysp_qname *qname;
struct lysp_restr **musts, *must;
uint32_t *num;
+ /* use module from the refine */
+ ctx->cur_mod = rfn_pmod->mod;
+ ctx->pmod = (struct lysp_module *)rfn_pmod;
+
+ /* keep the current path and add to it */
+ lysc_update_path(ctx, NULL, "{refine}");
+ lysc_update_path(ctx, NULL, rfn->nodeid);
+
/* default value */
if (rfn->dflts) {
switch (target->nodetype) {
@@ -860,7 +891,7 @@
LY_ARRAY_FOR(rfn->musts, u) {
LY_ARRAY_NEW_GOTO(ctx->ctx, *musts, must, ret, cleanup);
- LY_CHECK_GOTO(ret = lysp_restr_dup(ctx->ctx, must, &rfn->musts[u]), cleanup);
+ LY_CHECK_GOTO(ret = lysp_restr_dup(ctx->ctx, rfn_pmod, must, &rfn->musts[u]), cleanup);
}
}
@@ -918,10 +949,15 @@
}
}
- /* extension */
- /* TODO refine extensions */
+ /* extension instances */
+ DUP_ARRAY2(ctx->ctx, rfn_pmod, rfn->exts, target->exts, lysp_ext_dup);
cleanup:
+ ctx->cur_mod = orig_mod;
+ ctx->pmod = orig_pmod;
+
+ lysc_update_path(ctx, NULL, NULL);
+ lysc_update_path(ctx, NULL, NULL);
return ret;
}
@@ -973,7 +1009,7 @@
LY_ARRAY_FOR(d->musts, u) {
LY_ARRAY_NEW_GOTO(ctx->ctx, *musts, must, ret, cleanup);
- LY_CHECK_GOTO(ret = lysp_restr_dup(ctx->ctx, must, &d->musts[u]), cleanup);
+ LY_CHECK_GOTO(ret = lysp_restr_dup(ctx->ctx, ctx->pmod, must, &d->musts[u]), cleanup);
}
}
@@ -1279,7 +1315,7 @@
}
lysp_type_free(&ctx->free_ctx, &((struct lysp_node_leaf *)target)->type);
- lysp_type_dup(ctx->ctx, &((struct lysp_node_leaf *)target)->type, d->type);
+ lysp_type_dup(ctx->ctx, ctx->pmod, &((struct lysp_node_leaf *)target)->type, d->type);
}
/* [units-stmt] */
@@ -1415,6 +1451,65 @@
}
/**
+ * @brief Apply deviation with all its deviates.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] dev Deviation to apply.
+ * @param[in] dev_pmod Local module of the deviation.
+ * @param[in,out] target Deviation target.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lys_apply_deviation(struct lysc_ctx *ctx, struct lysp_deviation *dev, const struct lysp_module *dev_pmod,
+ struct lysp_node *target)
+{
+ LY_ERR ret = LY_SUCCESS;
+ struct lys_module *orig_mod = ctx->cur_mod;
+ struct lysp_module *orig_pmod = ctx->pmod;
+ char orig_path[LYSC_CTX_BUFSIZE];
+ struct lysp_deviate *d;
+
+ /* clear path and set modules */
+ strcpy(orig_path, ctx->path);
+ ctx->path_len = 1;
+ ctx->cur_mod = dev_pmod->mod;
+ ctx->pmod = (struct lysp_module *)dev_pmod;
+
+ /* generate correct path */
+ lysc_update_path(ctx, NULL, "{deviation}");
+ lysc_update_path(ctx, NULL, dev->nodeid);
+
+ LY_LIST_FOR(dev->deviates, d) {
+ switch (d->mod) {
+ case LYS_DEV_ADD:
+ ret = lys_apply_deviate_add(ctx, (struct lysp_deviate_add *)d, target);
+ break;
+ case LYS_DEV_DELETE:
+ ret = lys_apply_deviate_delete(ctx, (struct lysp_deviate_del *)d, target);
+ break;
+ case LYS_DEV_REPLACE:
+ ret = lys_apply_deviate_replace(ctx, (struct lysp_deviate_rpl *)d, target);
+ break;
+ default:
+ LOGINT(ctx->ctx);
+ ret = LY_EINT;
+ }
+ LY_CHECK_GOTO(ret, cleanup);
+ }
+
+ /* deviation extension instances */
+ DUP_ARRAY2(ctx->ctx, dev_pmod, dev->exts, target->exts, lysp_ext_dup);
+
+cleanup:
+ ctx->cur_mod = orig_mod;
+ ctx->pmod = orig_pmod;
+
+ strcpy(ctx->path, orig_path);
+ ctx->path_len = strlen(ctx->path);
+ return ret;
+}
+
+/**
* @brief Check whether a compiled node matches a single schema nodeid name test.
*
* @param[in,out] node Compiled node to consider. On a match it is moved to its parent.
@@ -1606,13 +1701,8 @@
LY_ERR ret = LY_SUCCESS;
uint32_t i;
LY_ARRAY_COUNT_TYPE u;
- struct lys_module *orig_mod = ctx->cur_mod;
- struct lysp_module *orig_pmod = ctx->pmod;
- char orig_path[LYSC_CTX_BUFSIZE];
struct lysc_refine *rfn;
struct lysc_deviation *dev;
- struct lysp_deviation *dev_p;
- struct lysp_deviate *d;
*dev_pnode = NULL;
*not_supported = 0;
@@ -1620,7 +1710,7 @@
for (i = 0; i < ctx->uses_rfns.count; ) {
rfn = ctx->uses_rfns.objs[i];
- if (!lysp_schema_nodeid_match(rfn->nodeid, rfn->nodeid_pmod, rfn->nodeid_ctx_node, parent, pnode, orig_mod)) {
+ if (!lysp_schema_nodeid_match(rfn->nodeid, rfn->nodeid_pmod, rfn->nodeid_ctx_node, parent, pnode, ctx->cur_mod)) {
/* not our target node */
++i;
continue;
@@ -1628,24 +1718,12 @@
if (!*dev_pnode) {
/* first refine on this node, create a copy first */
- LY_CHECK_GOTO(ret = lysp_dup_single(ctx->ctx, pnode, 1, dev_pnode), cleanup);
+ LY_CHECK_GOTO(ret = lysp_dup_single(ctx->ctx, ctx->pmod, pnode, 1, dev_pnode), cleanup);
}
- /* use modules from the refine */
- ctx->cur_mod = rfn->nodeid_pmod->mod;
- ctx->pmod = (struct lysp_module *)rfn->nodeid_pmod;
-
/* apply all the refines by changing (the copy of) the parsed node */
LY_ARRAY_FOR(rfn->rfns, u) {
- /* keep the current path and add to it */
- lysc_update_path(ctx, NULL, "{refine}");
- lysc_update_path(ctx, NULL, rfn->rfns[u]->nodeid);
-
- /* apply refine and restore the path */
- ret = lys_apply_refine(ctx, rfn->rfns[u], *dev_pnode);
- lysc_update_path(ctx, NULL, NULL);
- lysc_update_path(ctx, NULL, NULL);
- LY_CHECK_GOTO(ret, cleanup);
+ LY_CHECK_GOTO(ret = lys_apply_refine(ctx, rfn->rfns[u], rfn->nodeid_pmod, *dev_pnode), cleanup);
}
/* refine was applied, remove it */
@@ -1658,7 +1736,7 @@
for (i = 0; i < ctx->devs.count; ++i) {
dev = ctx->devs.objs[i];
- if (!lysp_schema_nodeid_match(dev->nodeid, dev->dev_pmods[0], NULL, parent, pnode, orig_mod)) {
+ if (!lysp_schema_nodeid_match(dev->nodeid, dev->dev_pmods[0], NULL, parent, pnode, ctx->cur_mod)) {
/* not our target node */
continue;
}
@@ -1671,42 +1749,12 @@
if (!*dev_pnode) {
/* first deviation on this node, create a copy first */
- LY_CHECK_GOTO(ret = lysp_dup_single(ctx->ctx, pnode, 1, dev_pnode), cleanup);
+ LY_CHECK_GOTO(ret = lysp_dup_single(ctx->ctx, ctx->pmod, pnode, 1, dev_pnode), cleanup);
}
/* apply all the deviates by changing (the copy of) the parsed node */
LY_ARRAY_FOR(dev->devs, u) {
- dev_p = dev->devs[u];
- LY_LIST_FOR(dev_p->deviates, d) {
- /* generate correct path */
- strcpy(orig_path, ctx->path);
- ctx->path_len = 1;
- ctx->cur_mod = dev->dev_pmods[u]->mod;
- ctx->pmod = (struct lysp_module *)dev->dev_pmods[u];
- lysc_update_path(ctx, NULL, "{deviation}");
- lysc_update_path(ctx, NULL, dev_p->nodeid);
-
- switch (d->mod) {
- case LYS_DEV_ADD:
- ret = lys_apply_deviate_add(ctx, (struct lysp_deviate_add *)d, *dev_pnode);
- break;
- case LYS_DEV_DELETE:
- ret = lys_apply_deviate_delete(ctx, (struct lysp_deviate_del *)d, *dev_pnode);
- break;
- case LYS_DEV_REPLACE:
- ret = lys_apply_deviate_replace(ctx, (struct lysp_deviate_rpl *)d, *dev_pnode);
- break;
- default:
- LOGINT(ctx->ctx);
- ret = LY_EINT;
- }
-
- /* restore previous path */
- strcpy(ctx->path, orig_path);
- ctx->path_len = strlen(ctx->path);
-
- LY_CHECK_GOTO(ret, cleanup);
- }
+ LY_CHECK_GOTO(ret = lys_apply_deviation(ctx, dev->devs[u], dev->dev_pmods[u], *dev_pnode), cleanup);
}
dev_applied:
@@ -1719,8 +1767,6 @@
}
cleanup:
- ctx->cur_mod = orig_mod;
- ctx->pmod = orig_pmod;
if (ret) {
lysp_dev_node_free(ctx, *dev_pnode);
*dev_pnode = NULL;
@@ -1877,6 +1923,9 @@
child_unres_disabled);
LY_CHECK_GOTO(rc, cleanup);
+ /* compile extensions into the target */
+ COMPILE_EXTS_GOTO(ctx, aug_p->exts, target->exts, target, rc, cleanup);
+
cleanup:
ctx->compile_opts = opt_prev;
return rc;
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 0d2fe6d..a1708b0 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -30,7 +30,6 @@
#include "dict.h"
#include "log.h"
#include "plugins.h"
-#include "plugins_exts_compile.h"
#include "plugins_internal.h"
#include "plugins_types.h"
#include "schema_compile.h"
@@ -404,7 +403,7 @@
* @return LY_ERR value.
*/
static LY_ERR
-lys_compile_when_(struct lysc_ctx *ctx, struct lysp_when *when_p, uint16_t parent_flags,
+lys_compile_when_(struct lysc_ctx *ctx, const struct lysp_when *when_p, uint16_t parent_flags,
const struct lysc_node *compiled_parent, const struct lysc_node *ctx_node, struct lysc_when **when)
{
LY_ERR ret = LY_SUCCESS;
@@ -432,21 +431,31 @@
}
LY_ERR
-lys_compile_when(struct lysc_ctx *ctx, struct lysp_when *when_p, uint16_t parent_flags, const struct lysc_node *compiled_parent,
- const struct lysc_node *ctx_node, struct lysc_node *node, struct lysc_when **when_c)
+lys_compile_when(struct lysc_ctx *ctx, const struct lysp_when *when_p, uint16_t parent_flags,
+ const struct lysc_node *compiled_parent, const struct lysc_node *ctx_node, struct lysc_node *node,
+ struct lysc_when **when_c)
{
- struct lysc_when **new_when, ***node_when;
+ LY_ERR rc = LY_SUCCESS;
+ struct lysc_when **new_when, ***node_when, *ptr;
- assert(when_p);
+ assert(when_p && (node || when_c));
- /* get the when array */
- node_when = lysc_node_when_p(node);
+ if (node) {
+ /* get the when array */
+ node_when = lysc_node_when_p(node);
- /* create new when pointer */
- LY_ARRAY_NEW_RET(ctx->ctx, *node_when, new_when, LY_EMEM);
+ /* create new when pointer */
+ LY_ARRAY_NEW_GOTO(ctx->ctx, *node_when, new_when, rc, cleanup);
+ } else {
+ /* individual when */
+ new_when = &ptr;
+ *new_when = calloc(1, sizeof **new_when);
+ LY_CHECK_ERR_GOTO(!*new_when, LOGMEM(ctx->ctx); rc = LY_EMEM, cleanup);
+ }
+
if (!when_c || !(*when_c)) {
/* compile when */
- LY_CHECK_RET(lys_compile_when_(ctx, when_p, parent_flags, compiled_parent, ctx_node, new_when));
+ LY_CHECK_GOTO(rc = lys_compile_when_(ctx, when_p, parent_flags, compiled_parent, ctx_node, new_when), cleanup);
/* remember the compiled when for sharing */
if (when_c) {
@@ -461,14 +470,15 @@
if (!(ctx->compile_opts & LYS_COMPILE_GROUPING)) {
/* do not check "when" semantics in a grouping, but repeat the check for different node because
* of dummy node check */
- LY_CHECK_RET(ly_set_add(&ctx->unres->whens, node, 0, NULL));
+ LY_CHECK_GOTO(rc = ly_set_add(&ctx->unres->whens, node, 0, NULL), cleanup);
}
- return LY_SUCCESS;
+cleanup:
+ return rc;
}
LY_ERR
-lys_compile_must(struct lysc_ctx *ctx, struct lysp_restr *must_p, struct lysc_must *must)
+lys_compile_must(struct lysc_ctx *ctx, const struct lysp_restr *must_p, struct lysc_must *must)
{
LY_ERR ret = LY_SUCCESS;
LY_VALUE_FORMAT format;
@@ -761,20 +771,8 @@
return ret;
}
-/**
- * @brief Compile the parsed range restriction.
- * @param[in] ctx Compile context.
- * @param[in] range_p Parsed range structure to compile.
- * @param[in] basetype Base YANG built-in type of the node with the range restriction.
- * @param[in] length_restr Flag to distinguish between range and length restrictions. Only for logging.
- * @param[in] frdigits The fraction-digits value in case of LY_TYPE_DEC64 basetype.
- * @param[in] base_range Range restriction of the type from which the current type is derived. The current
- * range restriction must be more restrictive than the base_range.
- * @param[in,out] range Pointer to the created current range structure.
- * @return LY_ERR value.
- */
-static LY_ERR
-lys_compile_type_range(struct lysc_ctx *ctx, struct lysp_restr *range_p, LY_DATA_TYPE basetype, ly_bool length_restr,
+LY_ERR
+lys_compile_type_range(struct lysc_ctx *ctx, const struct lysp_restr *range_p, LY_DATA_TYPE basetype, ly_bool length_restr,
uint8_t frdigits, struct lysc_range *base_range, struct lysc_range **range)
{
LY_ERR ret = LY_SUCCESS;
@@ -1287,8 +1285,8 @@
}
LY_ERR
-lys_compile_type_patterns(struct lysc_ctx *ctx, struct lysp_restr *patterns_p,
- struct lysc_pattern **base_patterns, struct lysc_pattern ***patterns)
+lys_compile_type_patterns(struct lysc_ctx *ctx, const struct lysp_restr *patterns_p, struct lysc_pattern **base_patterns,
+ struct lysc_pattern ***patterns)
{
struct lysc_pattern **pattern;
LY_ARRAY_COUNT_TYPE u;
@@ -1374,17 +1372,8 @@
LY_TYPE_INT64_STR
};
-/**
- * @brief Compile parsed type's enum structures (for enumeration and bits types).
- * @param[in] ctx Compile context.
- * @param[in] enums_p Array of the parsed enum structures to compile.
- * @param[in] basetype Base YANG built-in type from which the current type is derived. Only LY_TYPE_ENUM and LY_TYPE_BITS are expected.
- * @param[in] base_enums Array of the compiled enums information from the (latest) base type to check if the current enums are compatible.
- * @param[out] bitenums Newly created array of the compiled bitenums information for the current type.
- * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
- */
-static LY_ERR
-lys_compile_type_enums(struct lysc_ctx *ctx, struct lysp_type_enum *enums_p, LY_DATA_TYPE basetype,
+LY_ERR
+lys_compile_type_enums(struct lysc_ctx *ctx, const struct lysp_type_enum *enums_p, LY_DATA_TYPE basetype,
struct lysc_type_bitenum_item *base_enums, struct lysc_type_bitenum_item **bitenums)
{
LY_ERR ret = LY_SUCCESS;
@@ -1626,7 +1615,8 @@
*/
static LY_ERR
lys_compile_type_(struct lysc_ctx *ctx, struct lysp_node *context_pnode, uint16_t context_flags, const char *context_name,
- struct lysp_type *type_p, LY_DATA_TYPE basetype, const char *tpdfname, struct lysc_type *base, struct lysc_type **type)
+ struct lysp_type *type_p, LY_DATA_TYPE basetype, const char *tpdfname, const struct lysc_type *base,
+ struct lysc_type **type)
{
LY_ERR ret = LY_SUCCESS;
struct lysc_type_bin *bin;
@@ -1950,7 +1940,7 @@
LY_ERR
lys_compile_type(struct lysc_ctx *ctx, struct lysp_node *context_pnode, uint16_t context_flags, const char *context_name,
- struct lysp_type *type_p, struct lysc_type **type, const char **units, struct lysp_qname **dflt)
+ const struct lysp_type *type_p, struct lysc_type **type, const char **units, struct lysp_qname **dflt)
{
LY_ERR ret = LY_SUCCESS;
ly_bool dummyloops = 0;
@@ -2186,7 +2176,8 @@
(*type)->basetype = basetype;
(*type)->plugin = base ? base->plugin : lyplg_type_plugin_find("", NULL, ly_data_type2str[basetype]);
LY_ATOMIC_INC_BARRIER((*type)->refcount);
- ret = lys_compile_type_(ctx, context_pnode, context_flags, context_name, type_p, basetype, NULL, base, type);
+ ret = lys_compile_type_(ctx, context_pnode, context_flags, context_name, (struct lysp_type *)type_p, basetype,
+ NULL, base, type);
LY_CHECK_GOTO(ret, cleanup);
} else if ((basetype != LY_TYPE_BOOL) && (basetype != LY_TYPE_EMPTY)) {
/* no specific restriction in leaf's type definition, copy from the base */
@@ -2325,18 +2316,7 @@
#undef CHECK_NODE
}
-/**
- * @brief Connect the node into the siblings list and check its name uniqueness. Also,
- * keep specific order of augments targetting the same node.
- *
- * @param[in] ctx Compile context
- * @param[in] parent Parent node holding the children list, in case of node from a choice's case,
- * the choice itself is expected instead of a specific case node.
- * @param[in] node Schema node to connect into the list.
- * @return LY_ERR value - LY_SUCCESS or LY_EEXIST.
- * In case of LY_EEXIST, the node is actually kept in the tree, so do not free it directly.
- */
-static LY_ERR
+LY_ERR
lys_compile_node_connect(struct lysc_ctx *ctx, struct lysc_node *parent, struct lysc_node *node)
{
struct lysc_node **children, *anchor = NULL;
@@ -2443,8 +2423,7 @@
struct lysc_node **list;
if (ctx->ext) {
- /* container matches all data nodes */
- lysc_ext_substmt(ctx->ext, LY_STMT_CONTAINER, (void **)&list);
+ lyplg_ext_get_storage_p(ctx->ext, LY_STMT_DATA_NODE_MASK, (const void ***)&list);
} else if (node->nodetype == LYS_RPC) {
list = (struct lysc_node **)&ctx->cur_mod->compiled->rpcs;
} else if (node->nodetype == LYS_NOTIF) {
@@ -2638,14 +2617,6 @@
return ret;
}
-/**
- * @brief Compile parsed action's input/output node information.
- * @param[in] ctx Compile context
- * @param[in] pnode Parsed inout node.
- * @param[in,out] node Pre-prepared structure from lys_compile_node_() with filled generic node information
- * is enriched with the inout-specific information.
- * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
- */
LY_ERR
lys_compile_node_action_inout(struct lysc_ctx *ctx, struct lysp_node *pnode, struct lysc_node *node)
{
@@ -2675,13 +2646,14 @@
/**
* @brief Compile parsed action node information.
+ *
* @param[in] ctx Compile context
* @param[in] pnode Parsed action node.
* @param[in,out] node Pre-prepared structure from lys_compile_node() with filled generic node information
* is enriched with the action-specific information.
* @return LY_ERR value - LY_SUCCESS or LY_EVALID.
*/
-LY_ERR
+static LY_ERR
lys_compile_node_action(struct lysc_ctx *ctx, struct lysp_node *pnode, struct lysc_node *node)
{
LY_ERR ret;
@@ -2740,7 +2712,7 @@
* is enriched with the action-specific information.
* @return LY_ERR value - LY_SUCCESS or LY_EVALID.
*/
-LY_ERR
+static LY_ERR
lys_compile_node_notif(struct lysc_ctx *ctx, struct lysp_node *pnode, struct lysc_node *node)
{
LY_ERR ret = LY_SUCCESS;
@@ -3591,7 +3563,7 @@
if (any->flags & LYS_CONFIG_W) {
LOGVRB("Use of %s to define configuration data is not recommended. %s",
- ly_stmt2str(any->nodetype == LYS_ANYDATA ? LY_STMT_ANYDATA : LY_STMT_ANYXML), ctx->path);
+ lyplg_ext_stmt2str(any->nodetype == LYS_ANYDATA ? LY_STMT_ANYDATA : LY_STMT_ANYXML), ctx->path);
}
done:
return ret;
@@ -3695,7 +3667,7 @@
{
struct lysp_node *pnode;
struct lysp_node_grp *grp;
- struct lysp_node_grp * const *ext_grp;
+ const struct lysp_node_grp *ext_grp;
LY_ARRAY_COUNT_TYPE u;
const char *id, *name, *prefix, *local_pref;
size_t prefix_len, name_len;
@@ -3721,8 +3693,8 @@
/* if in an extension, search possible groupings in it */
if (ctx->ext) {
- ext_grp = lys_compile_ext_instance_get_storage(ctx->ext, LY_STMT_GROUPING);
- if (ext_grp && (grp = match_grouping(*ext_grp, name))) {
+ lyplg_ext_parsed_get_storage(ctx->ext, LY_STMT_GROUPING, (const void **)&ext_grp);
+ if ((grp = match_grouping(ext_grp, name))) {
found = ctx->pmod;
}
}
@@ -3730,8 +3702,7 @@
/* foreign module, find it first */
mod = ly_resolve_prefix(ctx->ctx, prefix, prefix_len, LY_VALUE_SCHEMA, ctx->pmod);
if (!mod) {
- LOGVAL(ctx->ctx, LYVE_REFERENCE,
- "Invalid prefix used for grouping reference.", uses_p->name);
+ LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid prefix used for grouping reference.", uses_p->name);
return LY_EVALID;
}
pmod = mod->parsed;
@@ -3752,8 +3723,7 @@
}
}
if (!found) {
- LOGVAL(ctx->ctx, LYVE_SEMANTICS,
- "Grouping \"%s\" referenced by a uses statement not found.", uses_p->name);
+ LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Grouping \"%s\" referenced by a uses statement not found.", uses_p->name);
return LY_EVALID;
}
@@ -3958,6 +3928,10 @@
}
LY_CHECK_GOTO(rc, cleanup);
+ /* compile uses and grouping extensions into the parent */
+ COMPILE_EXTS_GOTO(ctx, uses_p->exts, parent->exts, parent, rc, cleanup);
+ COMPILE_EXTS_GOTO(ctx, grp->exts, parent->exts, parent, rc, cleanup);
+
cleanup:
/* restore previous context */
ctx->compile_opts = opt_prev;
diff --git a/src/schema_compile_node.h b/src/schema_compile_node.h
index d1f050d..ae2ac5f 100644
--- a/src/schema_compile_node.h
+++ b/src/schema_compile_node.h
@@ -40,7 +40,7 @@
* for the first call.
* @return LY_ERR value.
*/
-LY_ERR lys_compile_when(struct lysc_ctx *ctx, struct lysp_when *when_p, uint16_t parent_flags,
+LY_ERR lys_compile_when(struct lysc_ctx *ctx, const struct lysp_when *when_p, uint16_t parent_flags,
const struct lysc_node *compiled_parent, const struct lysc_node *ctx_node, struct lysc_node *node,
struct lysc_when **when_c);
@@ -52,7 +52,23 @@
* @param[in,out] must Prepared (empty) compiled must structure to fill.
* @return LY_ERR value.
*/
-LY_ERR lys_compile_must(struct lysc_ctx *ctx, struct lysp_restr *must_p, struct lysc_must *must);
+LY_ERR lys_compile_must(struct lysc_ctx *ctx, const struct lysp_restr *must_p, struct lysc_must *must);
+
+/**
+ * @brief Compile the parsed range restriction.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] range_p Parsed range structure to compile.
+ * @param[in] basetype Base YANG built-in type of the node with the range restriction.
+ * @param[in] length_restr Flag to distinguish between range and length restrictions. Only for logging.
+ * @param[in] frdigits The fraction-digits value in case of LY_TYPE_DEC64 basetype.
+ * @param[in] base_range Range restriction of the type from which the current type is derived. The current
+ * range restriction must be more restrictive than the base_range.
+ * @param[in,out] range Pointer to the created current range structure.
+ * @return LY_ERR value.
+ */
+LY_ERR lys_compile_type_range(struct lysc_ctx *ctx, const struct lysp_restr *range_p, LY_DATA_TYPE basetype,
+ ly_bool length_restr, uint8_t frdigits, struct lysc_range *base_range, struct lysc_range **range);
/**
* @brief Checks pattern syntax.
@@ -74,10 +90,23 @@
* @param[out] patterns Pointer to the storage for the patterns of the current type.
* @return LY_ERR LY_SUCCESS, LY_EMEM, LY_EVALID.
*/
-LY_ERR lys_compile_type_patterns(struct lysc_ctx *ctx, struct lysp_restr *patterns_p,
+LY_ERR lys_compile_type_patterns(struct lysc_ctx *ctx, const struct lysp_restr *patterns_p,
struct lysc_pattern **base_patterns, struct lysc_pattern ***patterns);
/**
+ * @brief Compile parsed type's enum structures (for enumeration and bits types).
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] enums_p Array of the parsed enum structures to compile.
+ * @param[in] basetype Base YANG built-in type from which the current type is derived. Only LY_TYPE_ENUM and LY_TYPE_BITS are expected.
+ * @param[in] base_enums Array of the compiled enums information from the (latest) base type to check if the current enums are compatible.
+ * @param[out] bitenums Newly created array of the compiled bitenums information for the current type.
+ * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
+ */
+LY_ERR lys_compile_type_enums(struct lysc_ctx *ctx, const struct lysp_type_enum *enums_p, LY_DATA_TYPE basetype,
+ struct lysc_type_bitenum_item *base_enums, struct lysc_type_bitenum_item **bitenums);
+
+/**
* @brief Compile information about the leaf/leaf-list's type.
*
* @param[in] ctx Compile context.
@@ -91,10 +120,34 @@
* @return LY_ERR value.
*/
LY_ERR lys_compile_type(struct lysc_ctx *ctx, struct lysp_node *context_pnode, uint16_t context_flags,
- const char *context_name, struct lysp_type *type_p, struct lysc_type **type, const char **units,
+ const char *context_name, const struct lysp_type *type_p, struct lysc_type **type, const char **units,
struct lysp_qname **dflt);
/**
+ * @brief Connect the node into the siblings list and check its name uniqueness. Also,
+ * keep specific order of augments targetting the same node.
+ *
+ * @param[in] ctx Compile context
+ * @param[in] parent Parent node holding the children list, in case of node from a choice's case,
+ * the choice itself is expected instead of a specific case node.
+ * @param[in] node Schema node to connect into the list.
+ * @return LY_ERR value - LY_SUCCESS or LY_EEXIST.
+ * In case of LY_EEXIST, the node is actually kept in the tree, so do not free it directly.
+ */
+LY_ERR lys_compile_node_connect(struct lysc_ctx *ctx, struct lysc_node *parent, struct lysc_node *node);
+
+/**
+ * @brief Compile parsed action's input/output node information.
+ *
+ * @param[in] ctx Compile context
+ * @param[in] pnode Parsed inout node.
+ * @param[in,out] node Pre-prepared structure from lys_compile_node_() with filled generic node information
+ * is enriched with the inout-specific information.
+ * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
+ */
+LY_ERR lys_compile_node_action_inout(struct lysc_ctx *ctx, struct lysp_node *pnode, struct lysc_node *node);
+
+/**
* @brief Find the node according to the given descendant/absolute schema nodeid.
* Used in unique, refine and augment statements.
*
diff --git a/src/schema_features.c b/src/schema_features.c
index f70968f..dca998e 100644
--- a/src/schema_features.c
+++ b/src/schema_features.c
@@ -310,7 +310,7 @@
#define LYS_IFF_RP 0x08 /**< Additional, temporary, value of @ref ifftokens: ) */
static LY_ERR
-lys_compile_iffeature(const struct ly_ctx *ctx, struct lysp_qname *qname, struct lysc_iffeature *iff)
+lys_compile_iffeature(const struct ly_ctx *ctx, const struct lysp_qname *qname, struct lysc_iffeature *iff)
{
LY_ERR rc = LY_SUCCESS;
const char *c = qname->str;
@@ -501,7 +501,7 @@
}
LY_ERR
-lys_eval_iffeatures(const struct ly_ctx *ctx, struct lysp_qname *iffeatures, ly_bool *enabled)
+lys_eval_iffeatures(const struct ly_ctx *ctx, const struct lysp_qname *iffeatures, ly_bool *enabled)
{
LY_ERR ret;
LY_ARRAY_COUNT_TYPE u;
diff --git a/src/schema_features.h b/src/schema_features.h
index f12dc54..c73561f 100644
--- a/src/schema_features.h
+++ b/src/schema_features.h
@@ -30,7 +30,7 @@
* @return LY_SUCCESS on success.
* @return LY_ERR on error.
*/
-LY_ERR lys_eval_iffeatures(const struct ly_ctx *ctx, struct lysp_qname *iffeatures, ly_bool *enabled);
+LY_ERR lys_eval_iffeatures(const struct ly_ctx *ctx, const struct lysp_qname *iffeatures, ly_bool *enabled);
/**
* @brief Check whether all enabled features have their if-features satisfied.
diff --git a/src/set.c b/src/set.c
index d4836b8..1b8bfa5 100644
--- a/src/set.c
+++ b/src/set.c
@@ -76,7 +76,7 @@
}
LIBYANG_API_DEF ly_bool
-ly_set_contains(const struct ly_set *set, void *object, uint32_t *index_p)
+ly_set_contains(const struct ly_set *set, const void *object, uint32_t *index_p)
{
LY_CHECK_ARG_RET(NULL, set, 0);
@@ -95,7 +95,7 @@
}
LIBYANG_API_DEF LY_ERR
-ly_set_dup(const struct ly_set *set, void *(*duplicator)(void *obj), struct ly_set **newset_p)
+ly_set_dup(const struct ly_set *set, void *(*duplicator)(const void *obj), struct ly_set **newset_p)
{
struct ly_set *newset;
uint32_t u;
@@ -126,7 +126,7 @@
}
LIBYANG_API_DEF LY_ERR
-ly_set_add(struct ly_set *set, void *object, ly_bool list, uint32_t *index_p)
+ly_set_add(struct ly_set *set, const void *object, ly_bool list, uint32_t *index_p)
{
void **new;
@@ -157,13 +157,13 @@
if (index_p) {
*index_p = set->count;
}
- set->objs[set->count++] = object;
+ set->objs[set->count++] = (void *)object;
return LY_SUCCESS;
}
LIBYANG_API_DEF LY_ERR
-ly_set_merge(struct ly_set *trg, const struct ly_set *src, ly_bool list, void *(*duplicator)(void *obj))
+ly_set_merge(struct ly_set *trg, const struct ly_set *src, ly_bool list, void *(*duplicator)(const void *obj))
{
uint32_t u;
void *obj;
diff --git a/src/set.h b/src/set.h
index 636d3d0..3f79916 100644
--- a/src/set.h
+++ b/src/set.h
@@ -76,7 +76,7 @@
* @return LY_EMEM in case of memory allocation failure.
* @return LY_EINVAL in case of invalid parameters.
*/
-LIBYANG_API_DECL LY_ERR ly_set_dup(const struct ly_set *set, void *(*duplicator)(void *obj), struct ly_set **newset_p);
+LIBYANG_API_DECL LY_ERR ly_set_dup(const struct ly_set *set, void *(*duplicator)(const void *obj), struct ly_set **newset_p);
/**
* @brief Add an object into the set
@@ -91,7 +91,7 @@
* @return LY_EINVAL in case of invalid input parameters.
* @return LY_EMEM in case of memory allocation failure.
*/
-LIBYANG_API_DECL LY_ERR ly_set_add(struct ly_set *set, void *object, ly_bool list, uint32_t *index_p);
+LIBYANG_API_DECL LY_ERR ly_set_add(struct ly_set *set, const void *object, ly_bool list, uint32_t *index_p);
/**
* @brief Add all objects from \p src to \p trg.
@@ -108,7 +108,7 @@
* @return LY_EINVAL in case of invalid input parameters.
* @return LY_EMEM in case of memory allocation failure.
*/
-LIBYANG_API_DECL LY_ERR ly_set_merge(struct ly_set *trg, const struct ly_set *src, ly_bool list, void *(*duplicator)(void *obj));
+LIBYANG_API_DECL LY_ERR ly_set_merge(struct ly_set *trg, const struct ly_set *src, ly_bool list, void *(*duplicator)(const void *obj));
/**
* @brief Learn whether the set contains the specified object.
@@ -118,7 +118,7 @@
* @param[out] index_p Optional pointer to return index of the searched @p object.
* @return Boolean value whether the @p object was found in the @p set.
*/
-LIBYANG_API_DECL ly_bool ly_set_contains(const struct ly_set *set, void *object, uint32_t *index_p);
+LIBYANG_API_DECL ly_bool ly_set_contains(const struct ly_set *set, const void *object, uint32_t *index_p);
/**
* @brief Remove all objects from the set, but keep the set container for further use.
diff --git a/src/tree_data.c b/src/tree_data.c
index e416ea0..ceaea54 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -732,7 +732,7 @@
}
LIBYANG_API_DEF LY_ERR
-lyd_insert_ext(struct lyd_node *parent, struct lyd_node *first)
+lyplg_ext_insert(struct lyd_node *parent, struct lyd_node *first)
{
struct lyd_node *iter;
@@ -951,14 +951,14 @@
{
LY_ERR ret = LY_SUCCESS;
struct lysc_ext_instance *ant = NULL;
- const struct lysc_type **ant_type;
+ const struct lysc_type *ant_type;
struct lyd_meta *mt, *last;
LY_ARRAY_COUNT_TYPE u;
assert((parent || meta) && mod);
LY_ARRAY_FOR(mod->compiled->exts, u) {
- if (!strncmp(mod->compiled->exts[u].def->plugin->id, "libyang 2 - metadata", 20) &&
+ if (!strncmp(mod->compiled->exts[u].def->plugin->id, "ly2 metadata", 12) &&
!ly_strncmp(mod->compiled->exts[u].argument, name, name_len)) {
/* we have the annotation definition */
ant = &mod->compiled->exts[u];
@@ -977,8 +977,8 @@
LY_CHECK_ERR_GOTO(!mt, LOGMEM(mod->ctx); ret = LY_EMEM, cleanup);
mt->parent = parent;
mt->annotation = ant;
- ant_type = ant->substmts[ANNOTATION_SUBSTMT_TYPE].storage;
- ret = lyd_value_store(mod->ctx, &mt->value, *ant_type, value, value_len, dynamic, format, prefix_data, hints,
+ lyplg_ext_get_storage(ant, LY_STMT_TYPE, (const void **)&ant_type);
+ ret = lyd_value_store(mod->ctx, &mt->value, ant_type, value, value_len, dynamic, format, prefix_data, hints,
ctx_node, incomplete);
LY_CHECK_ERR_GOTO(ret, free(mt), cleanup);
ret = lydict_insert(mod->ctx, name, name_len, &mt->name);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 345c5db..3be476d 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -48,98 +48,6 @@
#include "tree_schema_internal.h"
#include "xpath.h"
-/**
- * @brief information about YANG statements
- */
-struct stmt_info_s stmt_attr_info[] = {
- [LY_STMT_NONE] = {NULL, NULL, 0},
- [LY_STMT_ACTION] = {"action", "name", STMT_FLAG_ID},
- [LY_STMT_ANYDATA] = {"anydata", "name", STMT_FLAG_ID},
- [LY_STMT_ANYXML] = {"anyxml", "name", STMT_FLAG_ID},
- [LY_STMT_ARGUMENT] = {"argument", "name", STMT_FLAG_ID},
- [LY_STMT_ARG_TEXT] = {"text", NULL, 0},
- [LY_STMT_ARG_VALUE] = {"value", NULL, 0},
- [LY_STMT_AUGMENT] = {"augment", "target-node", STMT_FLAG_ID},
- [LY_STMT_BASE] = {"base", "name", STMT_FLAG_ID},
- [LY_STMT_BELONGS_TO] = {"belongs-to", "module", STMT_FLAG_ID},
- [LY_STMT_BIT] = {"bit", "name", STMT_FLAG_ID},
- [LY_STMT_CASE] = {"case", "name", STMT_FLAG_ID},
- [LY_STMT_CHOICE] = {"choice", "name", STMT_FLAG_ID},
- [LY_STMT_CONFIG] = {"config", "value", STMT_FLAG_ID},
- [LY_STMT_CONTACT] = {"contact", "text", STMT_FLAG_YIN},
- [LY_STMT_CONTAINER] = {"container", "name", STMT_FLAG_ID},
- [LY_STMT_DEFAULT] = {"default", "value", 0},
- [LY_STMT_DESCRIPTION] = {"description", "text", STMT_FLAG_YIN},
- [LY_STMT_DEVIATE] = {"deviate", "value", STMT_FLAG_ID},
- [LY_STMT_DEVIATION] = {"deviation", "target-node", STMT_FLAG_ID},
- [LY_STMT_ENUM] = {"enum", "name", STMT_FLAG_ID},
- [LY_STMT_ERROR_APP_TAG] = {"error-app-tag", "value", 0},
- [LY_STMT_ERROR_MESSAGE] = {"error-message", "value", STMT_FLAG_YIN},
- [LY_STMT_EXTENSION] = {"extension", "name", STMT_FLAG_ID},
- [LY_STMT_EXTENSION_INSTANCE] = {NULL, NULL, 0},
- [LY_STMT_FEATURE] = {"feature", "name", STMT_FLAG_ID},
- [LY_STMT_FRACTION_DIGITS] = {"fraction-digits", "value", STMT_FLAG_ID},
- [LY_STMT_GROUPING] = {"grouping", "name", STMT_FLAG_ID},
- [LY_STMT_IDENTITY] = {"identity", "name", STMT_FLAG_ID},
- [LY_STMT_IF_FEATURE] = {"if-feature", "name", 0},
- [LY_STMT_IMPORT] = {"import", "module", STMT_FLAG_ID},
- [LY_STMT_INCLUDE] = {"include", "module", STMT_FLAG_ID},
- [LY_STMT_INPUT] = {"input", NULL, 0},
- [LY_STMT_KEY] = {"key", "value", 0},
- [LY_STMT_LEAF] = {"leaf", "name", STMT_FLAG_ID},
- [LY_STMT_LEAF_LIST] = {"leaf-list", "name", STMT_FLAG_ID},
- [LY_STMT_LENGTH] = {"length", "value", 0},
- [LY_STMT_LIST] = {"list", "name", STMT_FLAG_ID},
- [LY_STMT_MANDATORY] = {"mandatory", "value", STMT_FLAG_ID},
- [LY_STMT_MAX_ELEMENTS] = {"max-elements", "value", STMT_FLAG_ID},
- [LY_STMT_MIN_ELEMENTS] = {"min-elements", "value", STMT_FLAG_ID},
- [LY_STMT_MODIFIER] = {"modifier", "value", STMT_FLAG_ID},
- [LY_STMT_MODULE] = {"module", "name", STMT_FLAG_ID},
- [LY_STMT_MUST] = {"must", "condition", 0},
- [LY_STMT_NAMESPACE] = {"namespace", "uri", 0},
- [LY_STMT_NOTIFICATION] = {"notification", "name", STMT_FLAG_ID},
- [LY_STMT_ORDERED_BY] = {"ordered-by", "value", STMT_FLAG_ID},
- [LY_STMT_ORGANIZATION] = {"organization", "text", STMT_FLAG_YIN},
- [LY_STMT_OUTPUT] = {"output", NULL, 0},
- [LY_STMT_PATH] = {"path", "value", 0},
- [LY_STMT_PATTERN] = {"pattern", "value", 0},
- [LY_STMT_POSITION] = {"position", "value", STMT_FLAG_ID},
- [LY_STMT_PREFIX] = {"prefix", "value", STMT_FLAG_ID},
- [LY_STMT_PRESENCE] = {"presence", "value", 0},
- [LY_STMT_RANGE] = {"range", "value", 0},
- [LY_STMT_REFERENCE] = {"reference", "text", STMT_FLAG_YIN},
- [LY_STMT_REFINE] = {"refine", "target-node", STMT_FLAG_ID},
- [LY_STMT_REQUIRE_INSTANCE] = {"require-instance", "value", STMT_FLAG_ID},
- [LY_STMT_REVISION] = {"revision", "date", STMT_FLAG_ID},
- [LY_STMT_REVISION_DATE] = {"revision-date", "date", STMT_FLAG_ID},
- [LY_STMT_RPC] = {"rpc", "name", STMT_FLAG_ID},
- [LY_STMT_STATUS] = {"status", "value", STMT_FLAG_ID},
- [LY_STMT_SUBMODULE] = {"submodule", "name", STMT_FLAG_ID},
- [LY_STMT_SYNTAX_LEFT_BRACE] = {"{", NULL, 0},
- [LY_STMT_SYNTAX_RIGHT_BRACE] = {"}", NULL, 0},
- [LY_STMT_SYNTAX_SEMICOLON] = {";", NULL, 0},
- [LY_STMT_TYPE] = {"type", "name", STMT_FLAG_ID},
- [LY_STMT_TYPEDEF] = {"typedef", "name", STMT_FLAG_ID},
- [LY_STMT_UNIQUE] = {"unique", "tag", 0},
- [LY_STMT_UNITS] = {"units", "name", 0},
- [LY_STMT_USES] = {"uses", "name", STMT_FLAG_ID},
- [LY_STMT_VALUE] = {"value", "value", STMT_FLAG_ID},
- [LY_STMT_WHEN] = {"when", "condition", 0},
- [LY_STMT_YANG_VERSION] = {"yang-version", "value", STMT_FLAG_ID},
- [LY_STMT_YIN_ELEMENT] = {"yin-element", "value", STMT_FLAG_ID},
-};
-
-LIBYANG_API_DEF const char *
-ly_stmt2str(enum ly_stmt stmt)
-{
- if (stmt == LY_STMT_EXTENSION_INSTANCE) {
- return "extension instance";
- } else {
- return stmt_attr_info[stmt].name;
- }
-}
-
-
const char * const ly_devmod_list[] = {
[LYS_DEV_NOT_SUPPORTED] = "not-supported",
[LYS_DEV_ADD] = "add",
@@ -232,22 +140,22 @@
* be from an augment. If the @p ext is provided, the function is locked inside the schema tree defined in the
* extension instance.
*
- * ::lys_getnext_() is supposed to be called sequentially. In the first call, the \p last parameter is usually NULL
- * and function starts returning i) the first \p parent's child or ii) the first top level element specified in the
- * given extension (if provided) or iii) the first top level element of the \p module.
- * Consequent calls suppose to provide the previously returned node as the \p last parameter and still the same
- * \p parent and \p module parameters.
+ * ::lys_getnext_() is supposed to be called sequentially. In the first call, the @p last parameter is usually NULL
+ * and function starts returning i) the first @p parent's child or ii) the first top level element specified in the
+ * given extension (if provided) or iii) the first top level element of the @p module.
+ * Consequent calls suppose to provide the previously returned node as the @p last parameter and still the same
+ * @p parent and @p module parameters.
*
* Without options, the function is used to traverse only the schema nodes that can be paired with corresponding
- * data nodes in a data tree. By setting some \p options the behavior can be modified to the extent that
+ * data nodes in a data tree. By setting some @p options the behavior can be modified to the extent that
* all the schema nodes are iteratively returned.
*
* @param[in] last Previously returned schema tree node, or NULL in case of the first call.
* @param[in] parent Parent of the subtree where the function starts processing.
- * @param[in] module In case of iterating on top level elements, the \p parent is NULL and
+ * @param[in] module In case of iterating on top level elements, the @p parent is NULL and
* module must be specified.
* @param[in] ext The extension instance to provide a separate schema tree. To consider the top level elements in the tree,
- * the \p parent must be NULL. Anyway, at least one of @p parent, @p module and @p ext parameters must be specified.
+ * the @p parent must be NULL. Anyway, at least one of @p parent, @p module and @p ext parameters must be specified.
* @param[in] options [ORed options](@ref sgetnextflags).
* @return Next schema tree node that can be instantiated in a data tree, NULL in case there is no such element.
*/
@@ -257,7 +165,6 @@
{
const struct lysc_node *next = NULL;
ly_bool action_flag = 0, notif_flag = 0;
- struct lysc_node **data_p = NULL;
LY_CHECK_ARG_RET(NULL, parent || module || ext, NULL);
@@ -272,8 +179,8 @@
} else {
/* top level data */
if (ext) {
- lysc_ext_substmt(ext, LY_STMT_CONTAINER /* matches all nodes */, (void **)&data_p);
- next = last = data_p ? *data_p : NULL;
+ lyplg_ext_get_storage(ext, LY_STMT_DATA_NODE_MASK, (const void **)&last);
+ next = last;
} else {
next = last = module->data;
}
@@ -298,15 +205,13 @@
repeat:
if (!next) {
/* possibly go back to parent */
- data_p = NULL;
if (last && (last->parent != parent)) {
last = last->parent;
goto next;
} else if (!action_flag) {
action_flag = 1;
if (ext) {
- lysc_ext_substmt(ext, LY_STMT_RPC /* matches also actions */, (void **)&data_p);
- next = data_p ? *data_p : NULL;
+ lyplg_ext_get_storage(ext, LY_STMT_OP_MASK, (const void **)&next);
} else if (parent) {
next = (struct lysc_node *)lysc_node_actions(parent);
} else {
@@ -315,8 +220,7 @@
} else if (!notif_flag) {
notif_flag = 1;
if (ext) {
- lysc_ext_substmt(ext, LY_STMT_NOTIFICATION, (void **)&data_p);
- next = data_p ? *data_p : NULL;
+ lyplg_ext_get_storage(ext, LY_STMT_NOTIFICATION, (const void **)&next);
} else if (parent) {
next = (struct lysc_node *)lysc_node_notifs(parent);
} else {
@@ -1278,6 +1182,102 @@
}
/**
+ * @brief Generate path of the given paresed node.
+ *
+ * @param[in] node Schema path of this node will be generated.
+ * @param[in] parent Build relative path only until this parent is found. If NULL, the full absolute path is printed.
+ * @return NULL in case of memory allocation error, path of the node otherwise.
+ * In case the @p buffer is NULL, the returned string is dynamically allocated and caller is responsible to free it.
+ */
+static char *
+lysp_path_until(const struct lysp_node *node, const struct lysp_node *parent, const struct lysp_module *pmod)
+{
+ const struct lysp_node *iter, *par;
+ char *path = NULL, *s;
+ const char *slash;
+ int len = 0;
+
+ for (iter = node; iter && (iter != parent) && (len >= 0); iter = iter->parent) {
+ if (parent && (iter->parent == parent)) {
+ slash = "";
+ } else {
+ slash = "/";
+ }
+
+ s = path;
+ par = iter->parent;
+ if (!par) {
+ /* print prefix */
+ len = asprintf(&path, "%s%s:%s%s", slash, pmod->mod->name, iter->name, s ? s : "");
+ } else {
+ /* prefix is the same as in parent */
+ len = asprintf(&path, "%s%s%s", slash, iter->name, s ? s : "");
+ }
+ free(s);
+ }
+
+ if (len < 0) {
+ free(path);
+ path = NULL;
+ } else if (len == 0) {
+ path = strdup("/");
+ }
+
+ return path;
+}
+
+/**
+ * @brief Build log path for a parsed extension instance.
+ *
+ * @param[in] pcxt Parse context.
+ * @param[in] ext Parsed extension instance.
+ * @param[out] path Generated path.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lysp_resolve_ext_instance_log_path(const struct lysp_ctx *pctx, const struct lysp_ext_instance *ext, char **path)
+{
+ char *buf = NULL;
+ uint32_t used = 0, size = 0;
+
+ if (ext->parent_stmt & LY_STMT_NODE_MASK) {
+ /* parsed node path */
+ buf = lysp_path_until(ext->parent, NULL, PARSER_CUR_PMOD(pctx));
+ LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ size = used = strlen(buf);
+
+ /* slash */
+ size += 1;
+ buf = realloc(buf, size + 1);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ used += sprintf(buf + used, "/");
+ } else {
+ /* module */
+ size += 1 + strlen(PARSER_CUR_PMOD(pctx)->mod->name) + 1;
+ buf = realloc(buf, size + 1);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ used += sprintf(buf + used, "/%s:", PARSER_CUR_PMOD(pctx)->mod->name);
+ }
+
+ /* extension name */
+ size += 12 + strlen(ext->name) + 2;
+ buf = realloc(buf, size + 1);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ used += sprintf(buf + used, "{extension='%s'}", ext->name);
+
+ /* extension argument */
+ if (ext->argument) {
+ size += 1 + strlen(ext->argument);
+ buf = realloc(buf, size + 1);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
+ used += sprintf(buf + used, "/%s", ext->argument);
+ }
+
+ *path = buf;
+ return LY_SUCCESS;
+}
+
+/**
* @brief Resolve (find) all extension instance records and finish their parsing.
*
* @param[in] pctx Parse context with all the parsed extension instances.
@@ -1286,30 +1286,69 @@
static LY_ERR
lysp_resolve_ext_instance_records(struct lysp_ctx *pctx)
{
+ LY_ERR r;
+ struct lysf_ctx fctx = {.ctx = PARSER_CTX(pctx)};
struct lysp_ext_instance *exts, *ext;
const struct lys_module *mod;
- const char *ptr;
uint32_t i;
LY_ARRAY_COUNT_TYPE u;
+ char *path = NULL;
+ /* first finish parsing all extension instances ... */
for (i = 0; i < pctx->ext_inst.count; ++i) {
exts = pctx->ext_inst.objs[i];
LY_ARRAY_FOR(exts, u) {
ext = &exts[u];
- /* find the extension (definition) module */
- ptr = strchr(ext->name, ':');
- assert(ptr);
- mod = ly_resolve_prefix(PARSER_CTX(pctx), ext->name, ptr - ext->name, ext->format, ext->prefix_data);
- if (!mod) {
- LOGVAL(PARSER_CTX(pctx), LYVE_SYNTAX, "Unknown prefix \"%*.s\" used for an extension instance.",
- (int)(ptr - ext->name), ext->name);
- return LY_ENOTFOUND;
- }
+ /* find the extension definition */
+ LY_CHECK_RET(lysp_ext_find_definition(PARSER_CTX(pctx), ext, &mod, &ext->def));
+
+ /* resolve the argument, if needed */
+ LY_CHECK_RET(lysp_ext_instance_resolve_argument(PARSER_CTX(pctx), ext));
/* find the extension record, if any */
- ++ptr;
- ext->record = lyplg_ext_record_find(mod->name, mod->revision, ptr);
+ ext->record = lyplg_ext_record_find(mod->name, mod->revision, ext->def->name);
+ }
+ }
+
+ /* ... then call the parse callback */
+ for (i = 0; i < pctx->ext_inst.count; ++i) {
+ exts = pctx->ext_inst.objs[i];
+ u = 0;
+ while (u < LY_ARRAY_COUNT(exts)) {
+ ext = &exts[u];
+ if (!ext->record || !ext->record->plugin.parse) {
+ goto next_iter;
+ }
+
+ /* set up log path */
+ if ((r = lysp_resolve_ext_instance_log_path(pctx, ext, &path))) {
+ return r;
+ }
+ LOG_LOCINIT(NULL, NULL, path, NULL);
+
+ /* parse */
+ r = ext->record->plugin.parse(pctx, ext);
+
+ LOG_LOCBACK(0, 0, 1, 0);
+ free(path);
+
+ if (r == LY_ENOT) {
+ /* instance should be ignored, remove it */
+ lysp_ext_instance_free(&fctx, ext);
+ LY_ARRAY_DECREMENT(exts);
+ if (u < LY_ARRAY_COUNT(exts)) {
+ /* replace by the last item */
+ *ext = exts[LY_ARRAY_COUNT(exts)];
+ } /* else if there are no more items, leave the empty array, we are not able to free it */
+ continue;
+ } else if (r) {
+ /* error */
+ return r;
+ }
+
+next_iter:
+ ++u;
}
}
@@ -1413,31 +1452,32 @@
/**
* @brief Add ietf-netconf metadata to the parsed module. Operation, filter, and select are added.
*
+ * @param[in] pctx Parse context.
* @param[in] mod Parsed module to add to.
* @return LY_SUCCESS on success.
* @return LY_ERR on error.
*/
static LY_ERR
-lysp_add_internal_ietf_netconf(struct lysp_module *mod)
+lysp_add_internal_ietf_netconf(struct lysp_ctx *pctx, struct lysp_module *mod)
{
- struct lysp_ext_instance *ext_p;
+ struct lysp_ext_instance *extp;
struct lysp_stmt *stmt;
struct lysp_import *imp;
/*
* 1) edit-config's operation
*/
- LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
- LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "operation", 0, &ext_p->argument));
- ext_p->format = LY_VALUE_SCHEMA;
- ext_p->prefix_data = mod;
- ext_p->flags = LYS_INTERNAL;
- ext_p->parent_stmt = LY_STMT_MODULE;
- ext_p->parent_stmt_index = 0;
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
+ LY_CHECK_ERR_RET(!extp, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "operation", 0, &extp->argument));
+ extp->format = LY_VALUE_SCHEMA;
+ extp->prefix_data = mod;
+ extp->parent = mod;
+ extp->parent_stmt = LY_STMT_MODULE;
+ extp->flags = LYS_INTERNAL;
- ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ extp->child = stmt = calloc(1, sizeof *extp->child);
LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enumeration", 0, &stmt->arg));
@@ -1493,17 +1533,17 @@
/*
* 2) filter's type
*/
- LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
- LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &ext_p->argument));
- ext_p->format = LY_VALUE_SCHEMA;
- ext_p->prefix_data = mod;
- ext_p->flags = LYS_INTERNAL;
- ext_p->parent_stmt = LY_STMT_MODULE;
- ext_p->parent_stmt_index = 0;
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
+ LY_CHECK_ERR_RET(!extp, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &extp->argument));
+ extp->format = LY_VALUE_SCHEMA;
+ extp->prefix_data = mod;
+ extp->parent = mod;
+ extp->parent_stmt = LY_STMT_MODULE;
+ extp->flags = LYS_INTERNAL;
- ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ extp->child = stmt = calloc(1, sizeof *extp->child);
LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enumeration", 0, &stmt->arg));
@@ -1544,17 +1584,17 @@
/*
* 3) filter's select
*/
- LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
- LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "select", 0, &ext_p->argument));
- ext_p->format = LY_VALUE_SCHEMA;
- ext_p->prefix_data = mod;
- ext_p->flags = LYS_INTERNAL;
- ext_p->parent_stmt = LY_STMT_MODULE;
- ext_p->parent_stmt_index = 0;
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
+ LY_CHECK_ERR_RET(!extp, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "select", 0, &extp->argument));
+ extp->format = LY_VALUE_SCHEMA;
+ extp->prefix_data = mod;
+ extp->parent = mod;
+ extp->parent_stmt = LY_STMT_MODULE;
+ extp->flags = LYS_INTERNAL;
- ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ extp->child = stmt = calloc(1, sizeof *extp->child);
LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "yang_:xpath1.0", 0, &stmt->arg));
@@ -1562,15 +1602,18 @@
stmt->prefix_data = mod;
stmt->kw = LY_STMT_TYPE;
+ if (LY_ARRAY_COUNT(mod->exts) == 3) {
+ /* first extension instances */
+ LY_CHECK_RET(ly_set_add(&pctx->ext_inst, mod->exts, 1, NULL));
+ }
+
/* create new imports for the used prefixes */
LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
-
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-metadata", 0, &imp->name));
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_", 0, &imp->prefix));
imp->flags = LYS_INTERNAL;
LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
-
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-types", 0, &imp->name));
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "yang_", 0, &imp->prefix));
imp->flags = LYS_INTERNAL;
@@ -1581,31 +1624,31 @@
/**
* @brief Add ietf-netconf-with-defaults "default" metadata to the parsed module.
*
+ * @param[in] pctx Parse context.
* @param[in] mod Parsed module to add to.
* @return LY_SUCCESS on success.
* @return LY_ERR on error.
*/
static LY_ERR
-lysp_add_internal_ietf_netconf_with_defaults(struct lysp_module *mod)
+lysp_add_internal_ietf_netconf_with_defaults(struct lysp_ctx *pctx, struct lysp_module *mod)
{
- struct lysp_ext_instance *ext_p;
+ struct lysp_ext_instance *extp;
struct lysp_stmt *stmt;
struct lysp_import *imp;
/* add new extension instance */
- LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
/* fill in the extension instance fields */
- LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
- LY_CHECK_RET(lydict_insert(mod->mod->ctx, "default", 0, &ext_p->argument));
- ext_p->format = LY_VALUE_SCHEMA;
- ext_p->prefix_data = mod;
- ext_p->flags = LYS_INTERNAL;
- ext_p->parent_stmt = LY_STMT_MODULE;
- ext_p->parent_stmt_index = 0;
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "default", 0, &extp->argument));
+ extp->format = LY_VALUE_SCHEMA;
+ extp->prefix_data = mod;
+ extp->parent = mod;
+ extp->parent_stmt = LY_STMT_MODULE;
+ extp->flags = LYS_INTERNAL;
- ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ extp->child = stmt = calloc(1, sizeof *extp->child);
LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "boolean", 0, &stmt->arg));
@@ -1613,9 +1656,13 @@
stmt->prefix_data = mod;
stmt->kw = LY_STMT_TYPE;
+ if (LY_ARRAY_COUNT(mod->exts) == 1) {
+ /* first extension instance */
+ LY_CHECK_RET(ly_set_add(&pctx->ext_inst, mod->exts, 1, NULL));
+ }
+
/* create new import for the used prefix */
LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
-
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-metadata", 0, &imp->name));
LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_", 0, &imp->prefix));
imp->flags = LYS_INTERNAL;
@@ -1759,9 +1806,9 @@
/* add internal data in case specific modules were parsed */
if (!strcmp(mod->name, "ietf-netconf")) {
- LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf(mod->parsed), cleanup);
+ LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf(pctx, mod->parsed), cleanup);
} else if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
- LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf_with_defaults(mod->parsed), cleanup);
+ LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf_with_defaults(pctx, mod->parsed), cleanup);
}
/* add the module into newly created module set, will also be freed from there on any error */
diff --git a/src/tree_schema_common.c b/src/tree_schema_common.c
index 427d404..e82f6b9 100644
--- a/src/tree_schema_common.c
+++ b/src/tree_schema_common.c
@@ -40,6 +40,87 @@
#include "tree_schema.h"
#include "tree_schema_internal.h"
+/**
+ * @brief information about YANG statements
+ */
+struct stmt_info_s stmt_attr_info[] = {
+ [LY_STMT_NONE] = {NULL, NULL, 0},
+ [LY_STMT_ACTION] = {"action", "name", STMT_FLAG_ID},
+ [LY_STMT_ANYDATA] = {"anydata", "name", STMT_FLAG_ID},
+ [LY_STMT_ANYXML] = {"anyxml", "name", STMT_FLAG_ID},
+ [LY_STMT_ARGUMENT] = {"argument", "name", STMT_FLAG_ID},
+ [LY_STMT_ARG_TEXT] = {"text", NULL, 0},
+ [LY_STMT_ARG_VALUE] = {"value", NULL, 0},
+ [LY_STMT_AUGMENT] = {"augment", "target-node", STMT_FLAG_ID},
+ [LY_STMT_BASE] = {"base", "name", STMT_FLAG_ID},
+ [LY_STMT_BELONGS_TO] = {"belongs-to", "module", STMT_FLAG_ID},
+ [LY_STMT_BIT] = {"bit", "name", STMT_FLAG_ID},
+ [LY_STMT_CASE] = {"case", "name", STMT_FLAG_ID},
+ [LY_STMT_CHOICE] = {"choice", "name", STMT_FLAG_ID},
+ [LY_STMT_CONFIG] = {"config", "value", STMT_FLAG_ID},
+ [LY_STMT_CONTACT] = {"contact", "text", STMT_FLAG_YIN},
+ [LY_STMT_CONTAINER] = {"container", "name", STMT_FLAG_ID},
+ [LY_STMT_DEFAULT] = {"default", "value", 0},
+ [LY_STMT_DESCRIPTION] = {"description", "text", STMT_FLAG_YIN},
+ [LY_STMT_DEVIATE] = {"deviate", "value", STMT_FLAG_ID},
+ [LY_STMT_DEVIATION] = {"deviation", "target-node", STMT_FLAG_ID},
+ [LY_STMT_ENUM] = {"enum", "name", STMT_FLAG_ID},
+ [LY_STMT_ERROR_APP_TAG] = {"error-app-tag", "value", 0},
+ [LY_STMT_ERROR_MESSAGE] = {"error-message", "value", STMT_FLAG_YIN},
+ [LY_STMT_EXTENSION] = {"extension", "name", STMT_FLAG_ID},
+ [LY_STMT_EXTENSION_INSTANCE] = {NULL, NULL, 0},
+ [LY_STMT_FEATURE] = {"feature", "name", STMT_FLAG_ID},
+ [LY_STMT_FRACTION_DIGITS] = {"fraction-digits", "value", STMT_FLAG_ID},
+ [LY_STMT_GROUPING] = {"grouping", "name", STMT_FLAG_ID},
+ [LY_STMT_IDENTITY] = {"identity", "name", STMT_FLAG_ID},
+ [LY_STMT_IF_FEATURE] = {"if-feature", "name", 0},
+ [LY_STMT_IMPORT] = {"import", "module", STMT_FLAG_ID},
+ [LY_STMT_INCLUDE] = {"include", "module", STMT_FLAG_ID},
+ [LY_STMT_INPUT] = {"input", NULL, 0},
+ [LY_STMT_KEY] = {"key", "value", 0},
+ [LY_STMT_LEAF] = {"leaf", "name", STMT_FLAG_ID},
+ [LY_STMT_LEAF_LIST] = {"leaf-list", "name", STMT_FLAG_ID},
+ [LY_STMT_LENGTH] = {"length", "value", 0},
+ [LY_STMT_LIST] = {"list", "name", STMT_FLAG_ID},
+ [LY_STMT_MANDATORY] = {"mandatory", "value", STMT_FLAG_ID},
+ [LY_STMT_MAX_ELEMENTS] = {"max-elements", "value", STMT_FLAG_ID},
+ [LY_STMT_MIN_ELEMENTS] = {"min-elements", "value", STMT_FLAG_ID},
+ [LY_STMT_MODIFIER] = {"modifier", "value", STMT_FLAG_ID},
+ [LY_STMT_MODULE] = {"module", "name", STMT_FLAG_ID},
+ [LY_STMT_MUST] = {"must", "condition", 0},
+ [LY_STMT_NAMESPACE] = {"namespace", "uri", 0},
+ [LY_STMT_NOTIFICATION] = {"notification", "name", STMT_FLAG_ID},
+ [LY_STMT_ORDERED_BY] = {"ordered-by", "value", STMT_FLAG_ID},
+ [LY_STMT_ORGANIZATION] = {"organization", "text", STMT_FLAG_YIN},
+ [LY_STMT_OUTPUT] = {"output", NULL, 0},
+ [LY_STMT_PATH] = {"path", "value", 0},
+ [LY_STMT_PATTERN] = {"pattern", "value", 0},
+ [LY_STMT_POSITION] = {"position", "value", STMT_FLAG_ID},
+ [LY_STMT_PREFIX] = {"prefix", "value", STMT_FLAG_ID},
+ [LY_STMT_PRESENCE] = {"presence", "value", 0},
+ [LY_STMT_RANGE] = {"range", "value", 0},
+ [LY_STMT_REFERENCE] = {"reference", "text", STMT_FLAG_YIN},
+ [LY_STMT_REFINE] = {"refine", "target-node", STMT_FLAG_ID},
+ [LY_STMT_REQUIRE_INSTANCE] = {"require-instance", "value", STMT_FLAG_ID},
+ [LY_STMT_REVISION] = {"revision", "date", STMT_FLAG_ID},
+ [LY_STMT_REVISION_DATE] = {"revision-date", "date", STMT_FLAG_ID},
+ [LY_STMT_RPC] = {"rpc", "name", STMT_FLAG_ID},
+ [LY_STMT_STATUS] = {"status", "value", STMT_FLAG_ID},
+ [LY_STMT_SUBMODULE] = {"submodule", "name", STMT_FLAG_ID},
+ [LY_STMT_SYNTAX_LEFT_BRACE] = {"{", NULL, 0},
+ [LY_STMT_SYNTAX_RIGHT_BRACE] = {"}", NULL, 0},
+ [LY_STMT_SYNTAX_SEMICOLON] = {";", NULL, 0},
+ [LY_STMT_TYPE] = {"type", "name", STMT_FLAG_ID},
+ [LY_STMT_TYPEDEF] = {"typedef", "name", STMT_FLAG_ID},
+ [LY_STMT_UNIQUE] = {"unique", "tag", 0},
+ [LY_STMT_UNITS] = {"units", "name", 0},
+ [LY_STMT_USES] = {"uses", "name", STMT_FLAG_ID},
+ [LY_STMT_VALUE] = {"value", "value", STMT_FLAG_ID},
+ [LY_STMT_WHEN] = {"when", "condition", 0},
+ [LY_STMT_YANG_VERSION] = {"yang-version", "value", STMT_FLAG_ID},
+ [LY_STMT_YIN_ELEMENT] = {"yin-element", "value", STMT_FLAG_ID},
+};
+
LY_ERR
lysp_check_prefix(struct lysp_ctx *ctx, struct lysp_import *imports, const char *module_prefix, const char **value)
{
@@ -256,7 +337,7 @@
{
const char *str, *name;
struct lysp_tpdf *typedefs;
- const struct lysp_tpdf **ext_typedefs;
+ const struct lysp_tpdf *ext_typedefs;
const struct lys_module *mod;
const struct lysp_module *local_module;
LY_ARRAY_COUNT_TYPE u, v;
@@ -300,8 +381,8 @@
if (ext) {
/* search typedefs directly in the extension */
- ext_typedefs = (void *)lys_compile_ext_instance_get_storage(ext, LY_STMT_TYPEDEF);
- if (ext_typedefs && (*tpdf = lysp_typedef_match(name, *ext_typedefs))) {
+ lyplg_ext_parsed_get_storage(ext, LY_STMT_TYPEDEF, (const void **)&ext_typedefs);
+ if ((*tpdf = lysp_typedef_match(name, ext_typedefs))) {
/* match */
return LY_SUCCESS;
}
@@ -1348,43 +1429,6 @@
}
}
-LIBYANG_API_DEF enum ly_stmt
-lys_nodetype2stmt(uint16_t nodetype)
-{
- switch (nodetype) {
- case LYS_CONTAINER:
- return LY_STMT_CONTAINER;
- case LYS_CHOICE:
- return LY_STMT_CHOICE;
- case LYS_LEAF:
- return LY_STMT_LEAF;
- case LYS_LEAFLIST:
- return LY_STMT_LEAF_LIST;
- case LYS_LIST:
- return LY_STMT_LIST;
- case LYS_ANYXML:
- return LY_STMT_ANYXML;
- case LYS_ANYDATA:
- return LY_STMT_ANYDATA;
- case LYS_CASE:
- return LY_STMT_CASE;
- case LYS_RPC:
- return LY_STMT_RPC;
- case LYS_ACTION:
- return LY_STMT_ACTION;
- case LYS_NOTIF:
- return LY_STMT_NOTIFICATION;
- case LYS_USES:
- return LY_STMT_USES;
- case LYS_INPUT:
- return LY_STMT_INPUT;
- case LYS_OUTPUT:
- return LY_STMT_OUTPUT;
- default:
- return LY_STMT_NONE;
- }
-}
-
const char *
lys_datatype2str(LY_DATA_TYPE basetype)
{
@@ -2092,11 +2136,8 @@
const struct lys_module *mod = NULL;
const struct lysp_submodule *submod;
- assert(ext_def);
-
- *ext_def = NULL;
- if (ext_mod) {
- *ext_mod = NULL;
+ if (ext_def) {
+ *ext_def = NULL;
}
/* parse the prefix, the nodeid was previously already parsed and checked */
@@ -2104,7 +2145,7 @@
ly_parse_nodeid(&tmp, &prefix, &pref_len, &name, &name_len);
/* get module where the extension definition should be placed */
- mod = ly_resolve_prefix(ctx, prefix, pref_len, ext->format, ext->prefix_data);
+ *ext_mod = mod = ly_resolve_prefix(ctx, prefix, pref_len, ext->format, ext->prefix_data);
if (!mod) {
LOGVAL(ctx, LYVE_REFERENCE, "Invalid prefix \"%.*s\" used for extension instance identifier.", (int)pref_len, prefix);
return LY_EVALID;
@@ -2114,6 +2155,11 @@
return LY_EVALID;
}
+ if (!ext_def) {
+ /* we are done */
+ return LY_SUCCESS;
+ }
+
/* find the parsed extension definition there */
LY_ARRAY_FOR(mod->parsed->extensions, v) {
if (!strcmp(name, mod->parsed->extensions[v].name)) {
@@ -2138,25 +2184,24 @@
return LY_EVALID;
}
- if (ext_mod) {
- *ext_mod = mod;
- }
return LY_SUCCESS;
}
LY_ERR
-lysp_ext_instance_resolve_argument(struct ly_ctx *ctx, struct lysp_ext_instance *ext_p, struct lysp_ext *ext_def)
+lysp_ext_instance_resolve_argument(struct ly_ctx *ctx, struct lysp_ext_instance *ext_p)
{
- if (!ext_def->argname || ext_p->argument) {
+ assert(ext_p->def);
+
+ if (!ext_p->def->argname || ext_p->argument) {
/* nothing to do */
return LY_SUCCESS;
}
if (ext_p->format == LY_VALUE_XML) {
- /* Schema was parsed from YIN and an argument is expected, ... */
+ /* schema was parsed from YIN and an argument is expected, ... */
struct lysp_stmt *stmt = NULL;
- if (ext_def->flags & LYS_YINELEM_TRUE) {
+ if (ext_p->def->flags & LYS_YINELEM_TRUE) {
/* ... argument was the first XML child element */
for (stmt = ext_p->child; stmt && (stmt->flags & LYS_YIN_ATTR); stmt = stmt->next) {}
if (stmt) {
@@ -2167,9 +2212,9 @@
arg = stmt->stmt;
ly_parse_nodeid(&arg, &prefix_arg, &prefix_arg_len, &name_arg, &name_arg_len);
- if (ly_strncmp(ext_def->argname, name_arg, name_arg_len)) {
+ if (ly_strncmp(ext_p->def->argname, name_arg, name_arg_len)) {
LOGVAL(ctx, LYVE_SEMANTICS, "Extension instance \"%s\" expects argument element \"%s\" as its first XML child, "
- "but \"%.*s\" element found.", ext_p->name, ext_def->argname, (int)name_arg_len, name_arg);
+ "but \"%.*s\" element found.", ext_p->name, ext_p->def->argname, (int)name_arg_len, name_arg);
return LY_EVALID;
}
@@ -2181,15 +2226,14 @@
if (ly_resolve_prefix(ctx, prefix_ext, prefix_ext_len, ext_p->format, ext_p->prefix_data) !=
ly_resolve_prefix(ctx, prefix_arg, prefix_arg_len, stmt->format, stmt->prefix_data)) {
LOGVAL(ctx, LYVE_SEMANTICS, "Extension instance \"%s\" element and its argument element \"%s\" are "
- "expected in the same namespace, but they differ.", ext_p->name, ext_def->argname);
+ "expected in the same namespace, but they differ.", ext_p->name, ext_p->def->argname);
return LY_EVALID;
}
}
} else {
- /* ... argument was one of the XML attributes which are represented as child stmt
- * with LYS_YIN_ATTR flag */
+ /* ... argument was one of the XML attributes which are represented as child stmt with LYS_YIN_ATTR flag */
for (stmt = ext_p->child; stmt && (stmt->flags & LYS_YIN_ATTR); stmt = stmt->next) {
- if (!strcmp(stmt->stmt, ext_def->argname)) {
+ if (!strcmp(stmt->stmt, ext_p->def->argname)) {
/* this is the extension's argument */
break;
}
@@ -2204,8 +2248,8 @@
if (!ext_p->argument) {
/* missing extension's argument */
- LOGVAL(ctx, LYVE_SEMANTICS, "Extension instance \"%s\" misses argument %s\"%s\".",
- ext_p->name, (ext_def->flags & LYS_YINELEM_TRUE) ? "element " : "", ext_def->argname);
+ LOGVAL(ctx, LYVE_SEMANTICS, "Extension instance \"%s\" missing argument %s\"%s\".",
+ ext_p->name, (ext_p->def->flags & LYS_YINELEM_TRUE) ? "element " : "", ext_p->def->argname);
return LY_EVALID;
}
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 21d7539..9eedecf 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -33,11 +33,10 @@
#include "xml.h"
#include "xpath.h"
-static void lysc_extension_free(struct lysf_ctx *ctx, struct lysc_ext **ext);
static void lysc_node_free_(struct lysf_ctx *ctx, struct lysc_node *node);
void
-lysp_qname_free(struct ly_ctx *ctx, struct lysp_qname *qname)
+lysp_qname_free(const struct ly_ctx *ctx, struct lysp_qname *qname)
{
if (qname) {
lydict_remove(ctx, qname->str);
@@ -70,13 +69,12 @@
lysp_ext_instance_free(struct lysf_ctx *ctx, struct lysp_ext_instance *ext)
{
struct lysp_stmt *stmt, *next;
- struct lysp_node *node, *next_node;
lydict_remove(ctx->ctx, ext->name);
lydict_remove(ctx->ctx, ext->argument);
ly_free_prefix_data(ext->format, ext->prefix_data);
- LY_LIST_FOR_SAFE(ext->parsed, next_node, node) {
- lysp_node_free(ctx, node);
+ if (ext->record && ext->record->plugin.pfree) {
+ ext->record->plugin.pfree(ctx->ctx, ext);
}
LY_LIST_FOR_SAFE(ext->child, next, stmt) {
@@ -164,6 +162,29 @@
}
/**
+ * @brief Free the compiled extension definition and NULL the provided pointer.
+ *
+ * @param[in] ctx Free context.
+ * @param[in,out] ext Compiled extension definition to be freed.
+ */
+static void
+lysc_extension_free(struct lysf_ctx *ctx, struct lysc_ext **ext)
+{
+ if (ly_set_contains(&ctx->ext_set, *ext, NULL)) {
+ /* already freed and only referenced again in this module */
+ return;
+ }
+
+ /* remember this extension to be freed, nothing to do on error */
+ (void)ly_set_add(&ctx->ext_set, *ext, 0, NULL);
+
+ /* recursive exts free */
+ FREE_ARRAY(ctx, (*ext)->exts, lysc_ext_instance_free);
+
+ *ext = NULL;
+}
+
+/**
* @brief Free the parsed ext structure.
*
* @param[in] ctx Free context.
@@ -637,34 +658,11 @@
free(module);
}
-/**
- * @brief Free the compiled extension definition and NULL the provided pointer.
- *
- * @param[in] ctx Free context.
- * @param[in,out] ext Compiled extension definition to be freed.
- */
-static void
-lysc_extension_free(struct lysf_ctx *ctx, struct lysc_ext **ext)
-{
- if (ly_set_contains(&ctx->ext_set, *ext, NULL)) {
- /* already freed and only referenced again in this module */
- return;
- }
-
- /* remember this extension to be freed, nothing to do on error */
- (void)ly_set_add(&ctx->ext_set, *ext, 0, NULL);
-
- /* recursive exts free */
- FREE_ARRAY(ctx, (*ext)->exts, lysc_ext_instance_free);
-
- *ext = NULL;
-}
-
void
lysc_ext_instance_free(struct lysf_ctx *ctx, struct lysc_ext_instance *ext)
{
- if (ext->def && ext->def->plugin && ext->def->plugin->free) {
- ext->def->plugin->free(ctx->ctx, ext);
+ if (ext->def && ext->def->plugin && ext->def->plugin->cfree) {
+ ext->def->plugin->cfree(ctx->ctx, ext);
}
lydict_remove(ctx->ctx, ext->argument);
FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
@@ -1354,10 +1352,11 @@
}
LIBYANG_API_DEF void
-lyplg_ext_instance_substatements_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts)
+lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext_substmt *substmts)
{
LY_ARRAY_COUNT_TYPE u;
- struct lysf_ctx fctx = {.ctx = ctx};
+ struct lysf_ctx fctx = {.ctx = (struct ly_ctx *)ctx};
+ ly_bool node_free;
LY_ARRAY_FOR(substmts, u) {
if (!substmts[u].storage) {
@@ -1365,42 +1364,240 @@
}
switch (substmts[u].stmt) {
+ case LY_STMT_NOTIFICATION:
+ case LY_STMT_INPUT:
+ case LY_STMT_OUTPUT:
case LY_STMT_ACTION:
+ case LY_STMT_RPC:
case LY_STMT_ANYDATA:
case LY_STMT_ANYXML:
- case LY_STMT_CONTAINER:
+ case LY_STMT_AUGMENT:
+ case LY_STMT_CASE:
case LY_STMT_CHOICE:
+ case LY_STMT_CONTAINER:
+ case LY_STMT_GROUPING:
case LY_STMT_LEAF:
case LY_STMT_LEAF_LIST:
case LY_STMT_LIST:
- case LY_STMT_NOTIFICATION:
- case LY_STMT_RPC: {
- struct lysc_node *child, *child_next;
+ case LY_STMT_USES: {
+ struct lysp_node *child, *child_next;
- LY_LIST_FOR_SAFE(*((struct lysc_node **)substmts[u].storage), child_next, child) {
- lysc_node_free_(&fctx, child);
+ LY_LIST_FOR_SAFE(*((struct lysp_node **)substmts[u].storage), child_next, child) {
+ node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
+ lysp_node_free(&fctx, child);
+ if (node_free) {
+ free(child);
+ }
}
*((struct lysc_node **)substmts[u].storage) = NULL;
break;
}
- case LY_STMT_GROUPING: {
- struct lysp_node_grp *grp, *grp_next;
-
- LY_LIST_FOR_SAFE(*((struct lysp_node_grp **)substmts[u].storage), grp_next, grp) {
- lysp_node_free(&fctx, &grp->node);
- }
+ case LY_STMT_BASE:
+ /* multiple strings */
+ FREE_ARRAY(ctx, **(const char ***)substmts[u].storage, lydict_remove);
break;
- }
- case LY_STMT_USES:
+
+ case LY_STMT_BIT:
+ case LY_STMT_ENUM:
+ /* single enum */
+ lysp_type_enum_free(&fctx, *(struct lysp_type_enum **)substmts[u].storage);
+ break;
+
+ case LY_STMT_DEVIATE:
+ /* single deviate */
+ lysp_deviate_free(&fctx, *(struct lysp_deviate **)substmts[u].storage);
+ break;
+
+ case LY_STMT_DEVIATION:
+ /* single deviation */
+ lysp_deviation_free(&fctx, *(struct lysp_deviation **)substmts[u].storage);
+ break;
+
+ case LY_STMT_EXTENSION:
+ /* single extension */
+ lysp_ext_free(&fctx, *(struct lysp_ext **)substmts[u].storage);
+ break;
+
+ case LY_STMT_EXTENSION_INSTANCE:
+ /* multiple extension instances */
+ FREE_ARRAY(&fctx, *(struct lysp_ext_instance **)substmts[u].storage, lysp_ext_instance_free);
+ break;
+
+ case LY_STMT_FEATURE:
+ /* multiple features */
+ FREE_ARRAY(&fctx, *(struct lysp_feature **)substmts[u].storage, lysp_feature_free);
+ break;
+
+ case LY_STMT_IDENTITY:
+ /* multiple identities */
+ FREE_ARRAY(&fctx, *(struct lysp_ident **)substmts[u].storage, lysp_ident_free);
+ break;
+
+ case LY_STMT_IMPORT:
+ /* multiple imports */
+ FREE_ARRAY(&fctx, *(struct lysp_import **)substmts[u].storage, lysp_import_free);
+ break;
+
+ case LY_STMT_INCLUDE:
+ /* multiple includes */
+ FREE_ARRAY(&fctx, *(struct lysp_include **)substmts[u].storage, lysp_include_free);
+ break;
+
+ case LY_STMT_REFINE:
+ /* multiple refines */
+ FREE_ARRAY(&fctx, *(struct lysp_refine **)substmts[u].storage, lysp_refine_free);
+ break;
+
+ case LY_STMT_REVISION:
+ /* multiple revisions */
+ FREE_ARRAY(&fctx, *(struct lysp_revision **)substmts[u].storage, lysp_revision_free);
+ break;
+
case LY_STMT_CONFIG:
+ case LY_STMT_FRACTION_DIGITS:
+ case LY_STMT_MANDATORY:
+ case LY_STMT_MAX_ELEMENTS:
+ case LY_STMT_MIN_ELEMENTS:
+ case LY_STMT_ORDERED_BY:
+ case LY_STMT_POSITION:
+ case LY_STMT_REQUIRE_INSTANCE:
case LY_STMT_STATUS:
+ case LY_STMT_VALUE:
+ case LY_STMT_YANG_VERSION:
+ case LY_STMT_YIN_ELEMENT:
/* nothing to do */
break;
+
+ case LY_STMT_ARGUMENT:
+ case LY_STMT_BELONGS_TO:
case LY_STMT_CONTACT:
case LY_STMT_DESCRIPTION:
case LY_STMT_ERROR_APP_TAG:
case LY_STMT_ERROR_MESSAGE:
case LY_STMT_KEY:
+ case LY_STMT_MODIFIER:
+ case LY_STMT_NAMESPACE:
+ case LY_STMT_ORGANIZATION:
+ case LY_STMT_PREFIX:
+ case LY_STMT_PRESENCE:
+ case LY_STMT_REFERENCE:
+ case LY_STMT_REVISION_DATE:
+ case LY_STMT_UNITS:
+ /* single string */
+ lydict_remove(ctx, *(const char **)substmts[u].storage);
+ break;
+
+ case LY_STMT_LENGTH:
+ case LY_STMT_MUST:
+ case LY_STMT_PATTERN:
+ case LY_STMT_RANGE:
+ /* multiple restrictions */
+ FREE_ARRAY(&fctx, *(struct lysp_restr **)substmts[u].storage, lysp_restr_free);
+ break;
+
+ case LY_STMT_WHEN:
+ /* multiple whens */
+ FREE_ARRAY(&fctx, *(struct lysp_when **)substmts[u].storage, lysp_when_free);
+ break;
+
+ case LY_STMT_PATH:
+ /* single expression */
+ lyxp_expr_free(ctx, *(struct lyxp_expr **)substmts[u].storage);
+ break;
+
+ case LY_STMT_DEFAULT:
+ case LY_STMT_IF_FEATURE:
+ case LY_STMT_UNIQUE:
+ /* multiple qnames */
+ FREE_ARRAY(ctx, *(struct lysp_qname **)substmts[u].storage, lysp_qname_free);
+ break;
+
+ case LY_STMT_TYPEDEF:
+ /* multiple typedefs */
+ FREE_ARRAY(&fctx, *(struct lysp_tpdf **)substmts[u].storage, lysp_tpdf_free);
+ break;
+
+ case LY_STMT_TYPE: {
+ /* single type */
+ struct lysp_type **type_p = substmts[u].storage;
+
+ lysp_type_free(&fctx, *type_p);
+ free(*type_p);
+ break;
+ }
+ case LY_STMT_MODULE:
+ case LY_STMT_SUBMODULE:
+ /* single (sub)module */
+ lysp_module_free(&fctx, *(struct lysp_module **)substmts[u].storage);
+ break;
+
+ default:
+ LOGINT(ctx);
+ }
+ }
+
+ LY_ARRAY_FREE(substmts);
+}
+
+LIBYANG_API_DEF void
+lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext_substmt *substmts)
+{
+ LY_ARRAY_COUNT_TYPE u;
+ struct lysf_ctx fctx = {.ctx = (struct ly_ctx *)ctx};
+ ly_bool node_free;
+
+ LY_ARRAY_FOR(substmts, u) {
+ if (!substmts[u].storage) {
+ continue;
+ }
+
+ switch (substmts[u].stmt) {
+ case LY_STMT_NOTIFICATION:
+ case LY_STMT_INPUT:
+ case LY_STMT_OUTPUT:
+ case LY_STMT_ACTION:
+ case LY_STMT_RPC:
+ case LY_STMT_ANYDATA:
+ case LY_STMT_ANYXML:
+ case LY_STMT_CASE:
+ case LY_STMT_CHOICE:
+ case LY_STMT_CONTAINER:
+ case LY_STMT_LEAF:
+ case LY_STMT_LEAF_LIST:
+ case LY_STMT_LIST: {
+ struct lysc_node *child, *child_next;
+
+ LY_LIST_FOR_SAFE(*((struct lysc_node **)substmts[u].storage), child_next, child) {
+ node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
+ lysc_node_free_(&fctx, child);
+ if (node_free) {
+ free(child);
+ }
+ }
+ *((struct lysc_node **)substmts[u].storage) = NULL;
+ break;
+ }
+ case LY_STMT_USES:
+ case LY_STMT_CONFIG:
+ case LY_STMT_FRACTION_DIGITS:
+ case LY_STMT_MANDATORY:
+ case LY_STMT_MAX_ELEMENTS:
+ case LY_STMT_MIN_ELEMENTS:
+ case LY_STMT_ORDERED_BY:
+ case LY_STMT_POSITION:
+ case LY_STMT_REQUIRE_INSTANCE:
+ case LY_STMT_STATUS:
+ case LY_STMT_VALUE:
+ /* nothing to do */
+ break;
+
+ case LY_STMT_ARGUMENT:
+ case LY_STMT_CONTACT:
+ case LY_STMT_DESCRIPTION:
+ case LY_STMT_ERROR_APP_TAG:
+ case LY_STMT_ERROR_MESSAGE:
+ case LY_STMT_KEY:
+ case LY_STMT_MODIFIER:
case LY_STMT_NAMESPACE:
case LY_STMT_ORGANIZATION:
case LY_STMT_PRESENCE:
@@ -1412,44 +1609,88 @@
lydict_remove(ctx, str);
break;
}
+ case LY_STMT_BIT:
+ case LY_STMT_ENUM: {
+ /* sized array */
+ struct lysc_type_bitenum_item *items = *((struct lysc_type_bitenum_item **)substmts[u].storage);
+
+ FREE_ARRAY(&fctx, items, lysc_enum_item_free);
+ break;
+ }
+ case LY_STMT_LENGTH:
+ case LY_STMT_RANGE: {
+ /* single item */
+ struct lysc_range *range = *((struct lysc_range **)substmts[u].storage);
+
+ lysc_range_free(&fctx, range);
+ break;
+ }
case LY_STMT_MUST: {
- /* multiple items */
+ /* sized array */
struct lysc_must *musts = *((struct lysc_must **)substmts[u].storage);
FREE_ARRAY(&fctx, musts, lysc_must_free);
break;
}
- case LY_STMT_IF_FEATURE: {
- struct lysc_iffeature *iff = *((struct lysc_iffeature **)substmts[u].storage);
-
- if (!iff) {
- break;
- }
- /* multiple items */
- FREE_ARRAY(&fctx, iff, lysc_iffeature_free);
+ case LY_STMT_WHEN:
+ /* single item, expects a pointer */
+ lysc_when_free(&fctx, substmts[u].storage);
break;
- }
- case LY_STMT_TYPEDEF: {
- struct lysp_tpdf *tpdf = *((struct lysp_tpdf **)substmts[u].storage);
- if (!tpdf) {
- break;
- }
- /* always an array */
- FREE_ARRAY(&fctx, tpdf, lysp_tpdf_free);
+ case LY_STMT_PATTERN: {
+ /* sized array of pointers */
+ struct lysc_pattern **patterns = *((struct lysc_pattern ***)substmts[u].storage);
+
+ FREE_ARRAY(&fctx, patterns, lysc_pattern_free);
break;
}
case LY_STMT_TYPE: {
/* single item */
struct lysc_type *type = *((struct lysc_type **)substmts[u].storage);
- if (!type) {
- break;
- }
lysc_type_free(&fctx, type);
break;
}
- /* TODO other statements */
+ case LY_STMT_IDENTITY: {
+ /* sized array */
+ struct lysc_ident *idents = *((struct lysc_ident **)substmts[u].storage);
+
+ FREE_ARRAY(&fctx, idents, lysc_ident_free);
+ break;
+ }
+ case LY_STMT_EXTENSION_INSTANCE: {
+ /* sized array */
+ struct lysc_ext_instance *exts = *((struct lysc_ext_instance **)substmts[u].storage);
+
+ FREE_ARRAY(&fctx, exts, lysc_ext_instance_free);
+ break;
+ }
+ case LY_STMT_AUGMENT:
+ case LY_STMT_BASE:
+ case LY_STMT_BELONGS_TO:
+ case LY_STMT_DEFAULT:
+ case LY_STMT_DEVIATE:
+ case LY_STMT_DEVIATION:
+ case LY_STMT_EXTENSION:
+ case LY_STMT_FEATURE:
+ case LY_STMT_GROUPING:
+ case LY_STMT_IF_FEATURE:
+ case LY_STMT_IMPORT:
+ case LY_STMT_INCLUDE:
+ case LY_STMT_MODULE:
+ case LY_STMT_PATH:
+ case LY_STMT_PREFIX:
+ case LY_STMT_REFINE:
+ case LY_STMT_REVISION:
+ case LY_STMT_REVISION_DATE:
+ case LY_STMT_SUBMODULE:
+ case LY_STMT_TYPEDEF:
+ case LY_STMT_UNIQUE:
+ case LY_STMT_YANG_VERSION:
+ case LY_STMT_YIN_ELEMENT:
+ /* it is not possible to compile these statements */
+ break;
+
default:
LOGINT(ctx);
}
diff --git a/src/tree_schema_free.h b/src/tree_schema_free.h
index 778190b..d79164b 100644
--- a/src/tree_schema_free.h
+++ b/src/tree_schema_free.h
@@ -50,7 +50,7 @@
* @param[in] ctx libyang context.
* @param[in] qname Qualified name to free.
*/
-void lysp_qname_free(struct ly_ctx *ctx, struct lysp_qname *qname);
+void lysp_qname_free(const struct ly_ctx *ctx, struct lysp_qname *qname);
/**
* @brief Free the parsed extension instance structure.
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index a72ae74..31b5344 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -150,6 +150,7 @@
struct ly_set grps_nodes; /**< Set of nodes that contain grouping(s). Invalid in case of
submodule, use ::lysp_ctx.main_ctx instead. */
struct ly_set ext_inst; /**< parsed extension instances to finish parsing */
+
struct ly_set *parsed_mods; /**< (sub)modules being parsed, the last one is the current */
struct lysp_ctx *main_ctx; /**< This pointer must not be NULL. If this context deals with the submodule,
then should be set to the context of the module to which it belongs,
@@ -166,6 +167,7 @@
struct ly_set grps_nodes; /**< Set of nodes that contain grouping(s). Invalid in case of
submodule, use ::lysp_ctx.main_ctx instead. */
struct ly_set ext_inst; /**< parsed extension instances to finish parsing */
+
struct ly_set *parsed_mods; /**< (sub)modules being parsed, the last one is the current */
struct lysp_ctx *main_ctx; /**< This pointer must not be NULL. If this context deals with the submodule,
then should be set to the context of the module to which it belongs,
@@ -185,6 +187,7 @@
struct ly_set grps_nodes; /**< Set of nodes that contain grouping(s). Invalid in case of
submodule, use ::lysp_ctx.main_ctx instead. */
struct ly_set ext_inst; /**< parsed extension instances to finish parsing */
+
struct ly_set *parsed_mods; /**< (sub)modules being parsed, the last one is the current */
struct lysp_ctx *main_ctx; /**< This pointer must not be NULL. If this context deals with the submodule,
then should be set to the context of the module to which it belongs,
@@ -193,7 +196,7 @@
};
/**
- * @brief Check that \p c is valid UTF8 code point for YANG string.
+ * @brief Check that @p c is valid UTF8 code point for YANG string.
*
* @param[in] ctx parser context for logging.
* @param[in] c UTF8 code point of a character to check.
@@ -202,14 +205,14 @@
LY_ERR lysp_check_stringchar(struct lysp_ctx *ctx, uint32_t c);
/**
- * @brief Check that \p c is valid UTF8 code point for YANG identifier.
+ * @brief Check that @p c is valid UTF8 code point for YANG identifier.
*
* @param[in] ctx parser context for logging. If NULL, does not log.
* @param[in] c UTF8 code point of a character to check.
* @param[in] first Flag to check the first character of an identifier, which is more restricted.
* @param[in,out] prefix Storage for internally used flag in case of possible prefixed identifiers:
* 0 - colon not yet found (no prefix)
- * 1 - \p c is the colon character
+ * 1 - @p c is the colon character
* 2 - prefix already processed, now processing the identifier
*
* If the identifier cannot be prefixed, NULL is expected.
@@ -449,8 +452,8 @@
*
* @param[in] ctx libyang context.
* @param[in] ext Extension instance for which the definition will be searched.
- * @param[in, out] ext_mod Pointer to the module where the extension definition of the @p ext to correctly resolve prefixes.
- * @param[out] ext_def Pointer to return found extension definition.
+ * @param[out] ext_mod Module of the extension definition of @p ext.
+ * @param[out] ext_def Optional found extension definition.
* @return LY_SUCCESS when the definition was found.
* @return LY_EVALID when the extension instance is invalid and/or the definition not found.
*/
@@ -478,21 +481,17 @@
* (it might come from import modules which is not yet parsed at that time). Therefore, all the attributes are stored
* as substatements and resolving argument is postponed.
*
- * There are 3 places which need the argument, so they resolve it when missing - YIN and YANG printers and extension instance
- * compiler.
- *
* @param[in] ctx libyang context
* @param[in] ext_p Parsed extension to be updated.
- * @param[in] ext_def Extension definition, found with ::lysp_ext_find_definition().
* @return LY_ERR value.
*/
-LY_ERR lysp_ext_instance_resolve_argument(struct ly_ctx *ctx, struct lysp_ext_instance *ext_p, struct lysp_ext *ext_def);
+LY_ERR lysp_ext_instance_resolve_argument(struct ly_ctx *ctx, struct lysp_ext_instance *ext_p);
/**
* @brief Iterate over the specified type of the extension instances
*
* @param[in] ext ([Sized array](@ref sizedarrays)) of extensions to explore
- * @param[in] index Index in the \p ext array where to start searching (first call with 0, the consequent calls with
+ * @param[in] index Index in the @p ext array where to start searching (first call with 0, the consequent calls with
* the returned index increased by 1 (until the iteration is not terminated by returning LY_ARRAY_COUNT(ext).
* @param[in] substmt The statement the extension is supposed to belong to.
* @result index in the ext array, LY_ARRAY_COUNT(ext) value if not present.
@@ -599,17 +598,6 @@
uint8_t lysc_iff_getop(uint8_t *list, size_t pos);
/**
- * @brief Parse generic statement structure into a specific parsed-schema structure.
- *
- * @param[in] ctx The compilation context of the @p stmt being processed
- * @param[in] stmt Generic statement structure to process.
- * @param[out] result Specific parsed-schema structure for the given statement. For the specific type for the particular statement, check the function code.
- * @param[in,out] exts [sized array](@ref sizedarrays) For extension instances in case of statements that do not store extension instances in their own list.
- * @return LY_ERR value.
- */
-LY_ERR lysp_stmt_parse(struct lysc_ctx *ctx, const struct lysp_stmt *stmt, void **result, struct lysp_ext_instance **exts);
-
-/**
* @brief match yang keyword
*
* @param[in,out] in Input structure, is updated.
@@ -723,4 +711,16 @@
#define LYS_IS_SINGLE_DEP_SET(mod) \
(!(mod)->parsed->features && (!lys_has_compiled(mod) || ((mod)->compiled && !lys_has_recompiled(mod))))
+/**
+ * @brief Get pointer to a compiled ext instance storage for a specific statement.
+ *
+ * @param[in] ext Compiled ext instance.
+ * @param[in] stmt Compiled statement. Can be a mask when the first match is returned, it is expected the storage is
+ * the same for all the masked statements.
+ * @param[out] storage_p Pointer to a compiled ext instance substatement storage, NULL if was not compiled.
+ * @return LY_SUCCESS on success.
+ * @return LY_ENOT if the substatement is not supported.
+ */
+LY_ERR lyplg_ext_get_storage_p(const struct lysc_ext_instance *ext, int stmt, const void ***storage_p);
+
#endif /* LY_TREE_SCHEMA_INTERNAL_H_ */
diff --git a/src/validation.c b/src/validation.c
index 0283e19..8466147 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -345,9 +345,10 @@
--i;
struct lyd_meta *meta = meta_types->objs[i];
- struct lysc_type *type = *(struct lysc_type **)meta->annotation->substmts[ANNOTATION_SUBSTMT_TYPE].storage;
+ struct lysc_type *type;
/* validate and store the value of the metadata */
+ lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, (const void **)&type);
ret = lyd_value_validate_incomplete(LYD_CTX(meta->parent), type, &meta->value, meta->parent, *tree);
LY_CHECK_RET(ret);
@@ -1525,6 +1526,7 @@
struct lyd_node **diff)
{
const struct lyd_meta *meta;
+ const struct lysc_type *type;
struct lyd_node *node;
LYD_TREE_DFS_BEGIN(root, node) {
@@ -1539,7 +1541,8 @@
}
LY_LIST_FOR(node->meta, meta) {
- if ((*(const struct lysc_type **)meta->annotation->substmts[ANNOTATION_SUBSTMT_TYPE].storage)->plugin->validate) {
+ lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, (const void **)&type);
+ if (type->plugin->validate) {
/* metadata type resolution */
LY_CHECK_RET(ly_set_add(meta_types, (void *)meta, 1, NULL));
}