yin parser CHANGE add support for include element
diff --git a/src/common.h b/src/common.h
index 0bed0ad..f0f70e4 100644
--- a/src/common.h
+++ b/src/common.h
@@ -178,6 +178,7 @@
#define LY_VCODE_EOF LYVE_SYNTAX, "Unexpected end-of-input."
#define LY_VCODE_NTERM LYVE_SYNTAX, "%s not terminated."
#define LY_VCODE_NSUPP LYVE_SYNTAX, "%s not supported."
+
#define LY_VCODE_INSTMT LYVE_SYNTAX_YANG, "Invalid keyword \"%s\"."
#define LY_VCODE_INCHILDSTMT LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s\"."
#define LY_VCODE_INCHILDSTMT2 LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s\" - the statement is allowed only in YANG 1.1 modules."
@@ -191,13 +192,17 @@
#define LY_VCODE_OOB LYVE_SYNTAX_YANG, "Value \"%.*s\" is out of \"%s\" bounds."
#define LY_VCODE_INDEV LYVE_SYNTAX_YANG, "Deviate \"%s\" does not support keyword \"%s\"."
#define LY_VCODE_INREGEXP LYVE_SYNTAX_YANG, "Regular expression \"%s\" is not valid (\"%s\": %s)."
+
+#define LYVCODE_INSUBELEM2 LYVE_SYNTAX_YIN, "Invalid sub-elemnt \"%s\" of \"%s\" element - this sub-element is allowed only in modules with version 1.1 or newer."
#define LY_VCODE_INVAL_YIN LYVE_SYNTAX_YIN, "Invalid value \"%s\" of \"%s\"."
#define LY_VCODE_DUPELEM LYVE_SYNTAX_YIN, "Duplicate element \"%s\"."
#define LY_VCODE_INCHILDSTMT_YIN LYVE_SYNTAX_YIN, "Invalid element \"%.*s\" as a child of \"%.*s\"."
#define LY_VCODE_MISSATTR LYVE_SYNTAX_YIN, "Missing mandatory child element \"%s\" of %s element ."
#define LY_VCODE_UNEXP_SUBELEM LYVE_SYNTAX_YIN, "Unexpected child element \"%.*s\" of %s element."
+
#define LY_VCODE_XP_EOE LYVE_XPATH, "Unterminated string delimited with %c (%.15s)."
#define LY_VCODE_XP_INEXPR LYVE_XPATH, "Invalid character number %u of expression \'%s\'."
+
#define LY_VCODE_DEV_NODETYPE LYVE_REFERENCE, "Invalid deviation of %s node - it is not possible to %s \"%s\" property."
#define LY_VCODE_DEV_NOT_PRESENT LYVE_REFERENCE, "Invalid deviation %s \"%s\" property \"%s\" which is not present."
diff --git a/src/parser_yin.c b/src/parser_yin.c
index bc2d861..5e4d6a4 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -1385,6 +1385,36 @@
return yin_parse_content(ctx, subelems, 3, data, YANG_REVISION, NULL, &rev->exts);
}
+static LY_ERR
+yin_parse_include(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
+ struct include_meta *inc_meta)
+{
+ struct lysp_include *inc;
+
+ /* allocate new include */
+ LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *inc_meta->includes, inc, LY_EMEM);
+
+ /* parse argument */
+ LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_MODULE, &inc->name, Y_IDENTIF_ARG, YANG_INCLUDE));
+
+ /* submodules share the namespace with the module names, so there must not be
+ * a module of the same name in the context, no need for revision matching */
+ if (!strcmp(inc_meta->name, inc->name) || ly_ctx_get_module_latest(ctx->xml_ctx.ctx, inc->name)) {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YANG,
+ "Name collision between module and submodule of name \"%s\".", inc->name);
+ return LY_EVALID;
+ }
+
+ /* parse content */
+ struct yin_subelement subelems[4] = {
+ {YANG_DESCRIPTION, &inc->dsc, YIN_SUBELEM_UNIQUE | YIN_SUBELEM_VER2},
+ {YANG_REFERENCE, &inc->ref, YIN_SUBELEM_UNIQUE | YIN_SUBELEM_VER2},
+ {YANG_REVISION_DATE, &inc->rev, YIN_SUBELEM_UNIQUE},
+ {YANG_CUSTOM, NULL, 0},
+ };
+ return yin_parse_content(ctx, subelems, 4, data, YANG_INCLUDE, NULL, &inc->exts);
+}
+
/**
* @brief Map keyword type to substatement info.
*
@@ -1530,6 +1560,7 @@
/* TODO check relative order */
+ /* check flags */
/* if element is unique and already defined log error */
if ((subelem->flags & YIN_SUBELEM_UNIQUE) && (subelem->flags & YIN_SUBELEM_PARSED)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Redefinition of %s element in %s element.", ly_stmt2str(kw), ly_stmt2str(current_element));
@@ -1539,6 +1570,12 @@
ret = yin_check_subelem_first_constraint(ctx, subelem_info, subelem_info_size, current_element, subelem);
LY_CHECK_GOTO(ret, cleanup);
}
+ if (subelem->flags & YIN_SUBELEM_VER2) {
+ if (ctx->mod_version < 2) {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVCODE_INSUBELEM2, ly_stmt2str(kw), ly_stmt2str(current_element));
+ return LY_EVALID;
+ }
+ }
subelem->flags |= YIN_SUBELEM_PARSED;
switch (kw) {
@@ -1635,6 +1672,7 @@
ret = yin_parse_import(ctx, attrs, data, (struct lysp_module *)subelem->dest);
break;
case YANG_INCLUDE:
+ ret = yin_parse_include(ctx, attrs, data, (struct include_meta *)subelem->dest);
break;
case YANG_INPUT:
break;
diff --git a/src/parser_yin.h b/src/parser_yin.h
index 6f892a5..2fcae20 100644
--- a/src/parser_yin.h
+++ b/src/parser_yin.h
@@ -67,6 +67,7 @@
#define YIN_SUBELEM_MANDATORY 0x01 /**< is set when subelement is mandatory */
#define YIN_SUBELEM_UNIQUE 0x02 /**< is set when subelement is unique */
#define YIN_SUBELEM_FIRST 0x04 /**< is set when subelement is actually yang argument mapped to yin element */
+#define YIN_SUBELEM_VER2 0x08 /**< subelemnt is allowed only in modules with version at least 2 (YANG 1.1) */
#define YIN_SUBELEM_PARSED 0x80 /**< is set during parsing when given subelement is encountered for the first
time to simply check validity of given constraints */
@@ -102,11 +103,18 @@
struct lysp_tpdf **typedefs; /**< [Sized array](@ref sizedarrays) of typedefs to add to */
};
+/* Meta information passed to yin_parse_augment function */
struct augment_meta {
struct lysp_node *parent; /**< parent node */
struct lysp_augment **augments; /**< [Sized array](@ref sizedarrays) of augments to add to */
};
+/* Meta information passed to yin_parse_include function */
+struct include_meta {
+ const char *name; /**< module/submodule name */
+ struct lysp_include **includes; /**< [Sized array](@ref sizedarrays) of parsed includes to add to */
+};
+
/**
* @brief Match argument name.
*
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 8ad404f..e3fd817 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -64,7 +64,7 @@
FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
}
-static void
+void
lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
{
if (include->submodule) {