structure FEATURE support for augment-structure
WIP
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index 298557c..2c264a7 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -102,7 +102,7 @@
/**
* @brief Extensions API version
*/
-#define LYPLG_EXT_API_VERSION 5
+#define LYPLG_EXT_API_VERSION 6
/**
* @brief Macro to define plugin information in external plugins
diff --git a/src/plugins_exts/structure.c b/src/plugins_exts/structure.c
index 781cde0..3580ba3 100644
--- a/src/plugins_exts/structure.c
+++ b/src/plugins_exts/structure.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <string.h>
+#include "compat.h"
#include "libyang.h"
#include "plugins_exts.h"
@@ -29,6 +30,12 @@
struct lysc_node *child;
};
+struct lysc_ext_instance_augment_structure {
+ uint16_t flags;
+ const char *dsc;
+ const char *ref;
+};
+
/**
* @brief Compile structure extension instances.
*
@@ -37,11 +44,11 @@
static LY_ERR
structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
{
- LY_ERR ret;
+ LY_ERR rc;
LY_ARRAY_COUNT_TYPE u;
struct lysc_module *mod_c;
const struct lysc_node *child;
- struct lysc_ext_instance_structure *struct_ext;
+ struct lysc_ext_instance_structure *struct_data;
uint32_t prev_options = *lysc_ctx_get_options(cctx);
/* structure can appear only at the top level of a YANG module or submodule */
@@ -72,90 +79,229 @@
}
/* allocate the storage */
- struct_ext = calloc(1, sizeof *struct_ext);
- if (!struct_ext) {
+ struct_data = calloc(1, sizeof *struct_data);
+ if (!struct_data) {
goto emem;
}
- c_ext->data = struct_ext;
+ c_ext->data = struct_data;
/* compile substatements */
- LY_ARRAY_CREATE_GOTO(cctx->ctx, c_ext->substmts, 14, ret, emem);
+ 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].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[0].storage = &struct_ext->musts;
+ c_ext->substmts[0].storage = &struct_data->musts;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[1].stmt = LY_STMT_STATUS;
c_ext->substmts[1].cardinality = LY_STMT_CARD_OPT;
- c_ext->substmts[1].storage = &struct_ext->flags;
+ c_ext->substmts[1].storage = &struct_data->flags;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
c_ext->substmts[2].cardinality = LY_STMT_CARD_OPT;
- c_ext->substmts[2].storage = &struct_ext->dsc;
+ c_ext->substmts[2].storage = &struct_data->dsc;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[3].stmt = LY_STMT_REFERENCE;
c_ext->substmts[3].cardinality = LY_STMT_CARD_OPT;
- c_ext->substmts[3].storage = &struct_ext->ref;
+ c_ext->substmts[3].storage = &struct_data->ref;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[4].stmt = LY_STMT_TYPEDEF;
c_ext->substmts[4].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[4].storage = &struct_ext->typedefs;
+ c_ext->substmts[4].storage = &struct_data->typedefs;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[5].stmt = LY_STMT_GROUPING;
c_ext->substmts[5].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[5].storage = &struct_ext->groupings;
+ c_ext->substmts[5].storage = &struct_data->groupings;
/* data-def-stmt */
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[6].stmt = LY_STMT_CONTAINER;
c_ext->substmts[6].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[6].storage = &struct_ext->child;
+ c_ext->substmts[6].storage = &struct_data->child;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[7].stmt = LY_STMT_LEAF;
c_ext->substmts[7].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[7].storage = &struct_ext->child;
+ c_ext->substmts[7].storage = &struct_data->child;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
c_ext->substmts[8].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[8].storage = &struct_ext->child;
+ c_ext->substmts[8].storage = &struct_data->child;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[9].stmt = LY_STMT_LIST;
c_ext->substmts[9].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[9].storage = &struct_ext->child;
+ c_ext->substmts[9].storage = &struct_data->child;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[10].stmt = LY_STMT_CHOICE;
c_ext->substmts[10].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[10].storage = &struct_ext->child;
+ c_ext->substmts[10].storage = &struct_data->child;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[11].stmt = LY_STMT_ANYDATA;
c_ext->substmts[11].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[11].storage = &struct_ext->child;
+ c_ext->substmts[11].storage = &struct_data->child;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[12].stmt = LY_STMT_ANYXML;
c_ext->substmts[12].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[12].storage = &struct_ext->child;
+ c_ext->substmts[12].storage = &struct_data->child;
LY_ARRAY_INCREMENT(c_ext->substmts);
c_ext->substmts[13].stmt = LY_STMT_USES;
c_ext->substmts[13].cardinality = LY_STMT_CARD_ANY;
- c_ext->substmts[13].storage = &struct_ext->child;
+ c_ext->substmts[13].storage = &struct_data->child;
*lysc_ctx_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
- ret = lys_compile_extension_instance(cctx, p_ext, c_ext);
+ rc = lys_compile_extension_instance(cctx, p_ext, c_ext);
*lysc_ctx_get_options(cctx) = prev_options;
- if (ret) {
- return ret;
+ if (rc) {
+ return rc;
+ }
+
+ 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].cardinality = LY_STMT_CARD_OPT;
+ 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].cardinality = LY_STMT_CARD_OPT;
+ 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].cardinality = LY_STMT_CARD_OPT;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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].cardinality = LY_STMT_CARD_ANY;
+ 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;
@@ -210,5 +356,18 @@
.plugin.snode = NULL,
.plugin.validate = NULL
},
+ {
+ .module = "ietf-yang-structure-ext",
+ .revision = "2020-06-17",
+ .name = "augment-structure",
+
+ .plugin.id = "libyang 2 - structure, version 1",
+ .plugin.compile = structure_aug_compile,
+ .plugin.sprinter = structure_schema_printer,
+ .plugin.free = structure_free,
+ .plugin.node = NULL,
+ .plugin.snode = NULL,
+ .plugin.validate = NULL
+ },
{0} /* terminating zeroed record */
};
diff --git a/src/plugins_exts_compile.h b/src/plugins_exts_compile.h
index 5925350..0fbe43b 100644
--- a/src/plugins_exts_compile.h
+++ b/src/plugins_exts_compile.h
@@ -111,7 +111,7 @@
* 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 YANG schema compile context to track the compilation state.
+ * @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.
@@ -123,6 +123,36 @@
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.
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 54428f8..8eb550f 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -507,11 +507,12 @@
* @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_ext_substmt *substmt, struct lysp_stmt *stmt, struct lysc_node *aug_target)
{
LY_ERR rc = LY_SUCCESS;
struct lysf_ctx fctx = {.ctx = ctx->ctx};
@@ -549,8 +550,16 @@
}
*pnodes_p = pnode;
- /* compile, ctx->ext substatement storage is used as the document root */
- LY_CHECK_GOTO(rc = lys_compile_node(ctx, pnode, NULL, flags, NULL), cleanup);
+ 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: {
@@ -700,8 +709,9 @@
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)
+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;
@@ -743,7 +753,7 @@
}
stmt_counter++;
- if ((rc = lys_compile_ext_instance_stmt(ctx, ext_p, ext, &ext->substmts[u], stmt))) {
+ if ((rc = lys_compile_ext_instance_stmt(ctx, ext_p, ext, &ext->substmts[u], stmt, aug_target))) {
goto cleanup;
}
}
@@ -763,6 +773,23 @@
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.
*
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 66d2005..6876ea4 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -38,8 +38,48 @@
#include "tree_schema_internal.h"
#include "xpath.h"
-static const struct lys_module *lys_schema_node_get_module(const struct ly_ctx *ctx, const char *nametest,
- size_t nametest_len, const struct lysp_module *mod, const char **name, size_t *name_len);
+/**
+ * @brief Get module of a single nodeid node name test.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] nametest Nametest with an optional prefix.
+ * @param[in] nametest_len Length of @p nametest.
+ * @param[in] mod Both current and prefix module for resolving prefixes and to return in case of no prefix.
+ * @param[out] name Optional pointer to the name test without the prefix.
+ * @param[out] name_len Length of @p name.
+ * @return Resolved module.
+ */
+static const struct lys_module *
+lys_schema_node_get_module(const struct ly_ctx *ctx, const char *nametest, size_t nametest_len,
+ const struct lysp_module *mod, const char **name, size_t *name_len)
+{
+ const struct lys_module *target_mod;
+ const char *ptr;
+
+ ptr = ly_strnchr(nametest, ':', nametest_len);
+ if (ptr) {
+ target_mod = ly_resolve_prefix(ctx, nametest, ptr - nametest, LY_VALUE_SCHEMA, (void *)mod);
+ if (!target_mod) {
+ LOGVAL(ctx, LYVE_REFERENCE,
+ "Invalid absolute-schema-nodeid nametest \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
+ (int)nametest_len, nametest, (int)(ptr - nametest), nametest, LYSP_MODULE_NAME(mod));
+ return NULL;
+ }
+
+ if (name) {
+ *name = ptr + 1;
+ *name_len = nametest_len - ((ptr - nametest) + 1);
+ }
+ } else {
+ target_mod = mod->mod;
+ if (name) {
+ *name = nametest;
+ *name_len = nametest_len;
+ }
+ }
+
+ return target_mod;
+}
/**
* @brief Check the syntax of a node-id and collect all the referenced modules.
@@ -1375,49 +1415,6 @@
}
/**
- * @brief Get module of a single nodeid node name test.
- *
- * @param[in] ctx libyang context.
- * @param[in] nametest Nametest with an optional prefix.
- * @param[in] nametest_len Length of @p nametest.
- * @param[in] mod Both current and prefix module for resolving prefixes and to return in case of no prefix.
- * @param[out] name Optional pointer to the name test without the prefix.
- * @param[out] name_len Length of @p name.
- * @return Resolved module.
- */
-static const struct lys_module *
-lys_schema_node_get_module(const struct ly_ctx *ctx, const char *nametest, size_t nametest_len,
- const struct lysp_module *mod, const char **name, size_t *name_len)
-{
- const struct lys_module *target_mod;
- const char *ptr;
-
- ptr = ly_strnchr(nametest, ':', nametest_len);
- if (ptr) {
- target_mod = ly_resolve_prefix(ctx, nametest, ptr - nametest, LY_VALUE_SCHEMA, (void *)mod);
- if (!target_mod) {
- LOGVAL(ctx, LYVE_REFERENCE,
- "Invalid absolute-schema-nodeid nametest \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
- (int)nametest_len, nametest, (int)(ptr - nametest), nametest, LYSP_MODULE_NAME(mod));
- return NULL;
- }
-
- if (name) {
- *name = ptr + 1;
- *name_len = nametest_len - ((ptr - nametest) + 1);
- }
- } else {
- target_mod = mod->mod;
- if (name) {
- *name = nametest;
- *name_len = nametest_len;
- }
- }
-
- return target_mod;
-}
-
-/**
* @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.
@@ -1732,19 +1729,8 @@
return ret;
}
-/**
- * @brief Compile augment children.
- *
- * @param[in] ctx Compile context.
- * @param[in] aug_p Parsed augment to compile.
- * @param[in] child First augment child to compile.
- * @param[in] target Target node of the augment.
- * @param[in] child_unres_disabled Whether the children are to be put into unres disabled set or not.
- * @return LY_SUCCESS on success.
- * @return LY_EVALID on failure.
- */
-static LY_ERR
-lys_compile_augment_children(struct lysc_ctx *ctx, struct lysp_node_augment *aug_p, struct lysp_node *child,
+LY_ERR
+lys_compile_augment_children(struct lysc_ctx *ctx, struct lysp_when *aug_when, uint16_t aug_flags, struct lysp_node *child,
struct lysc_node *target, ly_bool child_unres_disabled)
{
LY_ERR rc = LY_SUCCESS;
@@ -1759,7 +1745,7 @@
* - new cases augmenting some choice can have mandatory nodes
* - mandatory nodes are allowed only in case the augmentation is made conditional with a when statement
*/
- if (aug_p->when || (target->nodetype == LYS_CHOICE) || (ctx->cur_mod == target->module)) {
+ if (aug_when || (target->nodetype == LYS_CHOICE) || (ctx->cur_mod == target->module)) {
allow_mand = 1;
}
@@ -1809,9 +1795,9 @@
goto cleanup;
}
- if (aug_p->when) {
+ if (aug_when) {
/* pass augment's when to all the children */
- rc = lys_compile_when(ctx, aug_p->when, aug_p->flags, target, lysc_data_node(target), node, &when_shared);
+ rc = lys_compile_when(ctx, aug_when, aug_flags, target, lysc_data_node(target), node, &when_shared);
LY_CHECK_GOTO(rc, cleanup);
}
@@ -1878,14 +1864,17 @@
}
/* augment children */
- LY_CHECK_GOTO(rc = lys_compile_augment_children(ctx, aug_p, aug_p->child, target, child_unres_disabled), cleanup);
+ rc = lys_compile_augment_children(ctx, aug_p->when, aug_p->flags, aug_p->child, target, child_unres_disabled);
+ LY_CHECK_GOTO(rc, cleanup);
/* augment actions */
- rc = lys_compile_augment_children(ctx, aug_p, (struct lysp_node *)aug_p->actions, target, child_unres_disabled);
+ rc = lys_compile_augment_children(ctx, aug_p->when, aug_p->flags, (struct lysp_node *)aug_p->actions, target,
+ child_unres_disabled);
LY_CHECK_GOTO(rc, cleanup);
/* augment notifications */
- rc = lys_compile_augment_children(ctx, aug_p, (struct lysp_node *)aug_p->notifs, target, child_unres_disabled);
+ rc = lys_compile_augment_children(ctx, aug_p->when, aug_p->flags, (struct lysp_node *)aug_p->notifs, target,
+ child_unres_disabled);
LY_CHECK_GOTO(rc, cleanup);
cleanup:
@@ -2379,3 +2368,73 @@
}
}
}
+
+LIBYANG_API_DEF 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)
+{
+ LY_ERR rc;
+ LY_ARRAY_COUNT_TYPE u;
+ struct lys_module *target_mod;
+ struct lysc_ext_instance *target_ext = NULL, *prev_ext;
+ const struct lysc_node *target;
+ const char *id, *id2, *name;
+ size_t name_len;
+ uint16_t flag;
+
+ LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, path, aug_target, LY_EINVAL);
+
+ /* skip first slash */
+ id = path;
+ if (id[0] != '/') {
+ LOGVAL(ctx->ctx, LYVE_SYNTAX, "Invalid absolute-schema-nodeid \"%s\".", path);
+ return LY_EVALID;
+ }
+ ++id;
+
+ /* find the next slash */
+ id2 = strchr(id, '/');
+ if (!id2) {
+ LOGVAL(ctx->ctx, LYVE_SYNTAX, "Invalid absolute-schema-nodeid \"%s\".", path);
+ return LY_EVALID;
+ }
+
+ /* find the target module */
+ target_mod = (struct lys_module *)lys_schema_node_get_module(ctx->ctx, id, id2 - id, ctx->pmod, &name, &name_len);
+ if (!target_mod) {
+ return LY_ENOTFOUND;
+ } else if (!target_mod->implemented) {
+ LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Augment target extension instance \"%*.s\" in a non-implemented module \"%s\".",
+ (int)name_len, name, target_mod->name);
+ return LY_ENOTFOUND;
+ }
+
+ /* find the extension instance */
+ LY_ARRAY_FOR(target_mod->compiled->exts, u) {
+ if (!ly_strncmp(target_mod->compiled->exts[u].argument, name, name_len)) {
+ target_ext = &target_mod->compiled->exts[u];
+ break;
+ }
+ }
+ if (!target_ext) {
+ LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Augment target extension instance \"%*.s\" not found in module \"%s\".",
+ (int)name_len, name, target_mod->name);
+ return LY_ENOTFOUND;
+ }
+
+ /* find the augment target with the correct compile context */
+ prev_ext = ctx->ext;
+ ctx->ext = target_ext;
+ rc = lysc_resolve_schema_nodeid(ctx, id2, strlen(id2), NULL, LY_VALUE_SCHEMA, ctx->pmod, 0, &target, &flag);
+ ctx->ext = prev_ext;
+ LY_CHECK_RET(rc);
+
+ /* add this module into the target module augmented_by, if not there */
+ lys_array_add_mod_ref(ctx, ctx->cur_mod, &target_mod->augmented_by);
+
+ if (aug_ext) {
+ *aug_ext = target_ext;
+ }
+ *aug_target = (struct lysc_node *)target;
+ return LY_SUCCESS;
+}
diff --git a/src/schema_compile_amend.h b/src/schema_compile_amend.h
index 581dfae..1e47c61 100644
--- a/src/schema_compile_amend.h
+++ b/src/schema_compile_amend.h
@@ -1,9 +1,10 @@
/**
* @file schema_compile_amend.h
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief Header for schema compilation of augments, deviations, and refines.
*
- * Copyright (c) 2015 - 2020 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.
@@ -15,6 +16,8 @@
#ifndef LY_SCHEMA_COMPILE_AMEND_H_
#define LY_SCHEMA_COMPILE_AMEND_H_
+#include <stddef.h>
+
#include "log.h"
struct ly_ctx;
@@ -23,6 +26,7 @@
struct lysc_node;
struct lysc_ctx;
struct lysp_node_uses;
+struct lysp_when;
struct lys_glob_unres;
struct lys_module;
@@ -131,6 +135,21 @@
const struct lysc_node *parent, struct lysp_node **dev_pnode, ly_bool *not_supported);
/**
+ * @brief Compile augment children.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] aug_when Parsed augment when to inherit.
+ * @param[in] aug_flags Parsed augment flags.
+ * @param[in] child First augment child to compile.
+ * @param[in] target Target node of the augment.
+ * @param[in] child_unres_disabled Whether the children are to be put into unres disabled set or not.
+ * @return LY_SUCCESS on success.
+ * @return LY_EVALID on failure.
+ */
+LY_ERR lys_compile_augment_children(struct lysc_ctx *ctx, struct lysp_when *aug_when, uint16_t aug_flags,
+ struct lysp_node *child, struct lysc_node *target, ly_bool child_unres_disabled);
+
+/**
* @brief Compile and apply any precompiled top-level or uses augments targeting a node.
*
* @param[in] ctx Compile context.
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 9263c95..10bcd22 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -1,9 +1,10 @@
/**
* @file schema_compile_node.c
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief Schema compilation of common nodes.
*
- * Copyright (c) 2015 - 2020 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.
@@ -2985,25 +2986,7 @@
return ret;
}
-/**
- * @brief Find the node according to the given descendant/absolute schema nodeid.
- * Used in unique, refine and augment statements.
- *
- * @param[in] ctx Compile context
- * @param[in] nodeid Descendant-schema-nodeid (according to the YANG grammar)
- * @param[in] nodeid_len Length of the given nodeid, if it is not NULL-terminated string.
- * @param[in] ctx_node Context node for a relative nodeid.
- * @param[in] format Format of any prefixes.
- * @param[in] prefix_data Format-specific prefix data (see ::ly_resolve_prefix).
- * @param[in] nodetype Optional (can be 0) restriction for target's nodetype. If target exists, but does not match
- * the given nodetype, LY_EDENIED is returned (and target is provided), but no error message is printed.
- * The value can be even an ORed value to allow multiple nodetypes.
- * @param[out] target Found target node if any.
- * @param[out] result_flag Output parameter to announce if the schema nodeid goes through the action's input/output or a Notification.
- * The LYSC_OPT_RPC_INPUT, LYSC_OPT_RPC_OUTPUT and LYSC_OPT_NOTIFICATION are used as flags.
- * @return LY_ERR values - LY_ENOTFOUND, LY_EVALID, LY_EDENIED or LY_SUCCESS.
- */
-static LY_ERR
+LY_ERR
lysc_resolve_schema_nodeid(struct lysc_ctx *ctx, const char *nodeid, size_t nodeid_len, const struct lysc_node *ctx_node,
LY_VALUE_FORMAT format, void *prefix_data, uint16_t nodetype, const struct lysc_node **target, uint16_t *result_flag)
{
@@ -3096,6 +3079,9 @@
/* only input or output is valid */
ctx_node = NULL;
}
+ } else if (ctx->ext && !ctx_node) {
+ /* top-level extension nodes */
+ ctx_node = lysc_ext_find_node(ctx->ext, mod, name, name_len, 0, LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE);
} else {
ctx_node = lys_find_child(ctx_node, mod, name, name_len, 0,
getnext_extra_flag | LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE);
diff --git a/src/schema_compile_node.h b/src/schema_compile_node.h
index 3b1eb6b..d1f050d 100644
--- a/src/schema_compile_node.h
+++ b/src/schema_compile_node.h
@@ -95,6 +95,27 @@
struct lysp_qname **dflt);
/**
+ * @brief Find the node according to the given descendant/absolute schema nodeid.
+ * Used in unique, refine and augment statements.
+ *
+ * @param[in] ctx Compile context
+ * @param[in] nodeid Descendant-schema-nodeid (according to the YANG grammar)
+ * @param[in] nodeid_len Length of the given nodeid, if it is not NULL-terminated string.
+ * @param[in] ctx_node Context node for a relative nodeid.
+ * @param[in] format Format of any prefixes.
+ * @param[in] prefix_data Format-specific prefix data (see ::ly_resolve_prefix).
+ * @param[in] nodetype Optional (can be 0) restriction for target's nodetype. If target exists, but does not match
+ * the given nodetype, LY_EDENIED is returned (and target is provided), but no error message is printed.
+ * The value can be even an ORed value to allow multiple nodetypes.
+ * @param[out] target Found target node if any.
+ * @param[out] result_flag Output parameter to announce if the schema nodeid goes through the action's input/output or a Notification.
+ * The LYSC_OPT_RPC_INPUT, LYSC_OPT_RPC_OUTPUT and LYSC_OPT_NOTIFICATION are used as flags.
+ * @return LY_ERR values - LY_ENOTFOUND, LY_EVALID, LY_EDENIED or LY_SUCCESS.
+ */
+LY_ERR lysc_resolve_schema_nodeid(struct lysc_ctx *ctx, const char *nodeid, size_t nodeid_len, const struct lysc_node *ctx_node,
+ LY_VALUE_FORMAT format, void *prefix_data, uint16_t nodetype, const struct lysc_node **target, uint16_t *result_flag);
+
+/**
* @brief Compile choice children.
*
* @param[in] ctx Compile context
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 892bb81..c6d9eec 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -515,7 +515,7 @@
struct lysp_stmt {
const char *stmt; /**< identifier of the statement */
const char *arg; /**< statement's argument */
- LY_VALUE_FORMAT format; /**< prefix format of the identifier/argument (::LY_VALUE_XML is YIN format) */
+ LY_VALUE_FORMAT format; /**< prefix format of the identifier/argument (::LY_VALUE_XML is YIN format) */
void *prefix_data; /**< Format-specific data for prefix resolution (see ly_resolve_prefix()) */
struct lysp_stmt *next; /**< link to the next statement */
@@ -775,56 +775,57 @@
* 1 - container 6 - anydata/anyxml 11 - output 16 - grouping 21 - enum
* 2 - choice 7 - case 12 - feature 17 - uses 22 - type
* 3 - leaf 8 - notification 13 - identity 18 - refine 23 - stmt
- * 4 - leaflist 9 - rpc 14 - extension 19 - augment
+ * 4 - leaflist 9 - rpc 14 - extension 19 - augment 24 - extension instance
* 5 - list 10 - input 15 - typedef 20 - deviate
*
* 1 1 1 1 1 1 1 1 1 1 2 2 2 2
* bit name 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
- * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 1 LYS_CONFIG_W |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | |
- * LYS_SET_BASE | | | | | | | | | | | | | | | | | | | | | |x| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 2 LYS_CONFIG_R |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | |
- * LYS_SET_BIT | | | | | | | | | | | | | | | | | | | | | |x| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 3 LYS_STATUS_CURR |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | |
- * LYS_SET_ENUM | | | | | | | | | | | | | | | | | | | | | |x| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 4 LYS_STATUS_DEPRC |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | |
- * LYS_SET_FRDIGITS | | | | | | | | | | | | | | | | | | | | | |x| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 5 LYS_STATUS_OBSLT |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | |
- * LYS_SET_LENGTH | | | | | | | | | | | | | | | | | | | | | |x| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 6 LYS_MAND_TRUE | |x|x| | |x| | | | | | | | | | | |x| |x| | | |
- * LYS_SET_PATH | | | | | | | | | | | | | | | | | | | | | |x| |
- * LYS_FENABLED | | | | | | | | | | | |x| | | | | | | | | | | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 7 LYS_MAND_FALSE | |x|x| | |x| | | | | | | | | | | |x| |x| | | |
- * LYS_ORDBY_USER | | | |x|x| | | | | | | | | | | | | | | | | | |
- * LYS_SET_PATTERN | | | | | | | | | | | | | | | | | | | | | |x| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 8 LYS_ORDBY_SYSTEM | | | |x|x| | | | | | | | | | | | | | | | | | |
- * LYS_YINELEM_TRUE | | | | | | | | | | | | | |x| | | | | | | | | |
- * LYS_SET_RANGE | | | | | | | | | | | | | | | | | | | | | |x| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 9 LYS_YINELEM_FALSE| | | | | | | | | | | | | |x| | | | | | | | | |
- * LYS_SET_TYPE | | | | | | | | | | | | | | | | | | | | | |x| |
- * LYS_SINGLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 10 LYS_SET_VALUE | | | | | | | | | | | | | | | | | | | | |x| | |
- * LYS_SET_REQINST | | | | | | | | | | | | | | | | | | | | | |x| |
- * LYS_SET_MIN | | | |x|x| | | | | | | | | | | | |x| |x| | | |
- * LYS_DOUBLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 11 LYS_SET_MAX | | | |x|x| | | | | | | | | | | | |x| |x| | | |
- * LYS_USED_GRP | | | | | | | | | | | | | | | |x| | | | | | | |
- * LYS_YIN_ATTR | | | | | | | | | | | | | | | | | | | | | | |x|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 12 LYS_YIN_ARGUMENT | | | | | | | | | | | | | | | | | | | | | | |x|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * 13 LYS_INTERNAL |x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
- * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 1 LYS_CONFIG_W |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | | |
+ * LYS_SET_BASE | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 2 LYS_CONFIG_R |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | | |
+ * LYS_SET_BIT | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 3 LYS_STATUS_CURR |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | | |
+ * LYS_SET_ENUM | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 4 LYS_STATUS_DEPRC |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | | |
+ * LYS_SET_FRDIGITS | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 5 LYS_STATUS_OBSLT |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | | |
+ * LYS_SET_LENGTH | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 6 LYS_MAND_TRUE | |x|x| | |x| | | | | | | | | | | |x| |x| | | | |
+ * LYS_SET_PATH | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * LYS_FENABLED | | | | | | | | | | | |x| | | | | | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 7 LYS_MAND_FALSE | |x|x| | |x| | | | | | | | | | | |x| |x| | | | |
+ * LYS_ORDBY_USER | | | |x|x| | | | | | | | | | | | | | | | | | | |
+ * LYS_SET_PATTERN | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 8 LYS_ORDBY_SYSTEM | | | |x|x| | | | | | | | | | | | | | | | | | | |
+ * LYS_YINELEM_TRUE | | | | | | | | | | | | | |x| | | | | | | | | | |
+ * LYS_SET_RANGE | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 9 LYS_YINELEM_FALSE| | | | | | | | | | | | | |x| | | | | | | | | | |
+ * LYS_SET_TYPE | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * LYS_SINGLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x| |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 10 LYS_SET_VALUE | | | | | | | | | | | | | | | | | | | | |x| | | |
+ * LYS_SET_REQINST | | | | | | | | | | | | | | | | | | | | | |x| | |
+ * LYS_SET_MIN | | | |x|x| | | | | | | | | | | | |x| |x| | | | |
+ * LYS_DOUBLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x| |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 11 LYS_SET_MAX | | | |x|x| | | | | | | | | | | | |x| |x| | | | |
+ * LYS_USED_GRP | | | | | | | | | | | | | | | |x| | | | | | | | |
+ * LYS_YIN_ATTR | | | | | | | | | | | | | | | | | | | | | | |x| |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 12 LYS_YIN_ARGUMENT | | | | | | | | | | | | | | | | | | | | | | |x| |
+ * LYS_EXT_PARSED_AUGMENT | | | | | | | | | | | | | | | | | | | | | | | |x|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 13 LYS_INTERNAL |x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
+ * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
@@ -951,6 +952,7 @@
#define LYS_YIN_ATTR 0x0400 /**< flag to identify YIN attribute parsed as extension's substatement, only when the source is YIN */
#define LYS_YIN_ARGUMENT 0x0800 /**< flag to identify statement representing extension's argument, only when the source is YIN */
+#define LYS_EXT_PARSED_AUGMENT 0x0800 /**< flag to mark an extension instance whose parsed nodes are augment nodes */
#define LYS_INTERNAL 0x1000 /**< flag to identify internal parsed statements that should not be printed */