yin parser CHANGE cleanup function for content parsing
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 38ffbb1..8e2dbfc 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -510,6 +510,28 @@
}
/**
+ * @brief Parse path 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] kw Type of current element.
+ * @param[out] type Type structure to store parsed value, flags and extension instances.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+yin_parse_path(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum yang_keyword kw,
+ struct lysp_type *type)
+{
+ LY_CHECK_RET(yin_parse_simple_element(ctx, attrs, data, kw, &type->path,
+ YIN_ARG_VALUE, Y_STR_ARG, &type->exts));
+ type->flags |= LYS_SET_PATH;
+
+ return LY_SUCCESS;
+}
+
+/**
* @brief Parse pattern element.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
@@ -698,6 +720,69 @@
}
/**
+ * @brief Parse simple element without any special constraints and argument mapped to yin attribute.
+ *
+ * @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] kw Type of current element.
+ * @param[out] values Parsed values to add to.
+ * @param[in] arg_type Expected type of attribute.
+ * @param[in] arg_val_type Type of expected value of attribute.
+ * @param[in,out] exts Extension instance to add to.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+yin_parse_simple_elem(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum yang_keyword kw,
+ struct yin_subelement *subinfo, enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
+{
+ if (subinfo->flags & YIN_SUBELEM_UNIQUE) {
+ LY_CHECK_RET(yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subinfo->dest,
+ arg_type, arg_val_type, exts));
+ } else {
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, attrs, data, kw, (const char ***)subinfo->dest,
+ arg_type, arg_val_type, exts));
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse base 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[out] dest Where parsed values should be stored.
+ * @param[in,out] exts Extension instance to add to.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+yin_parse_base(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum yang_keyword parent,
+ void *dest, struct lysp_ext_instance **exts)
+{
+ struct lysp_type *type = NULL;
+
+ if (parent == YANG_TYPE) {
+ type = (struct lysp_type *)dest;
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, attrs, data, YANG_BASE, &type->bases, YIN_ARG_NAME,
+ Y_PREF_IDENTIF_ARG, exts));
+ type->flags |= LYS_SET_BASE;
+ } else if (parent == YANG_IDENTITY) {
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, attrs, data, YANG_BASE, (const char ***)dest,
+ YIN_ARG_NAME, Y_PREF_IDENTIF_ARG, exts));
+ } else {
+ LOGINT(ctx->xml_ctx.ctx);
+ return LY_EINT;
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
* @brief Parse require instance element.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
@@ -780,7 +865,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] restr_kw Identificaton of element that is being parsed, can be set to YANG_MUST, YANG_LENGTH or YANG_RANGE.
- * @param[in]
+ * @param[in] restr Value to write to.
*/
static LY_ERR
yin_parse_restriction(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
@@ -802,6 +887,50 @@
}
/**
+ * @brief Parse range 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] type Type structure to store parsed value and flags.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+yin_parse_range(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs,
+ const char **data, struct lysp_type *type)
+{
+ type->range = calloc(1, sizeof *type->range);
+ LY_CHECK_ERR_RET(!type->range, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_RET(yin_parse_restriction(ctx, attrs, data, YANG_RANGE, type->range));
+ type->flags |= LYS_SET_RANGE;
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse length 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] type Type structure to store parsed value and flags.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+yin_parse_length(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs,
+ const char **data, struct lysp_type *type)
+{
+ type->length = calloc(1, sizeof *type->length);
+ LY_CHECK_ERR_RET(!type->length, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_RET(yin_parse_restriction(ctx, attrs, data, YANG_LENGTH, type->length));
+ type->flags |= LYS_SET_LENGTH;
+
+ return LY_SUCCESS;
+}
+
+/**
* @brief Parse must element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
@@ -979,19 +1108,35 @@
/**
* @brief parse type element.
*
- * @brief Parse position or value element.
+ * @brief Parse type 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,out] type Type to wrote to.
- * @param[in,out] exts Extension instance to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_type(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, struct lysp_type *type)
+yin_parse_type(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
+ enum yang_keyword parent, struct yin_subelement *subinfo)
{
+ struct lysp_type *type = NULL;
+ if (parent == YANG_DEVIATE) {
+ *(struct lysp_type **)subinfo->dest = calloc(1, sizeof **(struct lysp_type **)subinfo->dest);
+ LY_CHECK_ERR_RET(!(*(struct lysp_type **)subinfo->dest), LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ type = *((struct lysp_type **)subinfo->dest);
+ } else {
+ type = (struct lysp_type *)subinfo->dest;
+ }
+ /* type as child of another type */
+ if (parent == YANG_TYPE) {
+ struct lysp_type *nested_type = NULL;
+ LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, type->types, nested_type, LY_EMEM);
+ type->flags |= LYS_SET_TYPE;
+ type = nested_type;
+ }
struct yin_subelement subelems[11] = {
{YANG_BASE, type, 0},
{YANG_BIT, type, 0},
@@ -2740,7 +2885,6 @@
struct yin_arg_record *attrs = NULL;
enum yang_keyword kw = YANG_NONE, last_kw = YANG_NONE;
struct yin_subelement *subelem = NULL;
- struct lysp_type *type, *nested_type;
assert(is_ordered(subelem_info, subelem_info_size));
@@ -2772,6 +2916,7 @@
goto cleanup;
}
+ /* relative order is required only in module and submodule sub-elements */
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);
@@ -2822,18 +2967,7 @@
ret = yin_parse_augment(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
break;
case YANG_BASE:
- if (current_element == YANG_TYPE) {
- type = (struct lysp_type *)subelem->dest;
- ret = yin_parse_simple_elements(ctx, attrs, data, kw, &type->bases, YIN_ARG_NAME,
- Y_PREF_IDENTIF_ARG, exts);
- type->flags |= LYS_SET_BASE;
- } else if (current_element == YANG_IDENTITY) {
- ret = yin_parse_simple_elements(ctx, attrs, data, kw, (const char ***)subelem->dest,
- YIN_ARG_NAME, Y_PREF_IDENTIF_ARG, exts);
- } else {
- LOGINT(ctx->xml_ctx.ctx);
- ret = LY_EINT;
- }
+ ret = yin_parse_base(ctx, attrs, data, current_element, subelem->dest, exts);
break;
case YANG_BELONGS_TO:
ret = yin_parse_belongs_to(ctx, attrs, data, (struct lysp_submodule *)subelem->dest, exts);
@@ -2860,13 +2994,10 @@
ret = yin_parse_container(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
break;
case YANG_DEFAULT:
- if (subelem->flags & YIN_SUBELEM_UNIQUE) {
- ret = yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subelem->dest,
- YIN_ARG_VALUE, Y_STR_ARG, exts);
- } else {
- ret = yin_parse_simple_elements(ctx, attrs, data, kw, (const char ***)subelem->dest,
- YIN_ARG_VALUE, Y_STR_ARG, exts);
- }
+ case YANG_ERROR_APP_TAG:
+ case YANG_KEY:
+ case YANG_PRESENCE:
+ ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_VALUE, Y_STR_ARG, exts);
break;
case YANG_DEVIATE:
ret = yin_parse_deviate(ctx, attrs, data, (struct lysp_deviate **)subelem->dest);
@@ -2877,10 +3008,6 @@
case YANG_ENUM:
ret = yin_parse_enum(ctx, attrs, data, (struct lysp_type *)subelem->dest);
break;
- case YANG_ERROR_APP_TAG:
- ret = yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subelem->dest,
- YIN_ARG_VALUE, Y_STR_ARG, exts);
- break;
case YANG_ERROR_MESSAGE:
ret = yin_parse_err_msg_element(ctx, attrs, data, (const char **)subelem->dest, exts);
break;
@@ -2900,8 +3027,8 @@
ret = yin_parse_identity(ctx, attrs, data, (struct lysp_ident **)subelem->dest);
break;
case YANG_IF_FEATURE:
- ret = yin_parse_simple_elements(ctx, attrs, data, kw,
- (const char ***)subelem->dest, YIN_ARG_NAME, Y_STR_ARG, exts);
+ case YANG_UNITS:
+ ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_NAME, Y_STR_ARG, exts);
break;
case YANG_IMPORT:
ret = yin_parse_import(ctx, attrs, data, (struct import_meta *)subelem->dest);
@@ -2913,10 +3040,6 @@
case YANG_OUTPUT:
ret = yin_parse_inout(ctx, attrs, data, kw, (struct inout_meta *)subelem->dest);
break;
- case YANG_KEY:
- ret = yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subelem->dest, YIN_ARG_VALUE,
- Y_STR_ARG, exts);
- break;
case YANG_LEAF:
ret = yin_parse_leaf(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
break;
@@ -2924,11 +3047,7 @@
ret = yin_parse_leaflist(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
break;
case YANG_LENGTH:
- type = (struct lysp_type *)subelem->dest;
- type->length = calloc(1, sizeof *type->length);
- LY_CHECK_ERR_GOTO(!type->length, LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, cleanup);
- ret = yin_parse_restriction(ctx, attrs, data, kw, type->length);
- type->flags |= LYS_SET_LENGTH;
+ ret = yin_parse_length(ctx, attrs, data, (struct lysp_type *)subelem->dest);
break;
case YANG_LIST:
ret = yin_parse_list(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
@@ -2947,8 +3066,7 @@
ret = yin_parse_must(ctx, attrs, data, (struct lysp_restr **)subelem->dest);
break;
case YANG_NAMESPACE:
- ret = yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subelem->dest,
- YIN_ARG_URI, Y_STR_ARG, exts);
+ ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_URI, Y_STR_ARG, exts);
break;
case YANG_NOTIFICATION:
ret = yin_parse_notification(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
@@ -2957,33 +3075,20 @@
ret = yin_parse_orderedby(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
break;
case YANG_PATH:
- type = (struct lysp_type *)subelem->dest;
- ret = yin_parse_simple_element(ctx, attrs, data, kw, &type->path,
- YIN_ARG_VALUE, Y_STR_ARG, &type->exts);
- type->flags |= LYS_SET_PATH;
+ ret = yin_parse_path(ctx, attrs, data, kw, (struct lysp_type *)subelem->dest);
break;
case YANG_PATTERN:
ret = yin_parse_pattern(ctx, attrs, data, (struct lysp_type *)subelem->dest);
break;
case YANG_VALUE:
case YANG_POSITION:
- ret = yin_parse_value_pos_element(ctx, attrs, data, kw,
- (struct lysp_type_enum *)subelem->dest);
+ ret = yin_parse_value_pos_element(ctx, attrs, data, kw, (struct lysp_type_enum *)subelem->dest);
break;
case YANG_PREFIX:
- ret = yin_parse_simple_element(ctx, attrs, data, kw,
- (const char **)subelem->dest, YIN_ARG_VALUE, Y_IDENTIF_ARG, exts);
- break;
- case YANG_PRESENCE:
- ret = yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subelem->dest, YIN_ARG_VALUE,
- Y_STR_ARG, exts);
+ ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_VALUE, Y_IDENTIF_ARG, exts);
break;
case YANG_RANGE:
- type = (struct lysp_type *)subelem->dest;
- type->range = calloc(1, sizeof *type->range);
- LY_CHECK_ERR_GOTO(!type->range, LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, cleanup);
- ret = yin_parse_restriction(ctx, attrs, data, kw, type->range);
- type->flags |= LYS_SET_RANGE;
+ ret = yin_parse_range(ctx, attrs, data, (struct lysp_type *)subelem->dest);
break;
case YANG_REFINE:
ret = yin_parse_refine(ctx, attrs, data, (struct lysp_refine **)subelem->dest);
@@ -3001,31 +3106,13 @@
ret = yin_parse_status(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
break;
case YANG_TYPE:
- if (current_element == YANG_DEVIATE) {
- *(struct lysp_type **)subelem->dest = calloc(1, sizeof **(struct lysp_type **)subelem->dest);
- LY_CHECK_ERR_GOTO(!(*(struct lysp_type **)subelem->dest), LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, cleanup);
- type = *((struct lysp_type **)subelem->dest);
- } else {
- type = (struct lysp_type *)subelem->dest;
- }
- /* type as child of another type */
- if (current_element == YANG_TYPE) {
- LY_ARRAY_NEW_GOTO(ctx->xml_ctx.ctx, type->types, nested_type, ret, cleanup);
- type->flags |= LYS_SET_TYPE;
- type = nested_type;
- }
- ret = yin_parse_type(ctx, attrs, data, type);
+ ret = yin_parse_type(ctx, attrs, data, current_element, subelem);
break;
case YANG_TYPEDEF:
ret = yin_parse_typedef(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
break;
case YANG_UNIQUE:
- ret = yin_parse_simple_elements(ctx, attrs, data, kw, (const char ***)subelem->dest,
- YIN_ARG_TAG, Y_STR_ARG, exts);
- break;
- case YANG_UNITS:
- ret = yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subelem->dest,
- YIN_ARG_NAME, Y_STR_ARG, exts);
+ ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_TAG, Y_STR_ARG, exts);
break;
case YANG_USES:
ret = yin_parse_uses(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);