tree schema CHANGE plugin record in parsed extensions
diff --git a/src/parser_yang.c b/src/parser_yang.c
index d0b2ea1..3a1fe17 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -39,6 +39,7 @@
/**
* @brief Insert WORD into the libyang context's dictionary and store as TARGET.
+ *
* @param[in] CTX yang parser context to access libyang context.
* @param[in] BUF buffer in case the word is not a constant and can be inserted directly (zero-copy)
* @param[out] TARGET variable where to store the pointer to the inserted value.
@@ -51,44 +52,61 @@
/**
* @brief Read from the IN structure COUNT items. Also updates the indent value in yang parser context
+ *
* @param[in] CTX yang parser context to update its indent value.
* @param[in] COUNT number of items for which the DATA pointer is supposed to move on.
*/
#define MOVE_INPUT(CTX, COUNT) ly_in_skip((CTX)->in, COUNT);(CTX)->indent+=COUNT
/**
- * @brief Loop through all substatements.
+ * @brief Loop through all substatements. Starts a for loop and ::YANG_READ_SUBSTMT_NEXT_ITER must be used at its end.
*
* @param[in] CTX yang parser context for logging.
* @param[out] KW YANG keyword read.
* @param[out] WORD Pointer to the keyword itself.
* @param[out] WORD_LEN Length of the keyword.
* @param[out] RET Variable for error storing.
- * @param[in] SUC_CMD Command is applied if a semicolon is found, so no
- * substatements are available. It is expected to contain a return or goto command.
- * @param[in] ERR_CMD Command is applied if an error occurs before loop through
- * substatements. It is expected to contain return or goto command.
- *
- * @return In case there are no substatements or a fatal error encountered.
+ * @param[in] ERR_LABEL Label to go to on error.
*/
-#define YANG_READ_SUBSTMT_FOR(CTX, KW, WORD, WORD_LEN, RET, SUC_CMD, ERR_CMD) \
+#define YANG_READ_SUBSTMT_FOR_GOTO(CTX, KW, WORD, WORD_LEN, RET, ERR_LABEL) \
+ ly_bool __loop_end = 0; \
if ((RET = get_keyword(CTX, &KW, &WORD, &WORD_LEN))) { \
- ERR_CMD; \
+ goto ERR_LABEL; \
} \
if (KW == LY_STMT_SYNTAX_SEMICOLON) { \
- SUC_CMD; \
- } \
- if (KW != LY_STMT_SYNTAX_LEFT_BRACE) { \
+ __loop_end = 1; \
+ } else if (KW != LY_STMT_SYNTAX_LEFT_BRACE) { \
LOGVAL_PARSER(CTX, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\", expected \";\" or \"{\".", ly_stmt2str(KW)); \
RET = LY_EVALID; \
- ERR_CMD; \
+ goto ERR_LABEL; \
+ } else { \
+ YANG_READ_SUBSTMT_NEXT_ITER(CTX, KW, WORD, WORD_LEN, NULL, RET, ERR_LABEL); \
} \
- for (RET = get_keyword(CTX, &KW, &WORD, &WORD_LEN); \
- !RET && (KW != LY_STMT_SYNTAX_RIGHT_BRACE); \
- RET = get_keyword(CTX, &KW, &WORD, &WORD_LEN))
+ while (!__loop_end)
-LY_ERR parse_container(struct lys_yang_parser_ctx *ctx, struct lysp_node *parent,
- struct lysp_node **siblings);
+/**
+ * @brief Next iteration of ::YANG_READ_SUBSTMT_FOR_GOTO loop.
+ *
+ * @param[in] CTX yang parser context for logging.
+ * @param[out] KW YANG keyword read.
+ * @param[out] WORD Pointer to the keyword itself.
+ * @param[out] WORD_LEN Length of the keyword.
+ * @param[in] EXTS Final extension instance array to store.
+ * @param[out] RET Variable for error storing.
+ * @param[in] ERR_LABEL Label to go to on error.
+ */
+#define YANG_READ_SUBSTMT_NEXT_ITER(CTX, KW, WORD, WORD_LEN, EXTS, RET, ERR_LABEL) \
+ if ((RET = get_keyword(CTX, &KW, &WORD, &WORD_LEN))) { \
+ goto ERR_LABEL; \
+ } \
+ if (KW == LY_STMT_SYNTAX_RIGHT_BRACE) { \
+ if (EXTS && (RET = ly_set_add(&(CTX)->ext_inst, (EXTS), 1, NULL))) { \
+ goto ERR_LABEL; \
+ } \
+ __loop_end = 1; \
+ }
+
+LY_ERR parse_container(struct lys_yang_parser_ctx *ctx, struct lysp_node *parent, struct lysp_node **siblings);
LY_ERR parse_uses(struct lys_yang_parser_ctx *ctx, struct lysp_node *parent, struct lysp_node **siblings);
LY_ERR parse_choice(struct lys_yang_parser_ctx *ctx, struct lysp_node *parent, struct lysp_node **siblings);
LY_ERR parse_case(struct lys_yang_parser_ctx *ctx, struct lysp_node *parent, struct lysp_node **siblings);
@@ -106,7 +124,6 @@
* @param[in,out] buf Buffer to use, can be moved by realloc().
* @param[in,out] buf_len Current size of the buffer.
* @param[in,out] buf_used Currently used characters of the buffer.
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -144,7 +161,6 @@
* 0 - colon not yet found (no prefix)
* 1 - \p c is the colon character
* 2 - prefix already processed, now processing the identifier
- *
* @return LY_ERR values.
*/
LY_ERR
@@ -300,7 +316,6 @@
* @param[out] buf_len Length of the dynamically-allocated buffer \p word_b.
* @param[in] indent Current indent (number of YANG spaces). Needed for correct multi-line string
* indenation in the final quoted string.
- *
* @return LY_ERR values.
*/
static LY_ERR
@@ -888,8 +903,9 @@
stmt->prefix_data = PARSER_CUR_PMOD(ctx);
stmt->kw = kw;
- YANG_READ_SUBSTMT_FOR(ctx, child_kw, word, word_len, ret, return LY_SUCCESS, return ret) {
- LY_CHECK_RET(parse_ext_substmt(ctx, child_kw, word, word_len, &stmt->child));
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, child_kw, word, word_len, ret, cleanup) {
+ LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, child_kw, word, word_len, &stmt->child), cleanup)
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, child_kw, word, word_len, NULL, ret, cleanup);
}
cleanup:
@@ -941,8 +957,9 @@
e->parent_stmt = insubstmt;
e->parent_stmt_index = insubstmt_index;
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
- LY_CHECK_RET(parse_ext_substmt(ctx, kw, word, word_len, &e->child));
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
+ LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
cleanup:
@@ -982,7 +999,7 @@
/* store value and spend buf if allocated */
INSERT_WORD_GOTO(ctx, buf, *value, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, substmt, substmt_index, exts));
@@ -991,6 +1008,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(substmt));
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
cleanup:
@@ -1033,7 +1051,7 @@
}
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_YANG_VERSION, 0, exts));
@@ -1042,7 +1060,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "yang-version");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -1078,7 +1099,7 @@
}
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_PREFIX:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_PREFIX, 0, prefix, Y_IDENTIF_ARG, exts));
@@ -1090,14 +1111,16 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "belongs-to");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
+
/* mandatory substatements */
if (!*prefix) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "prefix", "belongs-to");
return LY_EVALID;
}
+
+cleanup:
return ret;
}
@@ -1136,7 +1159,7 @@
strncpy(rev, word, word_len);
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_REVISION_DATE, 0, exts));
@@ -1145,7 +1168,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "revision-date");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -1181,7 +1207,7 @@
return LY_EVALID;
}
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
PARSER_CHECK_STMTVER2_RET(ctx, "description", "include");
@@ -1201,6 +1227,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "include");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, inc->exts, ret, cleanup);
}
cleanup:
@@ -1231,7 +1258,7 @@
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, imp->name, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_PREFIX:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_PREFIX, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts));
@@ -1255,10 +1282,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "import");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, imp->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* mandatory substatements */
LY_CHECK_ERR_RET(!imp->prefix, LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "prefix", "import"), LY_EVALID);
@@ -1297,7 +1323,7 @@
strncpy(rev->date, word, word_len);
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &rev->dsc, Y_STR_ARG, &rev->exts));
@@ -1312,7 +1338,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "revision");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, rev->exts, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -1344,7 +1373,7 @@
LY_CHECK_RET(get_argument(ctx, arg, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, *item, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, substmt, LY_ARRAY_COUNT(*texts) - 1, exts));
@@ -1353,6 +1382,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(substmt));
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
cleanup:
@@ -1388,7 +1418,7 @@
INSERT_WORD_GOTO(ctx, buf, item->str, word, word_len, ret, cleanup);
item->mod = PARSER_CUR_PMOD(ctx);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, substmt, LY_ARRAY_COUNT(*qnames) - 1, exts));
@@ -1397,6 +1427,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(substmt));
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
cleanup:
@@ -1439,7 +1470,7 @@
}
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_CONFIG, 0, exts));
@@ -1448,7 +1479,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "config");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -1488,7 +1522,7 @@
}
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_MANDATORY, 0, exts));
@@ -1497,7 +1531,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "mandatory");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -1524,7 +1561,7 @@
CHECK_NONEMPTY(ctx, word_len, ly_stmt2str(restr_kw));
INSERT_WORD_GOTO(ctx, buf, restr->arg.str, word, word_len, ret, cleanup);
restr->arg.mod = PARSER_CUR_PMOD(ctx);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
@@ -1545,6 +1582,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(restr_kw));
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, restr->exts, ret, cleanup);
}
cleanup:
@@ -1607,7 +1645,7 @@
}
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_STATUS, 0, exts));
@@ -1616,7 +1654,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "status");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -1651,7 +1692,7 @@
CHECK_NONEMPTY(ctx, word_len, "when");
INSERT_WORD_GOTO(ctx, buf, when->cond, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto cleanup, goto cleanup) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &when->dsc, Y_STR_ARG, &when->exts), cleanup);
@@ -1667,6 +1708,7 @@
ret = LY_EVALID;
goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, when->exts, ret, cleanup);
}
cleanup:
@@ -1708,7 +1750,7 @@
INSERT_WORD_GOTO(ctx, buf, any->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, &any->flags, &any->exts));
@@ -1741,6 +1783,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(any_kw));
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, any->exts, ret, cleanup);
}
cleanup:
@@ -1763,7 +1806,7 @@
struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *buf, *word, *ptr;
+ char *buf = NULL, *word, *ptr;
size_t word_len;
long long int num = 0;
unsigned long long int unum = 0;
@@ -1771,7 +1814,8 @@
if (*flags & LYS_SET_VALUE) {
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(val_kw));
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
*flags |= LYS_SET_VALUE;
@@ -1780,7 +1824,8 @@
if (!word_len || (word[0] == '+') || ((word[0] == '0') && (word_len > 1)) || ((val_kw == LY_STMT_POSITION) && !strncmp(word, "-0", 2))) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
errno = 0;
@@ -1788,46 +1833,51 @@
num = strtoll(word, &ptr, LY_BASE_DEC);
if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
} else {
unum = strtoull(word, &ptr, LY_BASE_DEC);
if (unum > UINT64_C(4294967295)) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
}
/* we have not parsed the whole argument */
if ((size_t)(ptr - word) != word_len) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
if (errno == ERANGE) {
LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, ly_stmt2str(val_kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
if (val_kw == LY_STMT_VALUE) {
*value = num;
} else {
*value = unum;
}
- free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, val_kw == LY_STMT_VALUE ? LY_STMT_VALUE : LY_STMT_POSITION, 0, exts));
+ ret = parse_ext(ctx, word, word_len, val_kw == LY_STMT_VALUE ? LY_STMT_VALUE : LY_STMT_POSITION, 0, exts);
+ LY_CHECK_GOTO(ret, cleanup);
break;
default:
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(val_kw));
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
- return ret;
-error:
+cleanup:
free(buf);
- return LY_EVALID;
+ return ret;
}
/**
@@ -1860,7 +1910,7 @@
INSERT_WORD_GOTO(ctx, buf, enm->name, word, word_len, ret, cleanup);
CHECK_UNIQUENESS(ctx, *enums, name, ly_stmt2str(enum_kw), enm->name);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
@@ -1892,6 +1942,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(enum_kw));
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, enm->exts, ret, cleanup);
}
cleanup:
@@ -1911,7 +1962,7 @@
parse_type_fracdigits(struct lys_yang_parser_ctx *ctx, uint8_t *fracdig, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *buf, *word, *ptr;
+ char *buf = NULL, *word, *ptr;
size_t word_len;
unsigned long long int num;
enum ly_stmt kw;
@@ -1922,12 +1973,12 @@
}
/* get value */
- LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
+ LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if (!word_len || (word[0] == '0') || !isdigit(word[0])) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "fraction-digits");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
errno = 0;
@@ -1935,27 +1986,31 @@
/* we have not parsed the whole argument */
if ((size_t)(ptr - word) != word_len) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "fraction-digits");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
if ((errno == ERANGE) || (num > LY_TYPE_DEC64_FD_MAX)) {
LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, "fraction-digits");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
*fracdig = num;
- free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_FRACTION_DIGITS, 0, exts));
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_FRACTION_DIGITS, 0, exts), cleanup);
break;
default:
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "fraction-digits");
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
+ free(buf);
return ret;
}
@@ -1974,7 +2029,7 @@
struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *buf, *word;
+ char *buf = NULL, *word;
size_t word_len;
enum ly_stmt kw;
@@ -1985,27 +2040,31 @@
*flags |= LYS_SET_REQINST;
/* get value */
- LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
+ LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if ((word_len == ly_strlen_const("true")) && !strncmp(word, "true", word_len)) {
*reqinst = 1;
} else if ((word_len != ly_strlen_const("false")) || strncmp(word, "false", word_len)) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "require-instance");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
- free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_REQUIRE_INSTANCE, 0, exts));
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_REQUIRE_INSTANCE, 0, exts), cleanup);
break;
default:
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "require-instance");
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
+ free(buf);
return ret;
}
@@ -2022,7 +2081,7 @@
parse_type_pattern_modifier(struct lys_yang_parser_ctx *ctx, const char **pat, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *buf, *word;
+ char *buf = NULL, *word;
size_t word_len;
enum ly_stmt kw;
@@ -2032,35 +2091,40 @@
}
/* get value */
- LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
+ LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if ((word_len != ly_strlen_const("invert-match")) || strncmp(word, "invert-match", word_len)) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "modifier");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
- free(buf);
/* replace the value in the dictionary */
buf = malloc(strlen(*pat) + 1);
- LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
+ LY_CHECK_ERR_GOTO(!buf, LOGMEM(PARSER_CTX(ctx)); ret = LY_EMEM, cleanup);
strcpy(buf, *pat);
lydict_remove(PARSER_CTX(ctx), *pat);
assert(buf[0] == LYSP_RESTR_PATTERN_ACK);
buf[0] = LYSP_RESTR_PATTERN_NACK;
- LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, pat));
+ LY_CHECK_GOTO(ret = lydict_insert_zc(PARSER_CTX(ctx), buf, pat), cleanup);
+ buf = NULL;
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_MODIFIER, 0, exts));
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_MODIFIER, 0, exts), cleanup);
break;
default:
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "modifier");
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
+ free(buf);
return ret;
}
@@ -2102,7 +2166,7 @@
LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, &restr->arg.str));
restr->arg.mod = PARSER_CUR_PMOD(ctx);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
@@ -2127,7 +2191,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "pattern");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, restr->exts, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -2161,7 +2228,7 @@
/* set module */
type->pmod = PARSER_CUR_PMOD(ctx);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_BASE:
LY_CHECK_RET(parse_text_fields(ctx, LY_STMT_BASE, &type->bases, Y_PREF_IDENTIF_ARG, &type->exts));
@@ -2241,6 +2308,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "type");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, type->exts, ret, cleanup);
}
cleanup:
@@ -2274,7 +2342,7 @@
INSERT_WORD_GOTO(ctx, buf, leaf->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, &leaf->flags, &leaf->exts));
@@ -2317,10 +2385,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "leaf");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, leaf->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* mandatory substatements */
if (!leaf->type.name) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf");
@@ -2345,7 +2412,7 @@
parse_maxelements(struct lys_yang_parser_ctx *ctx, uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *buf, *word, *ptr;
+ char *buf = NULL, *word, *ptr;
size_t word_len;
unsigned long long int num;
enum ly_stmt kw;
@@ -2357,12 +2424,12 @@
*flags |= LYS_SET_MAX;
/* get value */
- LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
+ LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if (!word_len || (word[0] == '0') || ((word[0] != 'u') && !isdigit(word[0]))) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "max-elements");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
if (ly_strncmp("unbounded", word, word_len)) {
@@ -2371,13 +2438,13 @@
/* we have not parsed the whole argument */
if ((size_t)(ptr - word) != word_len) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "max-elements");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
if ((errno == ERANGE) || (num > UINT32_MAX)) {
LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, "max-elements");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
*max = num;
@@ -2387,16 +2454,21 @@
}
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_MAX_ELEMENTS, 0, exts));
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_MAX_ELEMENTS, 0, exts), cleanup);
break;
default:
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "max-elements");
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
+ free(buf);
return ret;
}
@@ -2414,7 +2486,7 @@
parse_minelements(struct lys_yang_parser_ctx *ctx, uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *buf, *word, *ptr;
+ char *buf = NULL, *word, *ptr;
size_t word_len;
unsigned long long int num;
enum ly_stmt kw;
@@ -2426,12 +2498,12 @@
*flags |= LYS_SET_MIN;
/* get value */
- LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
+ LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if (!word_len || !isdigit(word[0]) || ((word[0] == '0') && (word_len > 1))) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "min-elements");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
errno = 0;
@@ -2439,27 +2511,31 @@
/* we have not parsed the whole argument */
if ((size_t)(ptr - word) != word_len) {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "min-elements");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
if ((errno == ERANGE) || (num > UINT32_MAX)) {
LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, "min-elements");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
*min = num;
- free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_MIN_ELEMENTS, 0, exts));
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_MIN_ELEMENTS, 0, exts), cleanup);
break;
default:
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "min-elements");
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
+ free(buf);
return ret;
}
@@ -2476,7 +2552,7 @@
parse_orderedby(struct lys_yang_parser_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *buf, *word;
+ char *buf = NULL, *word;
size_t word_len;
enum ly_stmt kw;
@@ -2486,7 +2562,7 @@
}
/* get value */
- LY_CHECK_RET(get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len));
+ LY_CHECK_GOTO(ret = get_argument(ctx, Y_STR_ARG, NULL, &word, &buf, &word_len), cleanup);
if ((word_len == ly_strlen_const("system")) && !strncmp(word, "system", word_len)) {
*flags |= LYS_ORDBY_SYSTEM;
@@ -2494,21 +2570,25 @@
*flags |= LYS_ORDBY_USER;
} else {
LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "ordered-by");
- free(buf);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
- free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
- LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_ORDERED_BY, 0, exts));
+ LY_CHECK_GOTO(ret = parse_ext(ctx, word, word_len, LY_STMT_ORDERED_BY, 0, exts), cleanup);
break;
default:
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "ordered-by");
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
+ free(buf);
return ret;
}
@@ -2539,7 +2619,7 @@
INSERT_WORD_GOTO(ctx, buf, llist->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, &llist->flags, &llist->exts));
@@ -2588,10 +2668,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "llist");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, llist->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* mandatory substatements */
if (!llist->type.name) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf-list");
@@ -2626,7 +2705,7 @@
CHECK_NONEMPTY(ctx, word_len, "refine");
INSERT_WORD_GOTO(ctx, buf, rf->nodeid, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, &rf->flags, &rf->exts));
@@ -2666,6 +2745,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "refine");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, rf->exts, ret, cleanup);
}
cleanup:
@@ -2696,7 +2776,7 @@
INSERT_WORD_GOTO(ctx, buf, tpdf->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DEFAULT:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DEFAULT, 0, &tpdf->dflt.str, Y_STR_ARG, &tpdf->exts));
@@ -2724,10 +2804,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "typedef");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, tpdf->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* mandatory substatements */
if (!tpdf->type.name) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "typedef");
@@ -2774,7 +2853,7 @@
inout_p->parent = parent;
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_ANYDATA:
PARSER_CHECK_STMTVER2_RET(ctx, "anydata", ly_stmt2str(inout_kw));
@@ -2817,15 +2896,15 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(inout_kw));
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, inout_p->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
if (!inout_p->child) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(inout_kw));
return LY_EVALID;
}
+cleanup:
return ret;
}
@@ -2854,7 +2933,7 @@
act->nodetype = parent ? LYS_ACTION : LYS_RPC;
act->parent = parent;
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &act->dsc, Y_STR_ARG, &act->exts));
@@ -2889,10 +2968,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), parent ? "action" : "rpc");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, act->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* always initialize inout, they are technically present (needed for later deviations/refines) */
if (!act->input.nodetype) {
act->input.nodetype = LYS_INPUT;
@@ -2934,7 +3012,7 @@
notif->nodetype = LYS_NOTIF;
notif->parent = parent;
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, ¬if->dsc, Y_STR_ARG, ¬if->exts));
@@ -2991,6 +3069,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "notification");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, notif->exts, ret, cleanup);
}
cleanup:
@@ -3022,7 +3101,7 @@
grp->nodetype = LYS_GROUPING;
grp->parent = parent;
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &grp->dsc, Y_STR_ARG, &grp->exts));
@@ -3080,10 +3159,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "grouping");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, grp->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* store data for collision check */
if (parent) {
assert(ctx->main_ctx);
@@ -3120,7 +3198,7 @@
aug->nodetype = LYS_AUGMENT;
aug->parent = parent;
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
@@ -3181,6 +3259,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "augment");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, aug->exts, ret, cleanup);
}
cleanup:
@@ -3214,7 +3293,7 @@
INSERT_WORD_GOTO(ctx, buf, uses->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
@@ -3245,6 +3324,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "uses");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, uses->exts, ret, cleanup);
}
cleanup:
@@ -3278,7 +3358,7 @@
INSERT_WORD_GOTO(ctx, buf, cas->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
@@ -3327,6 +3407,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "case");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, cas->exts, ret, cleanup);
}
cleanup:
@@ -3360,7 +3441,7 @@
INSERT_WORD_GOTO(ctx, buf, choice->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, &choice->flags, &choice->exts));
@@ -3421,6 +3502,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "choice");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, choice->exts, ret, cleanup);
}
cleanup:
@@ -3454,7 +3536,7 @@
INSERT_WORD_GOTO(ctx, buf, cont->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, &cont->flags, &cont->exts));
@@ -3527,6 +3609,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "container");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, cont->exts, ret, cleanup);
}
cleanup:
@@ -3560,7 +3643,7 @@
INSERT_WORD_GOTO(ctx, buf, list->name, word, word_len, ret, cleanup);
/* parse substatements */
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
LY_CHECK_RET(parse_config(ctx, &list->flags, &list->exts));
@@ -3645,6 +3728,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "list");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, list->exts, ret, cleanup);
}
cleanup:
@@ -3687,7 +3771,7 @@
}
free(buf);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_EXTENSION_INSTANCE:
LY_CHECK_RET(parse_ext(ctx, word, word_len, LY_STMT_YIN_ELEMENT, 0, exts));
@@ -3697,7 +3781,10 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "yin-element");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
+
+cleanup:
return ret;
}
@@ -3728,7 +3815,7 @@
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, *argument, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_YIN_ELEMENT:
LY_CHECK_RET(parse_yinelement(ctx, flags, exts));
@@ -3740,6 +3827,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "argument");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
}
cleanup:
@@ -3769,7 +3857,7 @@
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, ex->name, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &ex->dsc, Y_STR_ARG, &ex->exts));
@@ -3790,6 +3878,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "extension");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, ex->exts, ret, cleanup);
}
cleanup:
@@ -3883,7 +3972,7 @@
}
d->mod = dev_mod;
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto cleanup, goto cleanup) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_CONFIG:
switch (dev_mod) {
@@ -4011,6 +4100,7 @@
ret = LY_EVALID;
goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, d->exts, ret, cleanup);
}
cleanup:
@@ -4050,7 +4140,7 @@
CHECK_NONEMPTY(ctx, word_len, "deviation");
INSERT_WORD_GOTO(ctx, buf, dev->nodeid, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, goto cleanup) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_GOTO(ret = parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &dev->dsc, Y_STR_ARG, &dev->exts), cleanup);
@@ -4069,10 +4159,9 @@
ret = LY_EVALID;
goto cleanup;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, dev->exts, ret, cleanup);
}
- LY_CHECK_GOTO(ret, cleanup);
-checks:
/* mandatory substatements */
if (!dev->deviates) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "deviate", "deviation");
@@ -4111,7 +4200,7 @@
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, feat->name, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &feat->dsc, Y_STR_ARG, &feat->exts));
@@ -4132,6 +4221,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "feature");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, feat->exts, ret, cleanup);
}
cleanup:
@@ -4161,7 +4251,7 @@
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, ident->name, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, return LY_SUCCESS, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
switch (kw) {
case LY_STMT_DESCRIPTION:
LY_CHECK_RET(parse_text_field(ctx, LY_STMT_DESCRIPTION, 0, &ident->dsc, Y_STR_ARG, &ident->exts));
@@ -4190,6 +4280,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "identity");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, ident->exts, ret, cleanup);
}
cleanup:
@@ -4220,7 +4311,7 @@
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, mod->mod->name, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
#define CHECK_ORDER(SECTION) \
if (mod_stmt > SECTION) {LOGVAL_PARSER(ctx, LY_VCODE_INORD, ly_stmt2str(kw), ly_stmt2str(prev_kw)); return LY_EVALID;}mod_stmt = SECTION
@@ -4381,10 +4472,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "module");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, mod->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* mandatory substatements */
if (!mod->mod->ns) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "namespace", "module");
@@ -4430,7 +4520,7 @@
LY_CHECK_RET(get_argument(ctx, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
INSERT_WORD_GOTO(ctx, buf, submod->name, word, word_len, ret, cleanup);
- YANG_READ_SUBSTMT_FOR(ctx, kw, word, word_len, ret, goto checks, return ret) {
+ YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
#define CHECK_ORDER(SECTION) \
if (mod_stmt > SECTION) {LOGVAL_PARSER(ctx, LY_VCODE_INORD, ly_stmt2str(kw), ly_stmt2str(prev_kw)); return LY_EVALID;}mod_stmt = SECTION
@@ -4591,10 +4681,9 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "submodule");
return LY_EVALID;
}
+ YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, submod->exts, ret, cleanup);
}
- LY_CHECK_RET(ret);
-checks:
/* mandatory substatements */
if (!submod->prefix) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "belongs-to", "submodule");
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 1e201b0..964fdd9 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -674,7 +674,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_PATTERN, NULL, &restr->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_PATTERN, NULL, &restr->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, restr->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -719,7 +724,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_FRACTION_DIGITS, NULL, &type->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_FRACTION_DIGITS, NULL, &type->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, type->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -751,7 +761,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ENUM, NULL, &en->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ENUM, NULL, &en->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, en->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -781,7 +796,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_BIT, NULL, &en->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_BIT, NULL, &en->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, en->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -811,7 +831,9 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, value, arg_val_type, kw));
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), kw, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), kw, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -898,7 +920,12 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REQUIRE_INSTANCE, NULL, &type->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REQUIRE_INSTANCE, NULL, &type->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, type->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -940,7 +967,9 @@
modified_val[0] = LYSP_RESTR_PATTERN_NACK;
LY_CHECK_RET(lydict_insert_zc(ctx->xmlctx->ctx, modified_val, pat));
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MODIFIER, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MODIFIER, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -968,7 +997,12 @@
LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, &restr->arg.str, Y_STR_ARG, restr_kw));
restr->arg.mod = PARSER_CUR_PMOD(ctx);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), restr_kw, NULL, &restr->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), restr_kw, NULL, &restr->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, restr->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -1084,22 +1118,25 @@
static LY_ERR
yin_parse_value_pos(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, struct lysp_type_enum *enm)
{
- assert(kw == LY_STMT_POSITION || kw == LY_STMT_VALUE);
+ LY_ERR ret = LY_SUCCESS;
const char *temp_val = NULL;
char *ptr;
long long int num = 0;
unsigned long long int unum = 0;
+ assert(kw == LY_STMT_POSITION || kw == LY_STMT_VALUE);
+
/* set value flag */
enm->flags |= LYS_SET_VALUE;
/* get attribute value */
- LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, kw));
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+ LY_CHECK_GOTO(ret = yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, kw), cleanup);
if (!temp_val || (temp_val[0] == '\0') || (temp_val[0] == '+') ||
((temp_val[0] == '0') && (temp_val[1] != '\0')) || ((kw == LY_STMT_POSITION) && !strcmp(temp_val, "-0"))) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
/* convert value */
@@ -1108,23 +1145,27 @@
num = strtoll(temp_val, &ptr, LY_BASE_DEC);
if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
} else {
unum = strtoull(temp_val, &ptr, LY_BASE_DEC);
if (unum > UINT64_C(4294967295)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
}
/* check if whole argument value was converted */
if (*ptr != '\0') {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
if (errno == ERANGE) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_OOB_YIN, temp_val, "value", ly_stmt2str(kw));
- goto error;
+ ret = LY_EVALID;
+ goto cleanup;
}
/* save correctly ternary operator can't be used because num and unum have different signes */
if (kw == LY_STMT_VALUE) {
@@ -1132,18 +1173,20 @@
} else {
enm->value = unum;
}
- lydict_remove(ctx->xmlctx->ctx, temp_val);
/* parse subelements */
struct yin_subelement subelems[] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), kw, NULL, &enm->exts);
+ LY_CHECK_GOTO(ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), kw, NULL, &enm->exts), cleanup);
-error:
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_GOTO(ret = ly_set_add(&ctx->ext_inst, enm->exts, 1, NULL), cleanup);
+
+cleanup:
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return LY_EVALID;
+ return ret;
}
/**
@@ -1174,7 +1217,9 @@
}
lydict_remove(ctx->xmlctx->ctx, belongsto);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_BELONGS_TO, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_BELONGS_TO, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1203,7 +1248,9 @@
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, elem_type));
/* parse content */
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), elem_type, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), elem_type, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1227,7 +1274,9 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, LY_STMT_ERROR_MESSAGE));
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ERROR_MESSAGE, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ERROR_MESSAGE, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1279,7 +1328,12 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &type->name, Y_PREF_IDENTIF_ARG, LY_STMT_TYPE));
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_TYPE, NULL, &type->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_TYPE, NULL, &type->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, type->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -1295,6 +1349,7 @@
static LY_ERR
yin_parse_maxelements(struct lys_yin_parser_ctx *ctx, uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
{
+ LY_ERR ret = LY_SUCCESS;
const char *temp_val = NULL;
char *ptr;
unsigned long long int num;
@@ -1303,12 +1358,12 @@
};
*flags |= LYS_SET_MAX;
- LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MAX_ELEMENTS));
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+ LY_CHECK_GOTO(ret = yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MAX_ELEMENTS), cleanup);
if (!temp_val || (temp_val[0] == '\0') || (temp_val[0] == '0') || ((temp_val[0] != 'u') && !isdigit(temp_val[0]))) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "max-elements");
- lydict_remove(ctx->xmlctx->ctx, temp_val);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
if (strcmp(temp_val, "unbounded")) {
@@ -1316,18 +1371,22 @@
num = strtoull(temp_val, &ptr, LY_BASE_DEC);
if (*ptr != '\0') {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "max-elements");
- lydict_remove(ctx->xmlctx->ctx, temp_val);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
if ((errno == ERANGE) || (num > UINT32_MAX)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_OOB_YIN, temp_val, "value", "max-elements");
- lydict_remove(ctx->xmlctx->ctx, temp_val);
- return LY_EVALID;
+ ret = LY_EVALID;
+ goto cleanup;
}
*max = num;
}
+
+ LY_CHECK_GOTO(ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MAX_ELEMENTS, NULL, exts), cleanup);
+
+cleanup:
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MAX_ELEMENTS, NULL, exts);
+ return ret;
}
/**
@@ -1374,7 +1433,9 @@
}
*min = num;
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MIN_ELEMENTS, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MIN_ELEMENTS, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1454,7 +1515,9 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ORDERED_BY, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ORDERED_BY, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1492,7 +1555,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), any_kw, NULL, &any->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), any_kw, NULL, &any->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, any->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -1533,7 +1601,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_LEAF, NULL, &leaf->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_LEAF, NULL, &leaf->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, leaf->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -1578,6 +1651,9 @@
LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_LEAF_LIST, NULL, &llist->exts));
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, llist->exts, 1, NULL));
+
/* check invalid combination of subelements */
if ((llist->min) && (llist->dflts)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INCHILDSTMSCOMB_YIN, "min-elements", "default", "leaf-list");
@@ -1624,6 +1700,9 @@
LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_TYPEDEF, NULL, &tpdf->exts));
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, tpdf->exts, 1, NULL));
+
/* store data for collision check */
if (typedef_meta->parent) {
assert(ctx->main_ctx);
@@ -1669,7 +1748,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REFINE, NULL, &rf->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REFINE, NULL, &rf->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, rf->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -1709,6 +1793,9 @@
LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_USES, NULL, &uses->exts));
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, uses->exts, 1, NULL));
+
return LY_SUCCESS;
}
@@ -1747,7 +1834,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REVISION, NULL, &rev->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REVISION, NULL, &rev->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, rev->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -1785,7 +1877,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_INCLUDE, NULL, &inc->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_INCLUDE, NULL, &inc->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, inc->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -1813,7 +1910,9 @@
strcpy(rev, temp_rev);
lydict_remove(ctx->xmlctx->ctx, temp_rev);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REVISION_DATE, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_REVISION_DATE, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1847,7 +1946,9 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_CONFIG, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_CONFIG, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1881,7 +1982,9 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_version);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_YANG_VERSION, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_YANG_VERSION, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1912,6 +2015,10 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, &imp->name, Y_IDENTIF_ARG, LY_STMT_IMPORT));
LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_IMPORT, NULL, &imp->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, imp->exts, 1, NULL));
+
/* check prefix validity */
LY_CHECK_RET(lysp_check_prefix((struct lys_parser_ctx *)ctx, *imp_meta->imports, imp_meta->prefix, &imp->prefix), LY_EVALID);
@@ -1949,7 +2056,9 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MANDATORY, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_MANDATORY, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -1985,7 +2094,9 @@
}
lydict_remove(ctx->xmlctx->ctx, value);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_STATUS, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_STATUS, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -2016,7 +2127,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_WHEN, NULL, &when->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_WHEN, NULL, &when->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, when->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -2051,7 +2167,9 @@
}
lydict_remove(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_YIN_ELEMENT, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_YIN_ELEMENT, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -2074,7 +2192,9 @@
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg_meta->argument, Y_IDENTIF_ARG, LY_STMT_ARGUMENT));
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ARGUMENT, NULL, exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_ARGUMENT, NULL, exts));
+
+ return LY_SUCCESS;
}
/**
@@ -2103,7 +2223,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_EXTENSION, NULL, &ex->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_EXTENSION, NULL, &ex->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, ex->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -2135,7 +2260,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_FEATURE, NULL, &feat->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_FEATURE, NULL, &feat->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, feat->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -2168,7 +2298,12 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_IDENTITY, NULL, &ident->exts);
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_IDENTITY, NULL, &ident->exts));
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, ident->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -2226,6 +2361,9 @@
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, list->exts, 1, NULL));
+
if (list->max && (list->min > list->max)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_MINMAX, list->min, list->max);
return LY_EVALID;
@@ -2283,6 +2421,9 @@
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, notif->exts, 1, NULL));
+
return LY_SUCCESS;
}
@@ -2333,6 +2474,9 @@
ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_GROUPING, NULL, &grp->exts);
subelems_deallocator(subelems_size, subelems);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, grp->exts, 1, NULL));
+
/* store data for collision check */
if (!ret && grp->parent) {
assert(ctx->main_ctx);
@@ -2392,8 +2536,12 @@
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_CONTAINER, NULL, &cont->exts);
subelems_deallocator(subelems_size, subelems);
+ LY_CHECK_RET(ret);
- return ret;
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, cont->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -2439,8 +2587,12 @@
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_CASE, NULL, &cas->exts);
subelems_deallocator(subelems_size, subelems);
+ LY_CHECK_RET(ret);
- return ret;
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, cas->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -2490,6 +2642,11 @@
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_CHOICE, NULL, &choice->exts);
subelems_deallocator(subelems_size, subelems);
+ LY_CHECK_RET(ret);
+
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, choice->exts, 1, NULL));
+
return ret;
}
@@ -2536,6 +2693,9 @@
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, inout_meta->inout_p->exts, 1, NULL));
+
if (!inout_meta->inout_p->child) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(inout_kw));
return LY_EVALID;
@@ -2648,8 +2808,12 @@
LY_STMT_EXTENSION_INSTANCE, NULL, 0));
ret = yin_parse_content(ctx, subelems, subelems_size, LY_STMT_AUGMENT, NULL, &aug->exts);
subelems_deallocator(subelems_size, subelems);
+ LY_CHECK_RET(ret);
- return ret;
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, aug->exts, 1, NULL));
+
+ return LY_SUCCESS;
}
/**
@@ -2718,7 +2882,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d_add->exts);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d->exts);
} else if (dev_mod == LYS_DEV_REPLACE) {
d_rpl = calloc(1, sizeof *d_rpl);
@@ -2737,7 +2901,7 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d_rpl->exts);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d->exts);
} else {
d_del = calloc(1, sizeof *d_del);
@@ -2751,10 +2915,13 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d_del->exts);
+ ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATE, NULL, &d->exts);
}
LY_CHECK_GOTO(ret, cleanup);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_GOTO(ret = ly_set_add(&ctx->ext_inst, d->exts, 1, NULL), cleanup);
+
d->mod = dev_mod;
/* insert into siblings */
LY_LIST_INSERT(deviates, d, next);
@@ -2796,6 +2963,9 @@
LY_CHECK_GOTO(ret = yin_parse_content(ctx, subelems, ly_sizeofarray(subelems), LY_STMT_DEVIATION, NULL, &dev->exts), cleanup);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_GOTO(ret = ly_set_add(&ctx->ext_inst, dev->exts, 1, NULL), cleanup);
+
cleanup:
if (ret) {
lysp_deviation_free(&fctx, dev);
@@ -3578,7 +3748,7 @@
LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
- /* mandatory subelemnts are checked only after whole element was succesfully parsed */
+ /* mandatory subelements are checked only after whole element was succesfully parsed */
LY_CHECK_RET(yin_check_subelem_mandatory_constraint(ctx, subelem_info, subelem_info_size, current_element));
cleanup:
@@ -3638,6 +3808,9 @@
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, mod->exts, 1, NULL));
+
/* submodules share the namespace with the module names, so there must not be
* a submodule of the same name in the context, no need for revision matching */
dup = ly_ctx_get_submodule_latest(ctx->xmlctx->ctx, mod->mod->name);
@@ -3702,6 +3875,9 @@
subelems_deallocator(subelems_size, subelems);
LY_CHECK_RET(ret);
+ /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+ LY_CHECK_RET(ly_set_add(&ctx->ext_inst, submod->exts, 1, NULL));
+
/* submodules share the namespace with the module names, so there must not be
* a submodule of the same name in the context, no need for revision matching */
dup = ly_ctx_get_submodule_latest(ctx->xmlctx->ctx, submod->name);
diff --git a/src/plugins.c b/src/plugins.c
index 28fcd0e..d62da1c 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -147,8 +147,8 @@
return plugins->objs[*index - 1];
}
-void *
-lyplg_find(enum LYPLG type, const char *module, const char *revision, const char *name)
+static void *
+lyplg_record_find(enum LYPLG type, const char *module, const char *revision, const char *name)
{
uint32_t i = 0;
struct lyplg_record *item;
@@ -164,13 +164,28 @@
continue;
}
- return &item->plugin;
+ return item;
}
}
return NULL;
}
+struct lyplg_type *
+lyplg_type_plugin_find(const char *module, const char *revision, const char *name)
+{
+ struct lyplg_record *record;
+
+ record = lyplg_record_find(LYPLG_TYPE, module, revision, name);
+ return record ? &((struct lyplg_type_record *)record)->plugin : NULL;
+}
+
+struct lyplg_ext_record *
+lyplg_ext_record_find(const char *module, const char *revision, const char *name)
+{
+ return lyplg_record_find(LYPLG_EXTENSION, module, revision, name);
+}
+
/**
* @brief Insert the provided extension plugin records into the internal set of extension plugins for use by libyang.
*
diff --git a/src/plugins_exts/metadata.h b/src/plugins_exts/metadata.h
index 56d5cb6..f9dbd12 100644
--- a/src/plugins_exts/metadata.h
+++ b/src/plugins_exts/metadata.h
@@ -26,8 +26,6 @@
#define ANNOTATION_SUBSTMT_DSC 4 /**< index for the LY_STMT_DSC substatement in annotation's ::lysc_ext_instance.substmts */
#define ANNOTATION_SUBSTMT_REF 5 /**< index for the LY_STMT_REF substatement in annotation's ::lysc_ext_instance.substmts */
-#define LYEXT_PLUGIN_INTERNAL_ANNOTATION "ietf-yang-metadata", "2016-08-05", "annotation"
-
#ifdef __cplusplus
}
#endif
diff --git a/src/plugins_internal.h b/src/plugins_internal.h
index 2a95e86..d13db16 100644
--- a/src/plugins_internal.h
+++ b/src/plugins_internal.h
@@ -1,9 +1,10 @@
/**
* @file plugins_internal.h
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief internal functions to support extension and type plugins.
*
- * Copyright (c) 2019-2021 CESNET, z.s.p.o.
+ * Copyright (c) 2019-2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -59,17 +60,26 @@
void lyplg_clean(void);
/**
- * @brief Find the plugin matching the provided attributes.
+ * @brief Find a type plugin.
*
- * @param[in] type Type of the plugin to find (type or extension)
- * @param[in] module Name of the module where the type/extension is defined. Must not be NULL, in case of plugins for
+ * @param[in] module Name of the module where the type is defined. Must not be NULL, in case of plugins for
* built-in types, the module is "".
- * @param[in] revision The revision of the module for which the plugin is implemented. NULL is not a wildcard, it matches
+ * @param[in] revision Revision of the module for which the plugin is implemented. NULL is not a wildcard, it matches
* only the plugins with NULL revision specified.
- * @param[in] name Name of the type/extension which the plugin implements.
- * @return NULL if the plugin matching the restrictions is not present.
- * @return Pointer to the matching ::lyplg_ext or ::lyplg_type according to the plugin's @p type.
+ * @param[in] name Name of the type which the plugin implements.
+ * @return Found type plugin, NULL if none found.
*/
-void *lyplg_find(enum LYPLG type, const char *module, const char *revision, const char *name);
+struct lyplg_type *lyplg_type_plugin_find(const char *module, const char *revision, const char *name);
+
+/**
+ * @brief Find an extension plugin.
+ *
+ * @param[in] module Name of the module where the extension is defined.
+ * @param[in] revision Revision of the module for which the plugin is implemented. NULL is not a wildcard, it matches
+ * only the plugins with NULL revision specified.
+ * @param[in] name Name of the extension which the plugin implements.
+ * @return Found extension record, NULL if none found.
+ */
+struct lyplg_ext_record *lyplg_ext_record_find(const char *module, const char *revision, const char *name);
#endif /* LY_PLUGINS_INTERNAL_H_ */
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 8eb550f..3fdb37d 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -52,7 +52,8 @@
* @brief Fill in the prepared compiled extensions definition structure according to the parsed extension definition.
*/
static LY_ERR
-lys_compile_extension(struct lysc_ctx *ctx, const struct lys_module *ext_mod, struct lysp_ext *ext_p, struct lysc_ext **ext)
+lys_compile_extension(struct lysc_ctx *ctx, const struct lys_module *ext_mod, struct lysp_ext *ext_p,
+ const struct lyplg_ext_record *record, struct lysc_ext **ext)
{
LY_ERR ret = LY_SUCCESS;
@@ -74,8 +75,7 @@
lysc_update_path(ctx, NULL, NULL);
/* find extension definition plugin */
- (*ext)->plugin = lyplg_find(LYPLG_EXTENSION, (*ext)->module->name,
- (*ext)->module->revision, (*ext)->name);
+ (*ext)->plugin = record ? (struct lyplg_ext *)&record->plugin : NULL;
}
*ext = ext_p->compiled;
@@ -104,7 +104,7 @@
lysc_update_path(ctx, NULL, ext_p->name);
LY_CHECK_GOTO(ret = lysp_ext_find_definition(ctx->ctx, ext_p, &ext_mod, &ext_def), cleanup);
- LY_CHECK_GOTO(ret = lys_compile_extension(ctx, ext_mod, ext_def, &ext->def), cleanup);
+ LY_CHECK_GOTO(ret = lys_compile_extension(ctx, ext_mod, ext_def, ext_p->record, &ext->def), cleanup);
if (ext_def->argname) {
LY_CHECK_GOTO(ret = lysp_ext_instance_resolve_argument(ctx->ctx, ext_p, ext_def), cleanup);
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 10bcd22..a935907 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -2130,7 +2130,7 @@
}
/* try to find loaded user type plugins */
- plugin = lyplg_find(LYPLG_TYPE, tctx->tpdf->type.pmod->mod->name, tctx->tpdf->type.pmod->mod->revision,
+ plugin = lyplg_type_plugin_find(tctx->tpdf->type.pmod->mod->name, tctx->tpdf->type.pmod->mod->revision,
tctx->tpdf->name);
if (!plugin && base) {
/* use the base type implementation if available */
@@ -2138,7 +2138,7 @@
}
if (!plugin) {
/* use the internal built-in type implementation */
- plugin = lyplg_find(LYPLG_TYPE, "", NULL, ly_data_type2str[basetype]);
+ plugin = lyplg_type_plugin_find("", NULL, ly_data_type2str[basetype]);
}
assert(plugin);
@@ -2184,7 +2184,7 @@
if (type_p->flags || !base || (basetype == LY_TYPE_LEAFREF)) {
/* get restrictions from the node itself */
(*type)->basetype = basetype;
- (*type)->plugin = base ? base->plugin : lyplg_find(LYPLG_TYPE, "", NULL, ly_data_type2str[basetype]);
+ (*type)->plugin = base ? base->plugin : lyplg_type_plugin_find("", NULL, ly_data_type2str[basetype]);
LY_ATOMIC_INC_BARRIER((*type)->refcount);
ret = lys_compile_type_(ctx, context_pnode, context_flags, context_name, type_p, basetype, NULL, base, type);
LY_CHECK_GOTO(ret, cleanup);
diff --git a/src/tree_data.c b/src/tree_data.c
index a40d4c4..e416ea0 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -958,7 +958,7 @@
assert((parent || meta) && mod);
LY_ARRAY_FOR(mod->compiled->exts, u) {
- if ((mod->compiled->exts[u].def->plugin == lyplg_find(LYPLG_EXTENSION, LYEXT_PLUGIN_INTERNAL_ANNOTATION)) &&
+ if (!strncmp(mod->compiled->exts[u].def->plugin->id, "libyang 2 - metadata", 20) &&
!ly_strncmp(mod->compiled->exts[u].argument, name, name_len)) {
/* we have the annotation definition */
ant = &mod->compiled->exts[u];
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 000c115..b0be387 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -37,6 +37,7 @@
#include "parser_internal.h"
#include "parser_schema.h"
#include "path.h"
+#include "plugins_internal.h"
#include "schema_compile.h"
#include "schema_compile_amend.h"
#include "schema_features.h"
@@ -1250,8 +1251,16 @@
return ret;
}
+/**
+ * @brief Resolve (find) all imported and included modules.
+ *
+ * @param[in] pctx Parser context.
+ * @param[in] pmod Parsed module to resolve.
+ * @param[out] new_mods Set with all the newly loaded modules.
+ * @return LY_ERR value.
+ */
static LY_ERR
-lys_resolve_import_include(struct lys_parser_ctx *pctx, struct lysp_module *pmod, struct ly_set *new_mods)
+lysp_resolve_import_include(struct lys_parser_ctx *pctx, struct lysp_module *pmod, struct ly_set *new_mods)
{
struct lysp_import *imp;
LY_ARRAY_COUNT_TYPE u, v;
@@ -1284,6 +1293,45 @@
return LY_SUCCESS;
}
+/**
+ * @brief Resolve (find) all extension instance records and finish their parsing.
+ *
+ * @param[in] pctx Parse context with all the parsed extension instances.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lysp_resolve_ext_instance_records(struct lys_parser_ctx *pctx)
+{
+ struct lysp_ext_instance *exts, *ext;
+ const struct lys_module *mod;
+ const char *ptr;
+ uint32_t i;
+ LY_ARRAY_COUNT_TYPE u;
+
+ for (i = 0; i < pctx->ext_inst.count; ++i) {
+ exts = pctx->ext_inst.objs[i];
+ LY_ARRAY_FOR(exts, u) {
+ ext = &exts[u];
+
+ /* find the extension (definition) module */
+ ptr = strchr(ext->name, ':');
+ assert(ptr);
+ mod = ly_resolve_prefix(PARSER_CTX(pctx), ext->name, ptr - ext->name, ext->format, ext->prefix_data);
+ if (!mod) {
+ LOGVAL(PARSER_CTX(pctx), LYVE_SYNTAX, "Unknown prefix \"%*.s\" used for an extension instance.",
+ (int)(ptr - ext->name), ext->name);
+ return LY_ENOTFOUND;
+ }
+
+ /* find the extension record, if any */
+ ++ptr;
+ ext->record = lyplg_ext_record_find(mod->name, mod->revision, ptr);
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
LY_ERR
lys_parse_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
LY_ERR (*custom_check)(const struct ly_ctx *, struct lysp_module *, struct lysp_submodule *, void *),
@@ -1350,7 +1398,10 @@
lys_parser_fill_filepath(ctx, in, &submod->filepath);
/* resolve imports and includes */
- LY_CHECK_GOTO(ret = lys_resolve_import_include(pctx, (struct lysp_module *)submod, new_mods), error);
+ LY_CHECK_GOTO(ret = lysp_resolve_import_include(pctx, (struct lysp_module *)submod, new_mods), error);
+
+ /* resolve extension instance plugin records */
+ LY_CHECK_GOTO(ret = lysp_resolve_ext_instance_records(pctx), error);
if (format == LYS_IN_YANG) {
yang_parser_ctx_free(yangctx);
@@ -1383,7 +1434,7 @@
* @return LY_ERR on error.
*/
static LY_ERR
-lys_parsed_add_internal_ietf_netconf(struct lysp_module *mod)
+lysp_add_internal_ietf_netconf(struct lysp_module *mod)
{
struct lysp_ext_instance *ext_p;
struct lysp_stmt *stmt;
@@ -1551,7 +1602,7 @@
* @return LY_ERR on error.
*/
static LY_ERR
-lys_parsed_add_internal_ietf_netconf_with_defaults(struct lysp_module *mod)
+lysp_add_internal_ietf_netconf_with_defaults(struct lysp_module *mod)
{
struct lysp_ext_instance *ext_p;
struct lysp_stmt *stmt;
@@ -1724,9 +1775,9 @@
/* add internal data in case specific modules were parsed */
if (!strcmp(mod->name, "ietf-netconf")) {
- LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf(mod->parsed), cleanup);
+ LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf(mod->parsed), cleanup);
} else if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
- LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf_with_defaults(mod->parsed), cleanup);
+ LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf_with_defaults(mod->parsed), cleanup);
}
/* add the module into newly created module set, will also be freed from there on any error */
@@ -1739,7 +1790,10 @@
ctx->change_count++;
/* resolve includes and all imports */
- LY_CHECK_GOTO(ret = lys_resolve_import_include(pctx, mod->parsed, new_mods), cleanup);
+ LY_CHECK_GOTO(ret = lysp_resolve_import_include(pctx, mod->parsed, new_mods), cleanup);
+
+ /* resolve extension instance plugin records */
+ LY_CHECK_GOTO(ret = lysp_resolve_ext_instance_records(pctx), cleanup);
/* check name collisions */
LY_CHECK_GOTO(ret = lysp_check_dup_typedefs(pctx, mod->parsed), cleanup);
@@ -1753,8 +1807,6 @@
/* compile identities */
LY_CHECK_GOTO(ret = lys_compile_identities(mod), cleanup);
- /* success */
-
cleanup:
if (ret && (ret != LY_EEXIST)) {
if (mod && mod->name) {
diff --git a/src/tree_schema.h b/src/tree_schema.h
index c6d9eec..f23c6fb 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -546,6 +546,7 @@
LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< in case the instance is in a substatement, this identifies
the index of that substatement in its [sized array](@ref sizedarrays) (if any) */
uint16_t flags; /**< LYS_INTERNAL value (@ref snodeflags) */
+ const struct lyplg_ext_record *record; /**< extension defintion plugin record, if any */
};
/**
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 34f1a22..77f9751 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -1496,6 +1496,7 @@
ly_set_erase(&ctx->grps_nodes, NULL);
}
assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
+ ly_set_erase(&ctx->ext_inst, NULL);
ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
if (!ctx->parsed_mods->count) {
ly_set_free(ctx->parsed_mods, NULL);
@@ -1513,6 +1514,7 @@
ly_set_erase(&ctx->grps_nodes, NULL);
}
assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
+ ly_set_erase(&ctx->ext_inst, NULL);
ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
if (!ctx->parsed_mods->count) {
ly_set_free(ctx->parsed_mods, NULL);
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index e90920a..e16f815 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -149,6 +149,7 @@
submodule, use ::lys_parser_ctx.main_ctx instead. */
struct ly_set grps_nodes; /**< Set of nodes that contain grouping(s). Invalid in case of
submodule, use ::lys_parser_ctx.main_ctx instead. */
+ struct ly_set ext_inst; /**< parsed extension instances to finish parsing */
struct ly_set *parsed_mods; /**< (sub)modules being parsed, the last one is the current */
struct lys_parser_ctx *main_ctx; /**< This pointer must not be NULL. If this context deals with the submodule,
then should be set to the context of the module to which it belongs,
@@ -164,6 +165,7 @@
submodule, use ::lys_parser_ctx.main_ctx instead. */
struct ly_set grps_nodes; /**< Set of nodes that contain grouping(s). Invalid in case of
submodule, use ::lys_parser_ctx.main_ctx instead. */
+ struct ly_set ext_inst; /**< parsed extension instances to finish parsing */
struct ly_set *parsed_mods; /**< (sub)modules being parsed, the last one is the current */
struct lys_parser_ctx *main_ctx; /**< This pointer must not be NULL. If this context deals with the submodule,
then should be set to the context of the module to which it belongs,
@@ -182,6 +184,7 @@
submodule, use ::lys_parser_ctx.main_ctx instead. */
struct ly_set grps_nodes; /**< Set of nodes that contain grouping(s). Invalid in case of
submodule, use ::lys_parser_ctx.main_ctx instead. */
+ struct ly_set ext_inst; /**< parsed extension instances to finish parsing */
struct ly_set *parsed_mods; /**< (sub)modules being parsed, the last one is the current */
struct lys_parser_ctx *main_ctx; /**< This pointer must not be NULL. If this context deals with the submodule,
then should be set to the context of the module to which it belongs,