libyang REFACTOR applying deviations, augments, and refines (#1217)
They are no longer applied as part of their
definition module compilation but instead their
target module compilation.
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 71155a1..65b7d47 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -1255,6 +1255,49 @@
}
/**
+ * @brief Parse a generic text field that can have more instances such as base.
+ *
+ * @param[in] ctx yang parser context for logging.
+ * @param[in,out] in Input structure.
+ * @param[in] substmt Type of this substatement.
+ * @param[in,out] qnames Parsed qnames to add to.
+ * @param[in] arg Type of the expected argument.
+ * @param[in,out] exts Extension instances to add to.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+parse_qnames(struct lys_yang_parser_ctx *ctx, struct ly_in *in, LYEXT_SUBSTMT substmt, struct lysp_qname **qnames,
+ enum yang_arg arg, struct lysp_ext_instance **exts)
+{
+ LY_ERR ret = LY_SUCCESS;
+ char *buf, *word;
+ struct lysp_qname *item;
+ size_t word_len;
+ enum ly_stmt kw;
+
+ /* allocate new pointer */
+ LY_ARRAY_NEW_RET(ctx->ctx, *qnames, item, LY_EMEM);
+
+ /* get value */
+ LY_CHECK_RET(get_argument(ctx, in, arg, NULL, &word, &buf, &word_len));
+
+ INSERT_WORD_RET(ctx, buf, item->str, word, word_len);
+ item->mod = ctx->main_mod;
+ YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
+ switch (kw) {
+ case LY_STMT_EXTENSION_INSTANCE:
+ LY_CHECK_RET(parse_ext(ctx, in, word, word_len, substmt, LY_ARRAY_COUNT(*qnames) - 1, exts));
+ break;
+ default:
+ LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), lyext_substmt2str(substmt));
+ return LY_EVALID;
+ }
+ }
+ return ret;
+}
+
+/**
* @brief Parse the config statement.
*
* @param[in] ctx yang parser context for logging.
@@ -1376,7 +1419,8 @@
LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
CHECK_NONEMPTY(ctx, word_len, ly_stmt2str(restr_kw));
- INSERT_WORD_RET(ctx, buf, restr->arg, word, word_len);
+ INSERT_WORD_RET(ctx, buf, restr->arg.str, word, word_len);
+ restr->arg.mod = ctx->main_mod;
YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
switch (kw) {
case LY_STMT_DESCRIPTION:
@@ -1563,7 +1607,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &any->dsc, Y_STR_ARG, &any->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &any->iffeatures, Y_STR_ARG, &any->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &any->iffeatures, Y_STR_ARG, &any->exts));
break;
case LY_STMT_MANDATORY:
LY_CHECK_RET(parse_mandatory(ctx, in, &any->flags, &any->exts));
@@ -1714,7 +1758,7 @@
break;
case LY_STMT_IF_FEATURE:
PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", ly_stmt2str(enum_kw));
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &enm->iffeatures, Y_STR_ARG, &enm->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &enm->iffeatures, Y_STR_ARG, &enm->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &enm->ref, Y_STR_ARG, &enm->exts));
@@ -1947,7 +1991,8 @@
memmove(buf + 1, word, word_len);
buf[0] = 0x06; /* pattern's default regular-match flag */
buf[word_len + 1] = '\0'; /* terminating NULL byte */
- LY_CHECK_RET(lydict_insert_zc(ctx->ctx, buf, &restr->arg));
+ LY_CHECK_RET(lydict_insert_zc(ctx->ctx, buf, &restr->arg.str));
+ restr->arg.mod = ctx->main_mod;
YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
switch (kw) {
@@ -1965,7 +2010,7 @@
break;
case LY_STMT_MODIFIER:
PARSER_CHECK_STMTVER2_RET(ctx, "modifier", "pattern");
- LY_CHECK_RET(parse_type_pattern_modifier(ctx, in, &restr->arg, &restr->exts));
+ LY_CHECK_RET(parse_type_pattern_modifier(ctx, in, &restr->arg.str, &restr->exts));
break;
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &restr->exts));
@@ -2117,13 +2162,14 @@
LY_CHECK_RET(parse_config(ctx, in, &leaf->flags, &leaf->exts));
break;
case LY_STMT_DEFAULT:
- LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &leaf->dflt, Y_STR_ARG, &leaf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &leaf->dflt.str, Y_STR_ARG, &leaf->exts));
+ leaf->dflt.mod = ctx->main_mod;
break;
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &leaf->dsc, Y_STR_ARG, &leaf->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &leaf->iffeatures, Y_STR_ARG, &leaf->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &leaf->iffeatures, Y_STR_ARG, &leaf->exts));
break;
case LY_STMT_MANDATORY:
LY_CHECK_RET(parse_mandatory(ctx, in, &leaf->flags, &leaf->exts));
@@ -2161,10 +2207,6 @@
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf");
return LY_EVALID;
}
- if ((leaf->flags & LYS_MAND_TRUE) && (leaf->dflt)) {
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMSCOMB, "mandatory", "default", "leaf");
- return LY_EVALID;
- }
return ret;
}
@@ -2387,13 +2429,13 @@
break;
case LY_STMT_DEFAULT:
PARSER_CHECK_STMTVER2_RET(ctx, "default", "leaf-list");
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_DEFAULT, &llist->dflts, Y_STR_ARG, &llist->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_DEFAULT, &llist->dflts, Y_STR_ARG, &llist->exts));
break;
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &llist->dsc, Y_STR_ARG, &llist->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &llist->iffeatures, Y_STR_ARG, &llist->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &llist->iffeatures, Y_STR_ARG, &llist->exts));
break;
case LY_STMT_MAX_ELEMENTS:
LY_CHECK_RET(parse_maxelements(ctx, in, &llist->max, &llist->flags, &llist->exts));
@@ -2437,16 +2479,6 @@
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf-list");
return LY_EVALID;
}
- if ((llist->min) && (llist->dflts)) {
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMSCOMB, "min-elements", "default", "leaf-list");
- return LY_EVALID;
- }
- if (llist->max && llist->min > llist->max) {
- LOGVAL_PARSER(ctx, LYVE_SEMANTICS,
- "Invalid combination of min-elements and max-elements: min value %u is bigger than the max value %u.",
- llist->min, llist->max);
- return LY_EVALID;
- }
return ret;
}
@@ -2489,7 +2521,7 @@
break;
case LY_STMT_IF_FEATURE:
PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "refine");
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &rf->iffeatures, Y_STR_ARG, &rf->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &rf->iffeatures, Y_STR_ARG, &rf->exts));
break;
case LY_STMT_MAX_ELEMENTS:
LY_CHECK_RET(parse_maxelements(ctx, in, &rf->max, &rf->flags, &rf->exts));
@@ -2548,7 +2580,8 @@
YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
switch (kw) {
case LY_STMT_DEFAULT:
- LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &tpdf->dflt, Y_STR_ARG, &tpdf->exts));
+ LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &tpdf->dflt.str, Y_STR_ARG, &tpdf->exts));
+ tpdf->dflt.mod = ctx->main_mod;
break;
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &tpdf->dsc, Y_STR_ARG, &tpdf->exts));
@@ -2582,7 +2615,7 @@
}
/* store data for collision check */
- if (parent && !(parent->nodetype & (LYS_GROUPING | LYS_RPC | LYS_ACTION | LYS_INOUT | LYS_NOTIF))) {
+ if (parent && !(parent->nodetype & (LYS_GROUPING | LYS_RPC | LYS_ACTION | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF))) {
LY_CHECK_RET(ly_set_add(&ctx->tpdfs_nodes, parent, 0, NULL));
}
@@ -2600,7 +2633,8 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_inout(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt inout_kw, struct lysp_node *parent, struct lysp_action_inout *inout_p)
+parse_inout(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt inout_kw, struct lysp_node *parent,
+ struct lysp_action_inout *inout_p)
{
LY_ERR ret = LY_SUCCESS;
char *word;
@@ -2707,7 +2741,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &act->dsc, Y_STR_ARG, &act->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &act->iffeatures, Y_STR_ARG, &act->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &act->iffeatures, Y_STR_ARG, &act->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &act->ref, Y_STR_ARG, &act->exts));
@@ -2738,6 +2772,17 @@
}
}
LY_CHECK_RET(ret);
+
+ /* always initialize inout, they are technically present (needed for later deviations/refines) */
+ if (!act->input.nodetype) {
+ act->input.nodetype = LYS_INPUT;
+ act->input.parent = (struct lysp_node *)act;
+ }
+ if (!act->output.nodetype) {
+ act->output.nodetype = LYS_OUTPUT;
+ act->output.parent = (struct lysp_node *)act;
+ }
+
checks:
/* finalize parent pointers to the reallocated items */
LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, act->groupings, NULL, NULL, NULL));
@@ -2777,7 +2822,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, ¬if->dsc, Y_STR_ARG, ¬if->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, ¬if->iffeatures, Y_STR_ARG, ¬if->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, ¬if->iffeatures, Y_STR_ARG, ¬if->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, ¬if->ref, Y_STR_ARG, ¬if->exts));
@@ -2963,7 +3008,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &aug->iffeatures, Y_STR_ARG, &aug->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &aug->iffeatures, Y_STR_ARG, &aug->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &aug->ref, Y_STR_ARG, &aug->exts));
@@ -3061,7 +3106,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &uses->iffeatures, Y_STR_ARG, &uses->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &uses->iffeatures, Y_STR_ARG, &uses->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &uses->ref, Y_STR_ARG, &uses->exts));
@@ -3128,7 +3173,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &cas->iffeatures, Y_STR_ARG, &cas->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &cas->iffeatures, Y_STR_ARG, &cas->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &cas->ref, Y_STR_ARG, &cas->exts));
@@ -3203,7 +3248,7 @@
INSERT_WORD_RET(ctx, buf, choice->name, word, word_len);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
+ YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, in, &choice->flags, &choice->exts));
@@ -3212,7 +3257,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &choice->dsc, Y_STR_ARG, &choice->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &choice->iffeatures, Y_STR_ARG, &choice->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &choice->iffeatures, Y_STR_ARG, &choice->exts));
break;
case LY_STMT_MANDATORY:
LY_CHECK_RET(parse_mandatory(ctx, in, &choice->flags, &choice->exts));
@@ -3227,7 +3272,9 @@
LY_CHECK_RET(parse_when(ctx, in, &choice->when));
break;
case LY_STMT_DEFAULT:
- LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &choice->dflt, Y_PREF_IDENTIF_ARG, &choice->exts));
+ LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &choice->dflt.str, Y_PREF_IDENTIF_ARG,
+ &choice->exts));
+ choice->dflt.mod = ctx->main_mod;
break;
case LY_STMT_ANYDATA:
@@ -3263,12 +3310,6 @@
return LY_EVALID;
}
}
- LY_CHECK_RET(ret);
-checks:
- if ((choice->flags & LYS_MAND_TRUE) && choice->dflt) {
- LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMSCOMB, "mandatory", "default", "choice");
- return LY_EVALID;
- }
return ret;
}
@@ -3309,7 +3350,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &cont->dsc, Y_STR_ARG, &cont->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &cont->iffeatures, Y_STR_ARG, &cont->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &cont->iffeatures, Y_STR_ARG, &cont->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &cont->ref, Y_STR_ARG, &cont->exts));
@@ -3417,7 +3458,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &list->dsc, Y_STR_ARG, &list->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &list->iffeatures, Y_STR_ARG, &list->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &list->iffeatures, Y_STR_ARG, &list->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &list->ref, Y_STR_ARG, &list->exts));
@@ -3441,7 +3482,7 @@
LY_CHECK_RET(parse_orderedby(ctx, in, &list->flags, &list->exts));
break;
case LY_STMT_UNIQUE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_UNIQUE, &list->uniques, Y_STR_ARG, &list->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_UNIQUE, &list->uniques, Y_STR_ARG, &list->exts));
break;
case LY_STMT_ANYDATA:
@@ -3499,13 +3540,6 @@
/* finalize parent pointers to the reallocated items */
LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, list->groupings, NULL, list->actions, list->notifs));
- if (list->max && list->min > list->max) {
- LOGVAL_PARSER(ctx, LYVE_SEMANTICS,
- "Invalid combination of min-elements and max-elements: min value %u is bigger than the max value %u.",
- list->min, list->max);
- return LY_EVALID;
- }
-
return ret;
}
@@ -3946,7 +3980,7 @@
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &feat->dsc, Y_STR_ARG, &feat->exts));
break;
case LY_STMT_IF_FEATURE:
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &feat->iffeatures, Y_STR_ARG, &feat->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &feat->iffeatures, Y_STR_ARG, &feat->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &feat->ref, Y_STR_ARG, &feat->exts));
@@ -3996,7 +4030,7 @@
break;
case LY_STMT_IF_FEATURE:
PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "identity");
- LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &ident->iffeatures, Y_STR_ARG, &ident->exts));
+ LY_CHECK_RET(parse_qnames(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &ident->iffeatures, Y_STR_ARG, &ident->exts));
break;
case LY_STMT_REFERENCE:
LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &ident->ref, Y_STR_ARG, &ident->exts));