yin parser CHANGE check relative order of module and submodule subelements
diff --git a/src/common.h b/src/common.h
index 7b81b1c..c51d862 100644
--- a/src/common.h
+++ b/src/common.h
@@ -200,6 +200,7 @@
#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_INDEV_YIN LYVE_SYNTAX_YIN, "Deviate of this type doesn't allow \"%s\" as it's sub-element."
+#define LY_VCODE_INORDER_YIN LYVE_SYNTAX_YIN, "Invalid order of %s\'s subelements \"%s\" can't appear after \"%s\"."
#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\'."
@@ -620,6 +621,4 @@
LY_CHECK_ERR_RET(!(NEW_ITEM), LOGMEM(CTX), LY_EMEM); \
LY_LIST_INSERT(LIST, NEW_ITEM, LINKER)
-#define LY_LIST_NEW_GOTO(CTX, LIST, NEW_ITEM, LINKER, GOTO) \
-
-#endif /* LY_COMMON_H_ */
\ No newline at end of file
+#endif /* LY_COMMON_H_ */
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 30c4e84..647a6f5 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -85,8 +85,6 @@
} else {
if (strncmp(start, "text", name_len) == 0) {
return YIN_TEXT;
- } else if (strncmp(start, "value", name_len) == 0) {
- return YIN_VALUE;
} else {
return YANG_NONE;
}
@@ -2522,6 +2520,80 @@
}
}
+static LY_ERR
+kw2kw_group(struct yin_parser_ctx *ctx, enum yang_keyword kw, enum yang_module_stmt *group)
+{
+ switch (kw) {
+ /* module header */
+ case YANG_NONE:
+ case YANG_NAMESPACE:
+ case YANG_PREFIX:
+ case YANG_BELONGS_TO:
+ case YANG_YANG_VERSION:
+ *group = Y_MOD_MODULE_HEADER;
+ break;
+ /* linkage */
+ case YANG_INCLUDE:
+ case YANG_IMPORT:
+ *group = Y_MOD_LINKAGE;
+ break;
+ /* meta */
+ case YANG_ORGANIZATION:
+ case YANG_CONTACT:
+ case YANG_DESCRIPTION:
+ case YANG_REFERENCE:
+ *group = Y_MOD_META;
+ break;
+ /* revision */
+ case YANG_REVISION:
+ *group = Y_MOD_REVISION;
+ break;
+ /* body */
+ case YANG_ANYDATA:
+ case YANG_ANYXML:
+ case YANG_AUGMENT:
+ case YANG_CHOICE:
+ case YANG_CONTAINER:
+ case YANG_DEVIATION:
+ case YANG_EXTENSION:
+ case YANG_FEATURE:
+ case YANG_GROUPING:
+ case YANG_IDENTITY:
+ case YANG_LEAF:
+ case YANG_LEAF_LIST:
+ case YANG_LIST:
+ case YANG_NOTIFICATION:
+ case YANG_RPC:
+ case YANG_TYPEDEF:
+ case YANG_USES:
+ case YANG_CUSTOM:
+ *group = Y_MOD_BODY;
+ break;
+ default:
+ LOGINT(ctx->xml_ctx.ctx);
+ return LY_EINT;
+ }
+
+ return LY_SUCCESS;
+}
+
+static LY_ERR
+yin_check_relative_order(struct yin_parser_ctx *ctx, enum yang_keyword kw, enum yang_keyword next_kw, enum yang_keyword parrent)
+{
+ assert(parrent == YANG_MODULE || parrent == YANG_SUBMODULE);
+ enum yang_module_stmt gr, next_gr;
+
+ LY_CHECK_RET(kw2kw_group(ctx, kw, &gr));
+ LY_CHECK_RET(kw2kw_group(ctx, next_kw, &next_gr));
+
+ if (gr > next_gr) {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INORDER_YIN, ly_stmt2str(parrent), ly_stmt2str(next_kw), ly_stmt2str(kw));
+ return LY_EVALID;
+ }
+
+ return LY_SUCCESS;
+}
+
LY_ERR
yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, signed char subelem_info_size,
const char **data, enum yang_keyword current_element, const char **text_content, struct lysp_ext_instance **exts)
@@ -2532,7 +2604,7 @@
size_t out_len = 0;
int dynamic = 0;
struct yin_arg_record *attrs = NULL;
- enum yang_keyword kw = YANG_NONE;
+ enum yang_keyword kw = YANG_NONE, last_kw = YANG_NONE;
struct yin_subelement *subelem = NULL;
struct lysp_type *type, *nested_type;
@@ -2551,6 +2623,7 @@
}
ret = yin_load_attributes(ctx, data, &attrs);
LY_CHECK_GOTO(ret, cleanup);
+ last_kw = kw;
kw = yin_match_keyword(ctx, name.value, name.len, prefix.value, prefix.len, current_element);
/* check if this element can be child of current element */
@@ -2565,7 +2638,10 @@
goto cleanup;
}
- /* TODO check relative order */
+ if (current_element == YANG_MODULE || current_element == YANG_SUBMODULE) {
+ ret = yin_check_relative_order(ctx, last_kw, kw, current_element);
+ LY_CHECK_GOTO(ret, cleanup);
+ }
/* flag check */
if ((subelem->flags & YIN_SUBELEM_UNIQUE) && (subelem->flags & YIN_SUBELEM_PARSED)) {