yin parser CHANGE add support for ordered-by element
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 3c3361b..4dc25e0 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -874,7 +874,7 @@
* @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
* @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] max Value to write to.
- * @param[in,out] flags Flags to write to.
+ * @param[in] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
@@ -924,7 +924,7 @@
* @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
* @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] min Value to write to.
- * @param[in,out] flags Flags to write to.
+ * @param[in] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
@@ -941,7 +941,7 @@
};
*flags |= LYS_SET_MIN;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, YANG_MAX_ELEMENTS));
+ LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, YANG_MIN_ELEMENTS));
if (!temp_val || temp_val[0] == '\0' || (temp_val[0] == '0' && temp_val[1] != '\0')) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL, strlen(temp_val), temp_val, "min-elements");
@@ -963,9 +963,21 @@
}
*min = num;
FREE_STRING(ctx->xml_ctx.ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, YANG_MAX_ELEMENTS, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, data, YANG_MIN_ELEMENTS, NULL, exts);
}
+/**
+ * @brief Parse min-elements or max-elements element.
+ *
+ * @param[in,out] ctx YIN parser context for logging and to store current state.
+ * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
+ * @param[in,out] data Data to read from, always moved to currently handled character.
+ * @param[in] parent Identification of parent element.
+ * @param[in] current Identification 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 yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
enum yang_keyword parent, enum yang_keyword current, void *dest)
@@ -1000,6 +1012,41 @@
}
/**
+ * @brief Parser ordered-by element.
+ *
+ * @param[in,out] ctx YIN parser context for logging and to store current state.
+ * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
+ * @param[in,out] data Data to read from, always moved to currently handled character.
+ * @param[out] flags Flags to write to.
+ * @param[in,out] exts Extension instance to add to.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+yin_parse_orderedby(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
+ uint16_t *flags, struct lysp_ext_instance **exts)
+{
+ const char *temp_val;
+ struct yin_subelement subelems[1] = {
+ {YANG_CUSTOM, NULL, 0},
+ };
+
+ LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, YANG_ORDERED_BY));
+ if (strcmp(temp_val, "system") == 0) {
+ *flags |= LYS_ORDBY_SYSTEM;
+ } else if (strcmp(temp_val, "user") == 0) {
+ *flags |= LYS_ORDBY_USER;
+ } else {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL, strlen(temp_val), temp_val, "ordered-by");
+ FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ return LY_EVALID;
+ }
+ FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+
+ return yin_parse_content(ctx, subelems, 1, data, YANG_ORDERED_BY, NULL, exts);
+}
+
+/**
* @brief Map keyword type to substatement info.
*
* @param[in] kw Keyword type.
@@ -1284,6 +1331,7 @@
case YANG_NOTIFICATION:
break;
case YANG_ORDERED_BY:
+ ret = yin_parse_orderedby(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
break;
case YANG_OUTPUT:
break;
diff --git a/tests/src/test_parser_yin.c b/tests/src/test_parser_yin.c
index 59d1cd9..8bfd09b 100644
--- a/tests/src/test_parser_yin.c
+++ b/tests/src/test_parser_yin.c
@@ -1820,6 +1820,28 @@
st->finished_correctly = true;
}
+static void
+test_ordby_elem(void **state)
+{
+ struct state *st = *state;
+ const char *data;
+ uint16_t flags = 0;
+
+ data = ELEMENT_WRAPPER_START "<ordered-by value=\"system\"/>" ELEMENT_WRAPPER_END;
+ assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
+ assert_true(flags | LYS_ORDBY_SYSTEM);
+
+ data = ELEMENT_WRAPPER_START "<ordered-by value=\"user\"/>" ELEMENT_WRAPPER_END;
+ assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
+ assert_true(flags | LYS_ORDBY_USER);
+
+ data = ELEMENT_WRAPPER_START "<ordered-by value=\"inv\"/>" ELEMENT_WRAPPER_END;
+ assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, false), LY_EVALID);
+ logbuf_assert("Invalid value \"inv\" of \"ordered-by\". Line number 1.");
+
+ st->finished_correctly = true;
+}
+
int
main(void)
{
@@ -1867,6 +1889,7 @@
cmocka_unit_test_setup_teardown(test_type_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_max_elems_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_min_elems_elem, setup_element_test, teardown_element_test),
+ cmocka_unit_test_setup_teardown(test_ordby_elem, setup_element_test, teardown_element_test),
};
return cmocka_run_group_tests(tests, setup_ly_ctx, destroy_ly_ctx);