YIN parser CHANGE remove unnecessary optimization complicating code maintenance
List of substatements is usually quite short and searching lineary is
not a big problem instead of binary search. However, maintenance of ordering
of the statements definition became challenging since the statements order is
also used for proper order of extension substatements compilation (there can be
dependencies between various statements (e.g. type needs status or
units).
So the binary search was replaced by linear search.
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 1c2a9a8..4c3aa83 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -372,7 +372,7 @@
}
/**
- * @brief Get record with given type. Array must be sorted in ascending order by array[n].type.
+ * @brief Get record with given type.
*
* @param[in] type Type of wanted record.
* @param[in] array_size Size of array.
@@ -381,24 +381,13 @@
* @return Pointer to desired record on success, NULL if element is not in the array.
*/
static struct yin_subelement *
-get_record(enum ly_stmt type, signed char array_size, struct yin_subelement *array)
+get_record(enum ly_stmt type, size_t array_size, struct yin_subelement *array)
{
- signed char left = 0, right = array_size - 1, middle;
-
- while (left <= right) {
- middle = left + (right - left) / 2;
-
- if (array[middle].type == type) {
- return &array[middle];
- }
-
- if (array[middle].type < type) {
- left = middle + 1;
- } else {
- right = middle - 1;
+ for (unsigned int u = 0; u < array_size; ++u) {
+ if (array[u].type == type) {
+ return &array[u];
}
}
-
return NULL;
}
@@ -418,7 +407,7 @@
{
for (signed char i = 0; i < subelem_info_size; ++i) {
/* 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)) {
+ if ((subelem_info[i].flags & YIN_SUBELEM_MANDATORY) && !(subelem_info[i].flags & YIN_SUBELEM_PARSED)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_MAND_SUBELEM,
ly_stmt2str(subelem_info[i].type), ly_stmt2str(current_element));
return LY_EVALID;
@@ -456,31 +445,6 @@
}
/**
- * @brief Helper function to check if array of information about subelements is in ascending order.
- *
- * @param[in] subelem_info Array of information about subelements.
- * @param[in] subelem_info_size Size of subelem_info array.
- *
- * @return True iff subelem_info array is in ascending order, False otherwise.
- */
-#ifndef NDEBUG
-static bool
-is_ordered(struct yin_subelement *subelem_info, signed char subelem_info_size)
-{
- enum ly_stmt current = LY_STMT_NONE; /* 0 (minimal value) */
-
- for (signed char i = 0; i < subelem_info_size; ++i) {
- if (subelem_info[i].type <= current) {
- return false;
- }
- current = subelem_info[i].type;
- }
-
- return true;
-}
-#endif
-
-/**
* @brief Parse simple element without any special constraints and argument mapped to yin attribute,
* for example prefix or namespace element.
*
@@ -2882,7 +2846,7 @@
}
LY_ERR
-yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, signed char subelem_info_size,
+yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
const char **data, enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -2894,8 +2858,6 @@
enum ly_stmt kw = LY_STMT_NONE, last_kw = LY_STMT_NONE;
struct yin_subelement *subelem = NULL;
- assert(is_ordered(subelem_info, subelem_info_size));
-
if (ctx->xml_ctx.status == LYXML_ELEM_CONTENT) {
ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
/* current element has subelements as content */
@@ -3434,6 +3396,7 @@
*yin_ctx = calloc(1, sizeof **yin_ctx);
LY_CHECK_ERR_RET(!(*yin_ctx), LOGMEM(ctx), LY_EMEM);
(*yin_ctx)->xml_ctx.ctx = ctx;
+ (*yin_ctx)->pos_type = LY_VLOG_LINE;
(*yin_ctx)->xml_ctx.line = 1;
/* map the typedefs and groupings list from main context to the submodule's context */
diff --git a/src/parser_yin.h b/src/parser_yin.h
index 1f26eb5..b4133af 100644
--- a/src/parser_yin.h
+++ b/src/parser_yin.h
@@ -176,8 +176,7 @@
* @brief Generic function for content parsing
*
* @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,
- * array must be ordered by subelem_info->type in ascending order.
+ * @param[in] subelem_info array of valid subelement types and meta information
* @param[in] subelem_info_size Size of subelem_info array.
* @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] current_element Type of current element.
@@ -186,7 +185,7 @@
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, signed char subelem_info_size,
+LY_ERR yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
const char **data, enum ly_stmt current_element, const char **text_content,
struct lysp_ext_instance **exts);