blob: 3a185374edff529d2de128036f77392fca6cf724 [file] [log] [blame]
Michal Vasko7fbc8162018-09-17 10:35:16 +02001/**
2 * @file parser_yang.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief YANG parser
5 *
6 * Copyright (c) 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
Michal Vasko63f3d842020-07-08 10:10:14 +020014#include "parser_internal.h"
Michal Vasko7fbc8162018-09-17 10:35:16 +020015
Radek Krejcie7b95092019-05-15 11:03:07 +020016#include <assert.h>
17#include <ctype.h>
18#include <errno.h>
19#include <stdint.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
Radek Krejci535ea9f2020-05-29 16:01:05 +020024#include "common.h"
Michal Vasko7fbc8162018-09-17 10:35:16 +020025#include "context.h"
Radek Krejcie7b95092019-05-15 11:03:07 +020026#include "dict.h"
Radek Krejcie7b95092019-05-15 11:03:07 +020027#include "log.h"
Michal Vasko004d3152020-06-11 19:59:22 +020028#include "path.h"
Radek Krejcica376bd2020-06-11 16:04:06 +020029#include "parser_schema.h"
Radek Krejcie7b95092019-05-15 11:03:07 +020030#include "set.h"
31#include "tree.h"
32#include "tree_schema.h"
Radek Krejci70853c52018-10-15 14:46:16 +020033#include "tree_schema_internal.h"
Radek Krejci44ceedc2018-10-02 15:54:31 +020034
Radek Krejciceaf2122019-01-02 15:03:26 +010035/**
36 * @brief Insert WORD into the libyang context's dictionary and store as TARGET.
37 * @param[in] CTX yang parser context to access libyang context.
38 * @param[in] BUF buffer in case the word is not a constant and can be inserted directly (zero-copy)
39 * @param[out] TARGET variable where to store the pointer to the inserted value.
40 * @param[in] WORD string to store.
41 * @param[in] LEN length of the string in WORD to store.
42 */
Radek Krejci9fcacc12018-10-11 15:59:11 +020043#define INSERT_WORD(CTX, BUF, TARGET, WORD, LEN) \
44 if (BUF) {(TARGET) = lydict_insert_zc((CTX)->ctx, WORD);}\
Radek Krejcif09e4e82019-06-14 15:08:11 +020045 else {(TARGET) = lydict_insert((CTX)->ctx, LEN ? WORD : "", LEN);}
Radek Krejci44ceedc2018-10-02 15:54:31 +020046
Radek Krejciceaf2122019-01-02 15:03:26 +010047/**
Michal Vasko63f3d842020-07-08 10:10:14 +020048 * @brief Read from the IN structure COUNT items. Also updates the indent value in yang parser context
Radek Krejciceaf2122019-01-02 15:03:26 +010049 * @param[in] CTX yang parser context to update its indent value.
Michal Vasko63f3d842020-07-08 10:10:14 +020050 * @param[in,out] IN input structure
Radek Krejciceaf2122019-01-02 15:03:26 +010051 * @param[in] COUNT number of items for which the DATA pointer is supposed to move on.
52 */
Michal Vasko63f3d842020-07-08 10:10:14 +020053#define MOVE_INPUT(CTX, IN, COUNT) ly_in_skip(IN, COUNT);(CTX)->indent+=COUNT
Radek Krejcid5f2b5f2018-10-11 10:54:36 +020054
Michal Vaskoea5abea2018-09-18 13:10:54 +020055/**
56 * @brief Loop through all substatements providing, return if there are none.
57 *
Radek Krejci44ceedc2018-10-02 15:54:31 +020058 * @param[in] CTX yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +020059 * @param[in] IN Input structure to read from.
Michal Vaskoea5abea2018-09-18 13:10:54 +020060 * @param[out] KW YANG keyword read.
61 * @param[out] WORD Pointer to the keyword itself.
62 * @param[out] WORD_LEN Length of the keyword.
63 * @param[out] ERR Variable for error storing.
64 *
65 * @return In case there are no substatements or a fatal error encountered.
66 */
Michal Vasko63f3d842020-07-08 10:10:14 +020067#define YANG_READ_SUBSTMT_FOR(CTX, IN, KW, WORD, WORD_LEN, ERR, CHECKGOTO) \
68 LY_CHECK_RET(get_keyword(CTX, IN, &KW, &WORD, &WORD_LEN)); \
Radek Krejcid6b76452019-09-03 17:03:03 +020069 if (KW == LY_STMT_SYNTAX_SEMICOLON) { \
Radek Krejci6d6556c2018-11-08 09:37:45 +010070 CHECKGOTO; \
Radek Krejci6d9b9b52018-11-02 12:43:39 +010071 return LY_SUCCESS; \
Michal Vasko7fbc8162018-09-17 10:35:16 +020072 } \
Radek Krejcid6b76452019-09-03 17:03:03 +020073 if (KW != LY_STMT_SYNTAX_LEFT_BRACE) { \
David Sedlákb3077192019-06-19 10:55:37 +020074 LOGVAL_PARSER(CTX, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\", expected \";\" or \"{\".", ly_stmt2str(KW)); \
Michal Vasko7fbc8162018-09-17 10:35:16 +020075 return LY_EVALID; \
76 } \
Michal Vasko63f3d842020-07-08 10:10:14 +020077 for (ERR = get_keyword(CTX, IN, &KW, &WORD, &WORD_LEN); \
Radek Krejcid6b76452019-09-03 17:03:03 +020078 !ERR && (KW != LY_STMT_SYNTAX_RIGHT_BRACE); \
Michal Vasko63f3d842020-07-08 10:10:14 +020079 ERR = get_keyword(CTX, IN, &KW, &WORD, &WORD_LEN))
Michal Vasko7fbc8162018-09-17 10:35:16 +020080
Michal Vasko63f3d842020-07-08 10:10:14 +020081LY_ERR parse_container(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent,
Radek Krejci0f969882020-08-21 16:56:47 +020082 struct lysp_node **siblings);
Michal Vasko63f3d842020-07-08 10:10:14 +020083LY_ERR parse_uses(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings);
84LY_ERR parse_choice(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings);
85LY_ERR parse_case(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings);
86LY_ERR parse_list(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings);
87LY_ERR parse_grouping(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_grp **groupings);
Michal Vasko7fbc8162018-09-17 10:35:16 +020088
Michal Vaskoea5abea2018-09-18 13:10:54 +020089/**
90 * @brief Add another character to dynamic buffer, a low-level function.
91 *
Radek Krejci44ceedc2018-10-02 15:54:31 +020092 * Enlarge if needed. Updates \p input as well as \p buf_used.
Michal Vaskoea5abea2018-09-18 13:10:54 +020093 *
Radek Krejci404251e2018-10-09 12:06:44 +020094 * @param[in] ctx libyang context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +020095 * @param[in,out] in Input structure.
Radek Krejci44ceedc2018-10-02 15:54:31 +020096 * @param[in] len Number of bytes to get from the input string and copy into the buffer.
Michal Vaskoea5abea2018-09-18 13:10:54 +020097 * @param[in,out] buf Buffer to use, can be moved by realloc().
98 * @param[in,out] buf_len Current size of the buffer.
Radek Krejci44ceedc2018-10-02 15:54:31 +020099 * @param[in,out] buf_used Currently used characters of the buffer.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200100 *
101 * @return LY_ERR values.
102 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200103LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200104buf_add_char(struct ly_ctx *ctx, struct ly_in *in, size_t len, char **buf, size_t *buf_len, size_t *buf_used)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200105{
Radek Krejci44ceedc2018-10-02 15:54:31 +0200106 if (*buf_len <= (*buf_used) + len) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200107 *buf_len += 16;
108 *buf = ly_realloc(*buf, *buf_len);
109 LY_CHECK_ERR_RET(!*buf, LOGMEM(ctx), LY_EMEM);
110 }
Radek Krejcic0917392019-04-10 13:04:04 +0200111 if (*buf_used) {
Michal Vasko63f3d842020-07-08 10:10:14 +0200112 ly_in_read(in, &(*buf)[*buf_used], len);
Radek Krejcic0917392019-04-10 13:04:04 +0200113 } else {
Michal Vasko63f3d842020-07-08 10:10:14 +0200114 ly_in_read(in, *buf, len);
Radek Krejcic0917392019-04-10 13:04:04 +0200115 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200116
Radek Krejci44ceedc2018-10-02 15:54:31 +0200117 (*buf_used) += len;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200118 return LY_SUCCESS;
119}
120
Michal Vaskoea5abea2018-09-18 13:10:54 +0200121/**
Radek Krejci44ceedc2018-10-02 15:54:31 +0200122 * @brief Store a single UTF8 character. It depends whether in a dynamically-allocated buffer or just as a pointer to the data.
123 *
124 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200125 * @param[in,out] in Input structure.
Radek Krejci44ceedc2018-10-02 15:54:31 +0200126 * @param[in] arg Type of the input string to select method of checking character validity.
127 * @param[in,out] word_p Word pointer. If buffer (\p word_b) was not yet needed, it is just a pointer to the first
Michal Vaskoea5abea2018-09-18 13:10:54 +0200128 * stored character. If buffer was needed (\p word_b is non-NULL or \p need_buf is set), it is pointing to the buffer.
Radek Krejci44ceedc2018-10-02 15:54:31 +0200129 * @param[in,out] word_len Current length of the word pointed to by \p word_p.
130 * @param[in,out] word_b Word buffer. Is kept NULL as long as it is not requested (word is a substring of the data).
Michal Vaskoea5abea2018-09-18 13:10:54 +0200131 * @param[in,out] buf_len Current length of \p word_b.
Radek Krejci44ceedc2018-10-02 15:54:31 +0200132 * @param[in] need_buf Flag if the dynamically allocated buffer is required.
David Sedlák40bb13b2019-07-10 14:34:18 +0200133 * @param[in,out] prefix Storage for internally used flag in case of possible prefixed identifiers:
134 * 0 - colon not yet found (no prefix)
135 * 1 - \p c is the colon character
136 * 2 - prefix already processed, now processing the identifier
Michal Vaskoea5abea2018-09-18 13:10:54 +0200137 *
138 * @return LY_ERR values.
139 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200140LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200141buf_store_char(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum yang_arg arg, char **word_p, size_t *word_len,
Radek Krejci1deb5be2020-08-26 16:43:36 +0200142 char **word_b, size_t *buf_len, uint8_t need_buf, uint8_t *prefix)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200143{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200144 uint32_t c;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200145 size_t len;
146
Radek Krejcif29b7c32019-04-09 16:17:49 +0200147 /* check valid combination of input paremeters - if need_buf specified, word_b must be provided */
148 assert(!need_buf || (need_buf && word_b));
149
Radek Krejci44ceedc2018-10-02 15:54:31 +0200150 /* get UTF8 code point (and number of bytes coding the character) */
Michal Vasko63f3d842020-07-08 10:10:14 +0200151 LY_CHECK_ERR_RET(ly_getutf8(&in->current, &c, &len),
152 LOGVAL_PARSER(ctx, LY_VCODE_INCHAR, in->current[-len]), LY_EVALID);
153 in->current -= len;
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200154 if (c == '\n') {
155 ctx->indent = 0;
156 } else {
157 /* note - even the multibyte character is count as 1 */
158 ++ctx->indent;
159 }
160
Radek Krejci44ceedc2018-10-02 15:54:31 +0200161 /* check character validity */
162 switch (arg) {
163 case Y_IDENTIF_ARG:
Michal Vaskob36053d2020-03-26 15:49:30 +0100164 LY_CHECK_RET(lysp_check_identifierchar((struct lys_parser_ctx *)ctx, c, !(*word_len), NULL));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200165 break;
166 case Y_PREF_IDENTIF_ARG:
Michal Vaskob36053d2020-03-26 15:49:30 +0100167 LY_CHECK_RET(lysp_check_identifierchar((struct lys_parser_ctx *)ctx, c, !(*word_len), prefix));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200168 break;
169 case Y_STR_ARG:
170 case Y_MAYBE_STR_ARG:
Michal Vaskob36053d2020-03-26 15:49:30 +0100171 LY_CHECK_RET(lysp_check_stringchar((struct lys_parser_ctx *)ctx, c));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200172 break;
173 }
174
Michal Vasko7fbc8162018-09-17 10:35:16 +0200175 if (word_b && *word_b) {
176 /* add another character into buffer */
Michal Vasko63f3d842020-07-08 10:10:14 +0200177 if (buf_add_char(ctx->ctx, in, len, word_b, buf_len, word_len)) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200178 return LY_EMEM;
179 }
180
181 /* in case of realloc */
182 *word_p = *word_b;
Radek Krejcif29b7c32019-04-09 16:17:49 +0200183 } else if (word_b && need_buf) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200184 /* first time we need a buffer, copy everything read up to now */
185 if (*word_len) {
186 *word_b = malloc(*word_len);
Radek Krejci44ceedc2018-10-02 15:54:31 +0200187 LY_CHECK_ERR_RET(!*word_b, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200188 *buf_len = *word_len;
189 memcpy(*word_b, *word_p, *word_len);
190 }
191
192 /* add this new character into buffer */
Michal Vasko63f3d842020-07-08 10:10:14 +0200193 if (buf_add_char(ctx->ctx, in, len, word_b, buf_len, word_len)) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200194 return LY_EMEM;
195 }
196
197 /* in case of realloc */
198 *word_p = *word_b;
199 } else {
200 /* just remember the first character pointer */
201 if (!*word_p) {
Michal Vasko63f3d842020-07-08 10:10:14 +0200202 *word_p = (char *)in->current;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200203 }
Radek Krejci44ceedc2018-10-02 15:54:31 +0200204 /* ... and update the word's length */
205 (*word_len) += len;
Michal Vasko63f3d842020-07-08 10:10:14 +0200206 ly_in_skip(in, len);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200207 }
208
209 return LY_SUCCESS;
210}
211
Michal Vaskoea5abea2018-09-18 13:10:54 +0200212/**
213 * @brief Skip YANG comment in data.
214 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200215 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200216 * @param[in,out] in Input structure.
Radek Krejci44ceedc2018-10-02 15:54:31 +0200217 * @param[in] comment Type of the comment to process:
218 * 1 for a one-line comment,
219 * 2 for a block comment.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200220 * @return LY_ERR values.
221 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200222LY_ERR
Radek Krejci1deb5be2020-08-26 16:43:36 +0200223skip_comment(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint8_t comment)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200224{
Radek Krejci80dd33e2018-09-26 15:57:18 +0200225 /* internal statuses: 0 - comment ended,
226 * 1 - in line comment,
227 * 2 - in block comment,
228 * 3 - in block comment with last read character '*'
229 */
Michal Vasko63f3d842020-07-08 10:10:14 +0200230 while (in->current[0] && comment) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200231 switch (comment) {
232 case 1:
Michal Vasko63f3d842020-07-08 10:10:14 +0200233 if (in->current[0] == '\n') {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200234 comment = 0;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200235 ++ctx->line;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200236 }
237 break;
238 case 2:
Michal Vasko63f3d842020-07-08 10:10:14 +0200239 if (in->current[0] == '*') {
Radek Krejci15c80ca2018-10-09 11:01:31 +0200240 comment = 3;
Michal Vasko63f3d842020-07-08 10:10:14 +0200241 } else if (in->current[0] == '\n') {
Radek Krejci15c80ca2018-10-09 11:01:31 +0200242 ++ctx->line;
243 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200244 break;
245 case 3:
Michal Vasko63f3d842020-07-08 10:10:14 +0200246 if (in->current[0] == '/') {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200247 comment = 0;
Michal Vasko63f3d842020-07-08 10:10:14 +0200248 } else if (in->current[0] != '*') {
249 if (in->current[0] == '\n') {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200250 ++ctx->line;
251 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200252 comment = 2;
253 }
254 break;
255 default:
Radek Krejci44ceedc2018-10-02 15:54:31 +0200256 LOGINT_RET(ctx->ctx);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200257 }
258
Michal Vasko63f3d842020-07-08 10:10:14 +0200259 if (in->current[0] == '\n') {
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200260 ctx->indent = 0;
261 } else {
262 ++ctx->indent;
263 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200264 ++in->current;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200265 }
266
Michal Vasko63f3d842020-07-08 10:10:14 +0200267 if (!in->current[0] && (comment > 1)) {
David Sedlákb3077192019-06-19 10:55:37 +0200268 LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Unexpected end-of-input, non-terminated comment.");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200269 return LY_EVALID;
270 }
271
272 return LY_SUCCESS;
273}
274
Michal Vaskoea5abea2018-09-18 13:10:54 +0200275/**
276 * @brief Read a quoted string from data.
277 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200278 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200279 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200280 * @param[in] arg Type of YANG keyword argument expected.
281 * @param[out] word_p Pointer to the read quoted string.
282 * @param[out] word_b Pointer to a dynamically-allocated buffer holding the read quoted string. If not needed,
283 * set to NULL. Otherwise equal to \p word_p.
284 * @param[out] word_len Length of the read quoted string.
285 * @param[out] buf_len Length of the dynamically-allocated buffer \p word_b.
286 * @param[in] indent Current indent (number of YANG spaces). Needed for correct multi-line string
287 * indenation in the final quoted string.
288 *
289 * @return LY_ERR values.
290 */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200291static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200292read_qstring(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum yang_arg arg, char **word_p, char **word_b,
Radek Krejci0f969882020-08-21 16:56:47 +0200293 size_t *word_len, size_t *buf_len)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200294{
295 /* string: 0 - string ended, 1 - string with ', 2 - string with ", 3 - string with " with last character \,
296 * 4 - string finished, now skipping whitespaces looking for +,
297 * 5 - string continues after +, skipping whitespaces */
Radek Krejci1deb5be2020-08-26 16:43:36 +0200298 uint8_t string;
299 uint64_t block_indent = 0, current_indent = 0;
300 uint8_t need_buf = 0, prefix = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200301 const char *c;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200302 uint64_t trailing_ws = 0; /* current number of stored trailing whitespace characters */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200303
Michal Vasko63f3d842020-07-08 10:10:14 +0200304 if (in->current[0] == '\"') {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200305 string = 2;
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200306 current_indent = block_indent = ctx->indent + 1;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200307 } else {
Michal Vasko63f3d842020-07-08 10:10:14 +0200308 assert(in->current[0] == '\'');
Michal Vasko7fbc8162018-09-17 10:35:16 +0200309 string = 1;
310 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200311 MOVE_INPUT(ctx, in, 1);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200312
Michal Vasko63f3d842020-07-08 10:10:14 +0200313 while (in->current[0] && string) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200314 switch (string) {
315 case 1:
Michal Vasko63f3d842020-07-08 10:10:14 +0200316 switch (in->current[0]) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200317 case '\'':
318 /* string may be finished, but check for + */
319 string = 4;
Michal Vasko63f3d842020-07-08 10:10:14 +0200320 MOVE_INPUT(ctx, in, 1);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200321 break;
322 default:
323 /* check and store character */
Michal Vasko63f3d842020-07-08 10:10:14 +0200324 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200325 break;
326 }
327 break;
328 case 2:
Michal Vasko63f3d842020-07-08 10:10:14 +0200329 switch (in->current[0]) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200330 case '\"':
331 /* string may be finished, but check for + */
332 string = 4;
Michal Vasko63f3d842020-07-08 10:10:14 +0200333 MOVE_INPUT(ctx, in, 1);
Radek Krejciff13cd12019-10-25 15:34:24 +0200334 trailing_ws = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200335 break;
336 case '\\':
337 /* special character following */
338 string = 3;
Radek Krejciff13cd12019-10-25 15:34:24 +0200339
340 /* the backslash sequence is substituted, so we will need a buffer to store the result */
341 need_buf = 1;
342
343 /* move forward to the escaped character */
Michal Vasko63f3d842020-07-08 10:10:14 +0200344 ++in->current;
Radek Krejciff13cd12019-10-25 15:34:24 +0200345
346 /* note that the trailing whitespaces are supposed to be trimmed before substitution of
347 * backslash-escaped characters (RFC 7950, 6.1.3), so we have to zero the trailing whitespaces counter */
348 trailing_ws = 0;
349
350 /* since the backslash-escaped character is handled as first non-whitespace character, stop eating indentation */
351 current_indent = block_indent;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200352 break;
353 case ' ':
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200354 if (current_indent < block_indent) {
355 ++current_indent;
Michal Vasko63f3d842020-07-08 10:10:14 +0200356 MOVE_INPUT(ctx, in, 1);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200357 } else {
Michal Vasko90edde42019-11-25 15:25:07 +0100358 /* check and store whitespace character */
Michal Vasko63f3d842020-07-08 10:10:14 +0200359 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
Michal Vasko90edde42019-11-25 15:25:07 +0100360 trailing_ws++;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200361 }
362 break;
363 case '\t':
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200364 if (current_indent < block_indent) {
365 assert(need_buf);
366 current_indent += 8;
367 ctx->indent += 8;
Michal Vaskod989ba02020-08-24 10:59:24 +0200368 for ( ; current_indent > block_indent; --current_indent, --ctx->indent) {
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200369 /* store leftover spaces from the tab */
Michal Vasko63f3d842020-07-08 10:10:14 +0200370 c = in->current;
371 in->current = " ";
372 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
373 in->current = c;
Michal Vasko90edde42019-11-25 15:25:07 +0100374 trailing_ws++;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200375 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200376 ++in->current;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200377 } else {
Michal Vasko90edde42019-11-25 15:25:07 +0100378 /* check and store whitespace character */
Michal Vasko63f3d842020-07-08 10:10:14 +0200379 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
Michal Vasko90edde42019-11-25 15:25:07 +0100380 trailing_ws++;
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200381 /* additional characters for indentation - only 1 was count in buf_store_char */
382 ctx->indent += 7;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200383 }
384 break;
385 case '\n':
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200386 if (block_indent) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200387 /* we will be removing the indents so we need our own buffer */
388 need_buf = 1;
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200389
390 /* remove trailing tabs and spaces */
Radek Krejciff13cd12019-10-25 15:34:24 +0200391 (*word_len) = *word_len - trailing_ws;
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200392
Radek Krejciff13cd12019-10-25 15:34:24 +0200393 /* restart indentation */
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200394 current_indent = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200395 }
396
397 /* check and store character */
Michal Vasko63f3d842020-07-08 10:10:14 +0200398 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200399
400 /* maintain line number */
401 ++ctx->line;
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200402
403 /* reset context indentation counter for possible string after this one */
404 ctx->indent = 0;
Radek Krejciff13cd12019-10-25 15:34:24 +0200405 trailing_ws = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200406 break;
407 default:
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200408 /* first non-whitespace character, stop eating indentation */
409 current_indent = block_indent;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200410
411 /* check and store character */
Michal Vasko63f3d842020-07-08 10:10:14 +0200412 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
Radek Krejciff13cd12019-10-25 15:34:24 +0200413 trailing_ws = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200414 break;
415 }
416 break;
417 case 3:
418 /* string encoded characters */
Michal Vasko63f3d842020-07-08 10:10:14 +0200419 c = in->current;
420 switch (in->current[0]) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200421 case 'n':
Michal Vasko63f3d842020-07-08 10:10:14 +0200422 in->current = "\n";
Michal Vasko7fbc8162018-09-17 10:35:16 +0200423 break;
424 case 't':
Michal Vasko63f3d842020-07-08 10:10:14 +0200425 in->current = "\t";
Michal Vasko7fbc8162018-09-17 10:35:16 +0200426 break;
427 case '\"':
Michal Vasko7fbc8162018-09-17 10:35:16 +0200428 case '\\':
Michal Vasko63f3d842020-07-08 10:10:14 +0200429 /* ok as is */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200430 break;
431 default:
Michal Vasko63f3d842020-07-08 10:10:14 +0200432 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Double-quoted string unknown special character '\\%c'.",
433 in->current[0]);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200434 return LY_EVALID;
435 }
436
437 /* check and store character */
Michal Vasko63f3d842020-07-08 10:10:14 +0200438 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200439
440 string = 2;
Michal Vasko63f3d842020-07-08 10:10:14 +0200441 in->current = c + 1;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200442 break;
443 case 4:
Michal Vasko63f3d842020-07-08 10:10:14 +0200444 switch (in->current[0]) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200445 case '+':
446 /* string continues */
447 string = 5;
Radek Krejciefd22f62018-09-27 11:47:58 +0200448 need_buf = 1;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200449 break;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200450 case '\n':
451 ++ctx->line;
Radek Krejci0f969882020-08-21 16:56:47 +0200452 /* fallthrough */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200453 case ' ':
454 case '\t':
Michal Vasko7fbc8162018-09-17 10:35:16 +0200455 /* just skip */
456 break;
457 default:
458 /* string is finished */
459 goto string_end;
460 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200461 MOVE_INPUT(ctx, in, 1);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200462 break;
463 case 5:
Michal Vasko63f3d842020-07-08 10:10:14 +0200464 switch (in->current[0]) {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200465 case '\n':
466 ++ctx->line;
Radek Krejci0f969882020-08-21 16:56:47 +0200467 /* fallthrough */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200468 case ' ':
469 case '\t':
Michal Vasko7fbc8162018-09-17 10:35:16 +0200470 /* skip */
471 break;
472 case '\'':
473 string = 1;
474 break;
475 case '\"':
476 string = 2;
477 break;
478 default:
479 /* it must be quoted again */
David Sedlákb3077192019-06-19 10:55:37 +0200480 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Both string parts divided by '+' must be quoted.");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200481 return LY_EVALID;
482 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200483 MOVE_INPUT(ctx, in, 1);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200484 break;
485 default:
486 return LY_EINT;
487 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200488 }
489
490string_end:
Radek Krejci4e199f52019-05-28 09:09:28 +0200491 if (arg <= Y_PREF_IDENTIF_ARG && !(*word_len)) {
492 /* empty identifier */
David Sedlákb3077192019-06-19 10:55:37 +0200493 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Statement argument is required.");
Radek Krejci4e199f52019-05-28 09:09:28 +0200494 return LY_EVALID;
495 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200496 return LY_SUCCESS;
497}
498
Michal Vaskoea5abea2018-09-18 13:10:54 +0200499/**
500 * @brief Get another YANG string from the raw data.
501 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200502 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200503 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200504 * @param[in] arg Type of YANG keyword argument expected.
Radek Krejcid3ca0632019-04-16 16:54:54 +0200505 * @param[out] flags optional output argument to get flag of the argument's quoting (LYS_*QOUTED - see [schema node flags](@ref snodeflags))
Michal Vasko2ca70f52018-09-27 11:04:51 +0200506 * @param[out] word_p Pointer to the read string. Can return NULL if \p arg is #Y_MAYBE_STR_ARG.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200507 * @param[out] word_b Pointer to a dynamically-allocated buffer holding the read string. If not needed,
508 * set to NULL. Otherwise equal to \p word_p.
509 * @param[out] word_len Length of the read string.
510 *
511 * @return LY_ERR values.
Michal Vasko7fbc8162018-09-17 10:35:16 +0200512 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200513LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200514get_argument(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum yang_arg arg, uint16_t *flags, char **word_p,
Radek Krejci0f969882020-08-21 16:56:47 +0200515 char **word_b, size_t *word_len)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200516{
Radek Krejci44ceedc2018-10-02 15:54:31 +0200517 size_t buf_len = 0;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200518 uint8_t prefix = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200519 /* word buffer - dynamically allocated */
520 *word_b = NULL;
521
522 /* word pointer - just a pointer to data */
523 *word_p = NULL;
524
525 *word_len = 0;
Michal Vasko63f3d842020-07-08 10:10:14 +0200526 while (in->current[0]) {
527 switch (in->current[0]) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200528 case '\'':
529 case '\"':
530 if (*word_len) {
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200531 /* invalid - quotes cannot be in unquoted string and only optsep, ; or { can follow it */
Michal Vasko63f3d842020-07-08 10:10:14 +0200532 LOGVAL_PARSER(ctx, LY_VCODE_INSTREXP, 1, in->current,
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200533 "unquoted string character, optsep, semicolon or opening brace");
534 return LY_EVALID;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200535 }
Radek Krejcid3ca0632019-04-16 16:54:54 +0200536 if (flags) {
Michal Vasko63f3d842020-07-08 10:10:14 +0200537 (*flags) |= in->current[0] == '\'' ? LYS_SINGLEQUOTED : LYS_DOUBLEQUOTED;
Radek Krejcid3ca0632019-04-16 16:54:54 +0200538 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200539 LY_CHECK_RET(read_qstring(ctx, in, arg, word_p, word_b, word_len, &buf_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200540 goto str_end;
541 case '/':
Michal Vasko63f3d842020-07-08 10:10:14 +0200542 if (in->current[1] == '/') {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200543 /* one-line comment */
Michal Vasko63f3d842020-07-08 10:10:14 +0200544 MOVE_INPUT(ctx, in, 2);
545 LY_CHECK_RET(skip_comment(ctx, in, 1));
546 } else if (in->current[1] == '*') {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200547 /* block comment */
Michal Vasko63f3d842020-07-08 10:10:14 +0200548 MOVE_INPUT(ctx, in, 2);
549 LY_CHECK_RET(skip_comment(ctx, in, 2));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200550 } else {
551 /* not a comment after all */
Michal Vasko63f3d842020-07-08 10:10:14 +0200552 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, &buf_len, 0, &prefix));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200553 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200554 break;
555 case ' ':
556 if (*word_len) {
557 /* word is finished */
558 goto str_end;
559 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200560 MOVE_INPUT(ctx, in, 1);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200561 break;
562 case '\t':
563 if (*word_len) {
564 /* word is finished */
565 goto str_end;
566 }
567 /* tabs count for 8 spaces */
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200568 ctx->indent += 8;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200569
Michal Vasko63f3d842020-07-08 10:10:14 +0200570 ++in->current;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200571 break;
572 case '\n':
573 if (*word_len) {
574 /* word is finished */
575 goto str_end;
576 }
577 /* reset indent */
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200578 ctx->indent = 0;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200579
580 /* track line numbers */
581 ++ctx->line;
582
Michal Vasko63f3d842020-07-08 10:10:14 +0200583 ++in->current;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200584 break;
585 case ';':
586 case '{':
587 if (*word_len || (arg == Y_MAYBE_STR_ARG)) {
588 /* word is finished */
589 goto str_end;
590 }
591
Michal Vasko63f3d842020-07-08 10:10:14 +0200592 LOGVAL_PARSER(ctx, LY_VCODE_INSTREXP, 1, in->current, "an argument");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200593 return LY_EVALID;
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200594 case '}':
595 /* invalid - braces cannot be in unquoted string (opening braces terminates the string and can follow it) */
Michal Vasko63f3d842020-07-08 10:10:14 +0200596 LOGVAL_PARSER(ctx, LY_VCODE_INSTREXP, 1, in->current,
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200597 "unquoted string character, optsep, semicolon or opening brace");
598 return LY_EVALID;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200599 default:
Michal Vasko63f3d842020-07-08 10:10:14 +0200600 LY_CHECK_RET(buf_store_char(ctx, in, arg, word_p, word_len, word_b, &buf_len, 0, &prefix));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200601 break;
602 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200603 }
604
Radek Krejci0a1d0d42019-05-16 15:14:51 +0200605 /* unexpected end of loop */
David Sedlákb3077192019-06-19 10:55:37 +0200606 LOGVAL_PARSER(ctx, LY_VCODE_EOF);
Radek Krejci0a1d0d42019-05-16 15:14:51 +0200607 return LY_EVALID;
608
Michal Vasko7fbc8162018-09-17 10:35:16 +0200609str_end:
Radek Krejci44ceedc2018-10-02 15:54:31 +0200610 /* terminating NULL byte for buf */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200611 if (*word_b) {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200612 (*word_b) = ly_realloc(*word_b, (*word_len) + 1);
613 LY_CHECK_ERR_RET(!(*word_b), LOGMEM(ctx->ctx), LY_EMEM);
614 (*word_b)[*word_len] = '\0';
Michal Vasko7fbc8162018-09-17 10:35:16 +0200615 *word_p = *word_b;
616 }
617
618 return LY_SUCCESS;
619}
620
Michal Vaskoea5abea2018-09-18 13:10:54 +0200621/**
622 * @brief Get another YANG keyword from the raw data.
623 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200624 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200625 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200626 * @param[out] kw YANG keyword read.
627 * @param[out] word_p Pointer to the keyword in the data. Useful for extension instances.
628 * @param[out] word_len Length of the keyword in the data. Useful for extension instances.
629 *
630 * @return LY_ERR values.
631 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200632LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200633get_keyword(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt *kw, char **word_p, size_t *word_len)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200634{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200635 uint8_t prefix;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200636 const char *word_start;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200637 size_t len;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200638
639 if (word_p) {
640 *word_p = NULL;
641 *word_len = 0;
642 }
643
644 /* first skip "optsep", comments */
Michal Vasko63f3d842020-07-08 10:10:14 +0200645 while (in->current[0]) {
646 switch (in->current[0]) {
Radek Krejcidcc7b322018-10-11 14:24:02 +0200647 case '/':
Michal Vasko63f3d842020-07-08 10:10:14 +0200648 if (in->current[1] == '/') {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200649 /* one-line comment */
Michal Vasko63f3d842020-07-08 10:10:14 +0200650 MOVE_INPUT(ctx, in, 2);
651 LY_CHECK_RET(skip_comment(ctx, in, 1));
652 } else if (in->current[1] == '*') {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200653 /* block comment */
Michal Vasko63f3d842020-07-08 10:10:14 +0200654 MOVE_INPUT(ctx, in, 2);
655 LY_CHECK_RET(skip_comment(ctx, in, 2));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200656 } else {
Radek Krejcidcc7b322018-10-11 14:24:02 +0200657 /* error - not a comment after all, keyword cannot start with slash */
David Sedlákb3077192019-06-19 10:55:37 +0200658 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Invalid identifier first character '/'.");
Radek Krejcidcc7b322018-10-11 14:24:02 +0200659 return LY_EVALID;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200660 }
Radek Krejci13028282019-06-11 14:56:48 +0200661 continue;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200662 case '\n':
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200663 /* skip whitespaces (optsep) */
Radek Krejci44ceedc2018-10-02 15:54:31 +0200664 ++ctx->line;
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200665 ctx->indent = 0;
666 break;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200667 case ' ':
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200668 /* skip whitespaces (optsep) */
669 ++ctx->indent;
670 break;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200671 case '\t':
Michal Vasko7fbc8162018-09-17 10:35:16 +0200672 /* skip whitespaces (optsep) */
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200673 ctx->indent += 8;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200674 break;
675 default:
676 /* either a keyword start or an invalid character */
677 goto keyword_start;
678 }
679
Michal Vasko63f3d842020-07-08 10:10:14 +0200680 ly_in_skip(in, 1);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200681 }
682
683keyword_start:
Michal Vasko63f3d842020-07-08 10:10:14 +0200684 word_start = in->current;
685 *kw = lysp_match_kw(ctx, in);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200686
Radek Krejcid6b76452019-09-03 17:03:03 +0200687 if (*kw == LY_STMT_SYNTAX_SEMICOLON || *kw == LY_STMT_SYNTAX_LEFT_BRACE || *kw == LY_STMT_SYNTAX_RIGHT_BRACE) {
Radek Krejci626df482018-10-11 15:06:31 +0200688 goto success;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200689 }
690
Radek Krejcid6b76452019-09-03 17:03:03 +0200691 if (*kw != LY_STMT_NONE) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200692 /* make sure we have the whole keyword */
Michal Vasko63f3d842020-07-08 10:10:14 +0200693 switch (in->current[0]) {
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200694 case '\n':
Michal Vasko7fbc8162018-09-17 10:35:16 +0200695 case '\t':
Radek Krejciabdd8062019-06-11 16:44:19 +0200696 case ' ':
697 /* mandatory "sep" is just checked, not eaten so nothing in the context is updated */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200698 break;
Radek Krejci156ccaf2018-10-15 15:49:17 +0200699 case ':':
700 /* keyword is not actually a keyword, but prefix of an extension.
701 * To avoid repeated check of the prefix syntax, move to the point where the colon was read
702 * and we will be checking the keyword (extension instance) itself */
703 prefix = 1;
Michal Vasko63f3d842020-07-08 10:10:14 +0200704 MOVE_INPUT(ctx, in, 1);
Radek Krejci156ccaf2018-10-15 15:49:17 +0200705 goto extension;
Radek Krejcidcc7b322018-10-11 14:24:02 +0200706 case '{':
707 /* allowed only for input and output statements which can be without arguments */
Radek Krejcid6b76452019-09-03 17:03:03 +0200708 if (*kw == LY_STMT_INPUT || *kw == LY_STMT_OUTPUT) {
Radek Krejcidcc7b322018-10-11 14:24:02 +0200709 break;
710 }
Radek Krejci0f969882020-08-21 16:56:47 +0200711 /* fallthrough */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200712 default:
Michal Vasko63f3d842020-07-08 10:10:14 +0200713 MOVE_INPUT(ctx, in, 1);
714 LOGVAL_PARSER(ctx, LY_VCODE_INSTREXP, (int)(in->current - word_start), word_start,
Radek Krejci44ceedc2018-10-02 15:54:31 +0200715 "a keyword followed by a separator");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200716 return LY_EVALID;
717 }
718 } else {
719 /* still can be an extension */
720 prefix = 0;
Radek Krejci156ccaf2018-10-15 15:49:17 +0200721extension:
Michal Vasko63f3d842020-07-08 10:10:14 +0200722 while (in->current[0] && (in->current[0] != ' ') && (in->current[0] != '\t') && (in->current[0] != '\n')
723 && (in->current[0] != '{') && (in->current[0] != ';')) {
Radek Krejci1deb5be2020-08-26 16:43:36 +0200724 uint32_t c = 0;
725
Michal Vasko63f3d842020-07-08 10:10:14 +0200726 LY_CHECK_ERR_RET(ly_getutf8(&in->current, &c, &len),
727 LOGVAL_PARSER(ctx, LY_VCODE_INCHAR, in->current[-len]), LY_EVALID);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200728 ++ctx->indent;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200729 /* check character validity */
Michal Vasko63f3d842020-07-08 10:10:14 +0200730 LY_CHECK_RET(lysp_check_identifierchar((struct lys_parser_ctx *)ctx, c,
731 in->current - len == word_start ? 1 : 0, &prefix));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200732 }
Michal Vasko63f3d842020-07-08 10:10:14 +0200733 if (!in->current[0]) {
David Sedlákb3077192019-06-19 10:55:37 +0200734 LOGVAL_PARSER(ctx, LY_VCODE_EOF);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200735 return LY_EVALID;
736 }
737
738 /* prefix is mandatory for extension instances */
Radek Krejcidcc7b322018-10-11 14:24:02 +0200739 if (prefix != 2) {
Michal Vasko63f3d842020-07-08 10:10:14 +0200740 LOGVAL_PARSER(ctx, LY_VCODE_INSTREXP, (int)(in->current - word_start), word_start, "a keyword");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200741 return LY_EVALID;
742 }
743
Radek Krejcid6b76452019-09-03 17:03:03 +0200744 *kw = LY_STMT_EXTENSION_INSTANCE;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200745 }
Radek Krejci626df482018-10-11 15:06:31 +0200746success:
Michal Vasko7fbc8162018-09-17 10:35:16 +0200747 if (word_p) {
748 *word_p = (char *)word_start;
Michal Vasko63f3d842020-07-08 10:10:14 +0200749 *word_len = in->current - word_start;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200750 }
751
752 return LY_SUCCESS;
753}
754
Michal Vaskoea5abea2018-09-18 13:10:54 +0200755/**
756 * @brief Parse extension instance substatements.
757 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200758 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200759 * @param[in,out] in Input structure.
Radek Krejci335332a2019-09-05 13:03:35 +0200760 * @param[in] kw Statement keyword value matching @p word value.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200761 * @param[in] word Extension instance substatement name (keyword).
762 * @param[in] word_len Extension instance substatement name length.
763 * @param[in,out] child Children of this extension instance to add to.
764 *
765 * @return LY_ERR values.
766 */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200767static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200768parse_ext_substmt(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt kw, char *word, size_t word_len,
Radek Krejci0f969882020-08-21 16:56:47 +0200769 struct lysp_stmt **child)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200770{
771 char *buf;
Radek Krejci6d9b9b52018-11-02 12:43:39 +0100772 LY_ERR ret = LY_SUCCESS;
Radek Krejci335332a2019-09-05 13:03:35 +0200773 enum ly_stmt child_kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200774 struct lysp_stmt *stmt, *par_child;
775
776 stmt = calloc(1, sizeof *stmt);
777 LY_CHECK_ERR_RET(!stmt, LOGMEM(NULL), LY_EMEM);
778
Radek Krejcibb9b1982019-04-08 14:24:59 +0200779 /* insert into parent statements */
780 if (!*child) {
781 *child = stmt;
782 } else {
Radek Krejci1e008d22020-08-17 11:37:37 +0200783 for (par_child = *child; par_child->next; par_child = par_child->next) {}
Radek Krejcibb9b1982019-04-08 14:24:59 +0200784 par_child->next = stmt;
785 }
786
Radek Krejci44ceedc2018-10-02 15:54:31 +0200787 stmt->stmt = lydict_insert(ctx->ctx, word, word_len);
Radek Krejci335332a2019-09-05 13:03:35 +0200788 stmt->kw = kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200789
790 /* get optional argument */
Michal Vasko63f3d842020-07-08 10:10:14 +0200791 LY_CHECK_RET(get_argument(ctx, in, Y_MAYBE_STR_ARG, &stmt->flags, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200792
Radek Krejci0ae092d2018-09-20 16:43:19 +0200793 if (word) {
794 if (buf) {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200795 stmt->arg = lydict_insert_zc(ctx->ctx, word);
Radek Krejci0ae092d2018-09-20 16:43:19 +0200796 } else {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200797 stmt->arg = lydict_insert(ctx->ctx, word, word_len);
Radek Krejci0ae092d2018-09-20 16:43:19 +0200798 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200799 }
800
Michal Vasko63f3d842020-07-08 10:10:14 +0200801 YANG_READ_SUBSTMT_FOR(ctx, in, child_kw, word, word_len, ret, ) {
802 LY_CHECK_RET(parse_ext_substmt(ctx, in, child_kw, word, word_len, &stmt->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200803 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200804 return ret;
805}
806
Michal Vaskoea5abea2018-09-18 13:10:54 +0200807/**
808 * @brief Parse extension instance.
809 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200810 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200811 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200812 * @param[in] ext_name Extension instance substatement name (keyword).
813 * @param[in] ext_name_len Extension instance substatement name length.
814 * @param[in] insubstmt Type of the keyword this extension instance is a substatement of.
815 * @param[in] insubstmt_index Index of the keyword instance this extension instance is a substatement of.
816 * @param[in,out] exts Extension instances to add to.
817 *
818 * @return LY_ERR values.
819 */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200820static LY_ERR
Radek Krejci1deb5be2020-08-26 16:43:36 +0200821parse_ext(struct lys_yang_parser_ctx *ctx, struct ly_in *in, const char *ext_name, size_t ext_name_len, LYEXT_SUBSTMT insubstmt,
Radek Krejci0f969882020-08-21 16:56:47 +0200822 LY_ARRAY_COUNT_TYPE insubstmt_index, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200823{
Radek Krejci6d9b9b52018-11-02 12:43:39 +0100824 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200825 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +0200826 size_t word_len;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200827 struct lysp_ext_instance *e;
Radek Krejcid6b76452019-09-03 17:03:03 +0200828 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200829
Radek Krejci2c4e7172018-10-19 15:56:26 +0200830 LY_ARRAY_NEW_RET(ctx->ctx, *exts, e, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200831
832 /* store name and insubstmt info */
Radek Krejci44ceedc2018-10-02 15:54:31 +0200833 e->name = lydict_insert(ctx->ctx, ext_name, ext_name_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200834 e->insubstmt = insubstmt;
835 e->insubstmt_index = insubstmt_index;
836
837 /* get optional argument */
Michal Vasko63f3d842020-07-08 10:10:14 +0200838 LY_CHECK_RET(get_argument(ctx, in, Y_MAYBE_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200839
Radek Krejci0ae092d2018-09-20 16:43:19 +0200840 if (word) {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200841 INSERT_WORD(ctx, buf, e->argument, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200842 }
843
Michal Vaskod989ba02020-08-24 10:59:24 +0200844 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko63f3d842020-07-08 10:10:14 +0200845 LY_CHECK_RET(parse_ext_substmt(ctx, in, kw, word, word_len, &e->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200846 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200847 return ret;
848}
849
Michal Vaskoea5abea2018-09-18 13:10:54 +0200850/**
851 * @brief Parse a generic text field without specific constraints. Those are contact, organization,
852 * description, etc...
853 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200854 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200855 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200856 * @param[in] substmt Type of this substatement.
857 * @param[in] substmt_index Index of this substatement.
858 * @param[in,out] value Place to store the parsed value.
859 * @param[in] arg Type of the YANG keyword argument (of the value).
860 * @param[in,out] exts Extension instances to add to.
861 *
862 * @return LY_ERR values.
863 */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200864static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200865parse_text_field(struct lys_yang_parser_ctx *ctx, struct ly_in *in, LYEXT_SUBSTMT substmt, uint32_t substmt_index,
Radek Krejci0f969882020-08-21 16:56:47 +0200866 const char **value, enum yang_arg arg, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200867{
Radek Krejci6d9b9b52018-11-02 12:43:39 +0100868 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200869 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +0200870 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +0200871 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200872
873 if (*value) {
David Sedlákb3077192019-06-19 10:55:37 +0200874 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyext_substmt2str(substmt));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200875 return LY_EVALID;
876 }
877
878 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +0200879 LY_CHECK_RET(get_argument(ctx, in, arg, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200880
881 /* store value and spend buf if allocated */
Radek Krejci44ceedc2018-10-02 15:54:31 +0200882 INSERT_WORD(ctx, buf, *value, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +0200883
Michal Vaskod989ba02020-08-24 10:59:24 +0200884 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200885 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +0200886 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +0200887 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, substmt, substmt_index, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200888 break;
889 default:
David Sedlákb3077192019-06-19 10:55:37 +0200890 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), lyext_substmt2str(substmt));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200891 return LY_EVALID;
892 }
893 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200894 return ret;
895}
896
Michal Vaskoea5abea2018-09-18 13:10:54 +0200897/**
898 * @brief Parse the yang-version statement.
899 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200900 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200901 * @param[in,out] in Input structure.
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100902 * @param[out] version Storage for the parsed information.
Michal Vasko63f3d842020-07-08 10:10:14 +0200903 * @param[in,out] exts Extension instances to add to.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200904 *
905 * @return LY_ERR values.
906 */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200907static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200908parse_yangversion(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint8_t *version, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200909{
Radek Krejci6d9b9b52018-11-02 12:43:39 +0100910 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200911 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +0200912 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +0200913 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200914
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100915 if (*version) {
David Sedlákb3077192019-06-19 10:55:37 +0200916 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yang-version");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200917 return LY_EVALID;
918 }
919
920 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +0200921 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200922
923 if ((word_len == 3) && !strncmp(word, "1.0", word_len)) {
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100924 *version = LYS_VERSION_1_0;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200925 } else if ((word_len == 3) && !strncmp(word, "1.1", word_len)) {
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100926 *version = LYS_VERSION_1_1;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200927 } else {
David Sedlákb3077192019-06-19 10:55:37 +0200928 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "yang-version");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200929 free(buf);
930 return LY_EVALID;
931 }
932 free(buf);
933
Michal Vaskod989ba02020-08-24 10:59:24 +0200934 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200935 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +0200936 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +0200937 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_VERSION, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200938 break;
939 default:
David Sedlákb3077192019-06-19 10:55:37 +0200940 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "yang-version");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200941 return LY_EVALID;
942 }
943 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200944 return ret;
945}
946
Michal Vaskoea5abea2018-09-18 13:10:54 +0200947/**
948 * @brief Parse the belongs-to statement.
949 *
Radek Krejci44ceedc2018-10-02 15:54:31 +0200950 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +0200951 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +0200952 * @param[in,out] belongsto Place to store the parsed value.
953 * @param[in,out] prefix Place to store the parsed belongs-to prefix value.
954 * @param[in,out] exts Extension instances to add to.
955 *
956 * @return LY_ERR values.
957 */
Michal Vasko7fbc8162018-09-17 10:35:16 +0200958static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +0200959parse_belongsto(struct lys_yang_parser_ctx *ctx, struct ly_in *in, const char **belongsto, const char **prefix, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +0200960{
Radek Krejci6d9b9b52018-11-02 12:43:39 +0100961 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200962 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +0200963 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +0200964 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +0200965
966 if (*belongsto) {
David Sedlákb3077192019-06-19 10:55:37 +0200967 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "belongs-to");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200968 return LY_EVALID;
969 }
970
971 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +0200972 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200973
Radek Krejci44ceedc2018-10-02 15:54:31 +0200974 INSERT_WORD(ctx, buf, *belongsto, word, word_len);
Radek Krejcif09e4e82019-06-14 15:08:11 +0200975
Michal Vasko63f3d842020-07-08 10:10:14 +0200976 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +0200977 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +0200978 case LY_STMT_PREFIX:
Michal Vasko63f3d842020-07-08 10:10:14 +0200979 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_PREFIX, 0, prefix, Y_IDENTIF_ARG, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200980 break;
Radek Krejcid6b76452019-09-03 17:03:03 +0200981 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +0200982 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_BELONGSTO, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +0200983 break;
984 default:
David Sedlákb3077192019-06-19 10:55:37 +0200985 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "belongs-to");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200986 return LY_EVALID;
987 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200988 }
Radek Krejcic59bc972018-09-17 16:13:06 +0200989 LY_CHECK_RET(ret);
Radek Krejci6d6556c2018-11-08 09:37:45 +0100990checks:
Michal Vasko7fbc8162018-09-17 10:35:16 +0200991 /* mandatory substatements */
992 if (!*prefix) {
David Sedlákb3077192019-06-19 10:55:37 +0200993 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "prefix", "belongs-to");
Michal Vasko7fbc8162018-09-17 10:35:16 +0200994 return LY_EVALID;
995 }
Michal Vasko7fbc8162018-09-17 10:35:16 +0200996 return ret;
997}
998
Michal Vaskoea5abea2018-09-18 13:10:54 +0200999/**
1000 * @brief Parse the revision-date statement.
1001 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001002 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001003 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001004 * @param[in,out] rev Array to store the parsed value in.
1005 * @param[in,out] exts Extension instances to add to.
1006 *
1007 * @return LY_ERR values.
1008 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001009static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001010parse_revisiondate(struct lys_yang_parser_ctx *ctx, struct ly_in *in, char *rev, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001011{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001012 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001013 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001014 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001015 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001016
1017 if (rev[0]) {
David Sedlákb3077192019-06-19 10:55:37 +02001018 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "revision-date");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001019 return LY_EVALID;
1020 }
1021
1022 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001023 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001024
1025 /* check value */
Michal Vaskob36053d2020-03-26 15:49:30 +01001026 if (lysp_check_date((struct lys_parser_ctx *)ctx, word, word_len, "revision-date")) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001027 free(buf);
1028 return LY_EVALID;
1029 }
1030
1031 /* store value and spend buf if allocated */
1032 strncpy(rev, word, word_len);
1033 free(buf);
1034
Michal Vaskod989ba02020-08-24 10:59:24 +02001035 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001036 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001037 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001038 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_REVISIONDATE, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001039 break;
1040 default:
David Sedlákb3077192019-06-19 10:55:37 +02001041 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "revision-date");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001042 return LY_EVALID;
1043 }
1044 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001045 return ret;
1046}
1047
Michal Vaskoea5abea2018-09-18 13:10:54 +02001048/**
1049 * @brief Parse the include statement.
1050 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001051 * @param[in] ctx yang parser context for logging.
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001052 * @param[in] module_name Name of the module to check name collisions.
Michal Vasko63f3d842020-07-08 10:10:14 +02001053 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001054 * @param[in,out] includes Parsed includes to add to.
1055 *
1056 * @return LY_ERR values.
1057 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001058static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001059parse_include(struct lys_yang_parser_ctx *ctx, const char *module_name, struct ly_in *in, struct lysp_include **includes)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001060{
Radek Krejcid33273d2018-10-25 14:55:52 +02001061 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001062 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001063 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001064 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001065 struct lysp_include *inc;
1066
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001067 LY_ARRAY_NEW_RET(ctx->ctx, *includes, inc, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001068
1069 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001070 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001071
Radek Krejci086c7132018-10-26 15:29:04 +02001072 INSERT_WORD(ctx, buf, inc->name, word, word_len);
1073
Radek Krejcifaa1eac2018-10-30 14:34:55 +01001074 /* submodules share the namespace with the module names, so there must not be
1075 * a module of the same name in the context, no need for revision matching */
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001076 if (!strcmp(module_name, inc->name) || ly_ctx_get_module_latest(ctx->ctx, inc->name)) {
David Sedlákb3077192019-06-19 10:55:37 +02001077 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Name collision between module and submodule of name \"%s\".", inc->name);
Radek Krejcifaa1eac2018-10-30 14:34:55 +01001078 return LY_EVALID;
1079 }
1080
Michal Vaskod989ba02020-08-24 10:59:24 +02001081 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001082 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001083 case LY_STMT_DESCRIPTION:
Radek Krejci335332a2019-09-05 13:03:35 +02001084 PARSER_CHECK_STMTVER2_RET(ctx, "description", "include");
Michal Vasko63f3d842020-07-08 10:10:14 +02001085 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &inc->dsc, Y_STR_ARG, &inc->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001086 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001087 case LY_STMT_REFERENCE:
Radek Krejci335332a2019-09-05 13:03:35 +02001088 PARSER_CHECK_STMTVER2_RET(ctx, "reference", "include");
Michal Vasko63f3d842020-07-08 10:10:14 +02001089 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &inc->ref, Y_STR_ARG, &inc->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001090 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001091 case LY_STMT_REVISION_DATE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001092 LY_CHECK_RET(parse_revisiondate(ctx, in, inc->rev, &inc->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001093 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001094 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001095 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &inc->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001096 break;
1097 default:
David Sedlákb3077192019-06-19 10:55:37 +02001098 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "include");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001099 return LY_EVALID;
1100 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001101 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001102 return ret;
1103}
1104
Michal Vaskoea5abea2018-09-18 13:10:54 +02001105/**
1106 * @brief Parse the import statement.
1107 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001108 * @param[in] ctx yang parser context for logging.
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001109 * @param[in] module_prefix Prefix of the module to check prefix collisions.
Michal Vasko63f3d842020-07-08 10:10:14 +02001110 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001111 * @param[in,out] imports Parsed imports to add to.
1112 *
1113 * @return LY_ERR values.
1114 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001115static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001116parse_import(struct lys_yang_parser_ctx *ctx, const char *module_prefix, struct ly_in *in, struct lysp_import **imports)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001117{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001118 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001119 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001120 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001121 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001122 struct lysp_import *imp;
1123
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001124 LY_ARRAY_NEW_RET(ctx->ctx, *imports, imp, LY_EVALID);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001125
1126 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001127 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02001128 INSERT_WORD(ctx, buf, imp->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001129
Michal Vasko63f3d842020-07-08 10:10:14 +02001130 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001131 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001132 case LY_STMT_PREFIX:
Michal Vasko63f3d842020-07-08 10:10:14 +02001133 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_PREFIX, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts));
Michal Vaskob36053d2020-03-26 15:49:30 +01001134 LY_CHECK_RET(lysp_check_prefix((struct lys_parser_ctx *)ctx, *imports, module_prefix, &imp->prefix), LY_EVALID);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001135 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001136 case LY_STMT_DESCRIPTION:
Radek Krejci335332a2019-09-05 13:03:35 +02001137 PARSER_CHECK_STMTVER2_RET(ctx, "description", "import");
Michal Vasko63f3d842020-07-08 10:10:14 +02001138 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &imp->dsc, Y_STR_ARG, &imp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001139 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001140 case LY_STMT_REFERENCE:
Radek Krejci335332a2019-09-05 13:03:35 +02001141 PARSER_CHECK_STMTVER2_RET(ctx, "reference", "import");
Michal Vasko63f3d842020-07-08 10:10:14 +02001142 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &imp->ref, Y_STR_ARG, &imp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001143 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001144 case LY_STMT_REVISION_DATE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001145 LY_CHECK_RET(parse_revisiondate(ctx, in, imp->rev, &imp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001146 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001147 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001148 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &imp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001149 break;
1150 default:
David Sedlákb3077192019-06-19 10:55:37 +02001151 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "import");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001152 return LY_EVALID;
1153 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001154 }
Radek Krejcic59bc972018-09-17 16:13:06 +02001155 LY_CHECK_RET(ret);
Radek Krejci6d6556c2018-11-08 09:37:45 +01001156checks:
Michal Vasko7fbc8162018-09-17 10:35:16 +02001157 /* mandatory substatements */
David Sedlákb3077192019-06-19 10:55:37 +02001158 LY_CHECK_ERR_RET(!imp->prefix, LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "prefix", "import"), LY_EVALID);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001159
1160 return ret;
1161}
1162
Michal Vaskoea5abea2018-09-18 13:10:54 +02001163/**
1164 * @brief Parse the revision statement.
1165 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001166 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001167 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001168 * @param[in,out] revs Parsed revisions to add to.
1169 *
1170 * @return LY_ERR values.
1171 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001172static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001173parse_revision(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_revision **revs)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001174{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001175 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001176 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001177 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001178 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001179 struct lysp_revision *rev;
1180
Radek Krejci2c4e7172018-10-19 15:56:26 +02001181 LY_ARRAY_NEW_RET(ctx->ctx, *revs, rev, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001182
1183 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001184 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001185
1186 /* check value */
Michal Vaskob36053d2020-03-26 15:49:30 +01001187 if (lysp_check_date((struct lys_parser_ctx *)ctx, word, word_len, "revision")) {
David Sedlák68ef3dc2019-07-22 13:40:19 +02001188 free(buf);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001189 return LY_EVALID;
1190 }
1191
Radek Krejcib7db73a2018-10-24 14:18:40 +02001192 strncpy(rev->date, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001193 free(buf);
1194
Michal Vaskod989ba02020-08-24 10:59:24 +02001195 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001196 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001197 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02001198 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &rev->dsc, Y_STR_ARG, &rev->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001199 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001200 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001201 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &rev->ref, Y_STR_ARG, &rev->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001202 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001203 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001204 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &rev->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001205 break;
1206 default:
David Sedlákb3077192019-06-19 10:55:37 +02001207 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "revision");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001208 return LY_EVALID;
1209 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001210 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001211 return ret;
1212}
1213
Michal Vaskoea5abea2018-09-18 13:10:54 +02001214/**
1215 * @brief Parse a generic text field that can have more instances such as base.
1216 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001217 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001218 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001219 * @param[in] substmt Type of this substatement.
1220 * @param[in,out] texts Parsed values to add to.
1221 * @param[in] arg Type of the expected argument.
1222 * @param[in,out] exts Extension instances to add to.
1223 *
1224 * @return LY_ERR values.
1225 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001226static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001227parse_text_fields(struct lys_yang_parser_ctx *ctx, struct ly_in *in, LYEXT_SUBSTMT substmt, const char ***texts, enum yang_arg arg,
Radek Krejci0f969882020-08-21 16:56:47 +02001228 struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001229{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001230 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001231 char *buf, *word;
Radek Krejci151a5b72018-10-19 14:21:44 +02001232 const char **item;
1233 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001234 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001235
1236 /* allocate new pointer */
Radek Krejci2c4e7172018-10-19 15:56:26 +02001237 LY_ARRAY_NEW_RET(ctx->ctx, *texts, item, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001238
1239 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001240 LY_CHECK_RET(get_argument(ctx, in, arg, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001241
Radek Krejci151a5b72018-10-19 14:21:44 +02001242 INSERT_WORD(ctx, buf, *item, word, word_len);
Michal Vaskod989ba02020-08-24 10:59:24 +02001243 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001244 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001245 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001246 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, substmt, LY_ARRAY_COUNT(*texts) - 1, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001247 break;
1248 default:
David Sedlákb3077192019-06-19 10:55:37 +02001249 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), lyext_substmt2str(substmt));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001250 return LY_EVALID;
1251 }
1252 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001253 return ret;
1254}
1255
Michal Vaskoea5abea2018-09-18 13:10:54 +02001256/**
1257 * @brief Parse the config statement.
1258 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001259 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001260 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001261 * @param[in,out] flags Flags to add to.
1262 * @param[in,out] exts Extension instances to add to.
1263 *
1264 * @return LY_ERR values.
1265 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001266static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001267parse_config(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint16_t *flags, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001268{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001269 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001270 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001271 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001272 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001273
1274 if (*flags & LYS_CONFIG_MASK) {
David Sedlákb3077192019-06-19 10:55:37 +02001275 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "config");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001276 return LY_EVALID;
1277 }
1278
1279 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001280 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001281
1282 if ((word_len == 4) && !strncmp(word, "true", word_len)) {
1283 *flags |= LYS_CONFIG_W;
1284 } else if ((word_len == 5) && !strncmp(word, "false", word_len)) {
1285 *flags |= LYS_CONFIG_R;
1286 } else {
David Sedlákb3077192019-06-19 10:55:37 +02001287 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "config");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001288 free(buf);
1289 return LY_EVALID;
1290 }
1291 free(buf);
1292
Michal Vaskod989ba02020-08-24 10:59:24 +02001293 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001294 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001295 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001296 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_CONFIG, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001297 break;
1298 default:
David Sedlákb3077192019-06-19 10:55:37 +02001299 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "config");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001300 return LY_EVALID;
1301 }
1302 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001303 return ret;
1304}
1305
Michal Vaskoea5abea2018-09-18 13:10:54 +02001306/**
1307 * @brief Parse the mandatory statement.
1308 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001309 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001310 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001311 * @param[in,out] flags Flags to add to.
1312 * @param[in,out] exts Extension instances to add to.
1313 *
1314 * @return LY_ERR values.
1315 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001316static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001317parse_mandatory(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint16_t *flags, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001318{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001319 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001320 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001321 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001322 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001323
1324 if (*flags & LYS_MAND_MASK) {
David Sedlákb3077192019-06-19 10:55:37 +02001325 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "mandatory");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001326 return LY_EVALID;
1327 }
1328
1329 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001330 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001331
1332 if ((word_len == 4) && !strncmp(word, "true", word_len)) {
1333 *flags |= LYS_MAND_TRUE;
1334 } else if ((word_len == 5) && !strncmp(word, "false", word_len)) {
1335 *flags |= LYS_MAND_FALSE;
1336 } else {
David Sedlákb3077192019-06-19 10:55:37 +02001337 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "mandatory");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001338 free(buf);
1339 return LY_EVALID;
1340 }
1341 free(buf);
1342
Michal Vaskod989ba02020-08-24 10:59:24 +02001343 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001344 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001345 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001346 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_MANDATORY, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001347 break;
1348 default:
David Sedlákb3077192019-06-19 10:55:37 +02001349 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "mandatory");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001350 return LY_EVALID;
1351 }
1352 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001353 return ret;
1354}
1355
Michal Vaskoea5abea2018-09-18 13:10:54 +02001356/**
1357 * @brief Parse a restriction such as range or length.
1358 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001359 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001360 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001361 * @param[in] restr_kw Type of this particular restriction.
1362 * @param[in,out] exts Extension instances to add to.
1363 *
1364 * @return LY_ERR values.
1365 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001366static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001367parse_restr(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt restr_kw, struct lysp_restr *restr)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001368{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001369 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001370 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001371 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001372 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001373
1374 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001375 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001376
Michal Vaskob36053d2020-03-26 15:49:30 +01001377 CHECK_NONEMPTY(ctx, word_len, ly_stmt2str(restr_kw));
Radek Krejci44ceedc2018-10-02 15:54:31 +02001378 INSERT_WORD(ctx, buf, restr->arg, word, word_len);
Michal Vaskod989ba02020-08-24 10:59:24 +02001379 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001380 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001381 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02001382 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001383 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001384 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001385 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &restr->ref, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001386 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001387 case LY_STMT_ERROR_APP_TAG:
Michal Vasko63f3d842020-07-08 10:10:14 +02001388 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_ERRTAG, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001389 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001390 case LY_STMT_ERROR_MESSAGE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001391 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_ERRMSG, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001392 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001393 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001394 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001395 break;
1396 default:
David Sedlákb3077192019-06-19 10:55:37 +02001397 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(restr_kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001398 return LY_EVALID;
1399 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001400 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001401 return ret;
1402}
1403
Michal Vaskoea5abea2018-09-18 13:10:54 +02001404/**
1405 * @brief Parse a restriction that can have more instances such as must.
1406 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001407 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001408 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001409 * @param[in] restr_kw Type of this particular restriction.
1410 * @param[in,out] restrs Restrictions to add to.
1411 *
1412 * @return LY_ERR values.
1413 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001414static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001415parse_restrs(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt restr_kw, struct lysp_restr **restrs)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001416{
1417 struct lysp_restr *restr;
1418
Radek Krejci2c4e7172018-10-19 15:56:26 +02001419 LY_ARRAY_NEW_RET(ctx->ctx, *restrs, restr, LY_EMEM);
Michal Vasko63f3d842020-07-08 10:10:14 +02001420 return parse_restr(ctx, in, restr_kw, restr);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001421}
1422
Michal Vaskoea5abea2018-09-18 13:10:54 +02001423/**
1424 * @brief Parse the status statement.
1425 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001426 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001427 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001428 * @param[in,out] flags Flags to add to.
1429 * @param[in,out] exts Extension instances to add to.
1430 *
1431 * @return LY_ERR values.
1432 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001433static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001434parse_status(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint16_t *flags, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001435{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001436 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001437 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001438 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001439 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001440
1441 if (*flags & LYS_STATUS_MASK) {
David Sedlákb3077192019-06-19 10:55:37 +02001442 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "status");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001443 return LY_EVALID;
1444 }
1445
1446 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001447 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001448
1449 if ((word_len == 7) && !strncmp(word, "current", word_len)) {
1450 *flags |= LYS_STATUS_CURR;
1451 } else if ((word_len == 10) && !strncmp(word, "deprecated", word_len)) {
1452 *flags |= LYS_STATUS_DEPRC;
1453 } else if ((word_len == 8) && !strncmp(word, "obsolete", word_len)) {
1454 *flags |= LYS_STATUS_OBSLT;
1455 } else {
David Sedlákb3077192019-06-19 10:55:37 +02001456 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "status");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001457 free(buf);
1458 return LY_EVALID;
1459 }
1460 free(buf);
1461
Michal Vaskod989ba02020-08-24 10:59:24 +02001462 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001463 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001464 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001465 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_STATUS, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001466 break;
1467 default:
David Sedlákb3077192019-06-19 10:55:37 +02001468 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "status");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001469 return LY_EVALID;
1470 }
1471 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001472 return ret;
1473}
1474
Michal Vaskoea5abea2018-09-18 13:10:54 +02001475/**
1476 * @brief Parse the when statement.
1477 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001478 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001479 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001480 * @param[in,out] when_p When pointer to parse to.
1481 *
1482 * @return LY_ERR values.
1483 */
Radek Krejcif09e4e82019-06-14 15:08:11 +02001484LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001485parse_when(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_when **when_p)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001486{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001487 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001488 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001489 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001490 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001491 struct lysp_when *when;
1492
1493 if (*when_p) {
David Sedlákb3077192019-06-19 10:55:37 +02001494 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "when");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001495 return LY_EVALID;
1496 }
1497
1498 when = calloc(1, sizeof *when);
Radek Krejci44ceedc2018-10-02 15:54:31 +02001499 LY_CHECK_ERR_RET(!when, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001500
1501 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001502 LY_CHECK_ERR_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len), free(when), LY_EMEM);
Michal Vaskob36053d2020-03-26 15:49:30 +01001503 CHECK_NONEMPTY(ctx, word_len, "when");
Radek Krejci44ceedc2018-10-02 15:54:31 +02001504 INSERT_WORD(ctx, buf, when->cond, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001505
Radek Krejcif09e4e82019-06-14 15:08:11 +02001506 *when_p = when;
1507
Michal Vaskod989ba02020-08-24 10:59:24 +02001508 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001509 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001510 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02001511 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &when->dsc, Y_STR_ARG, &when->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001512 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001513 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001514 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &when->ref, Y_STR_ARG, &when->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001515 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001516 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001517 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &when->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001518 break;
1519 default:
David Sedlákb3077192019-06-19 10:55:37 +02001520 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "when");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001521 return LY_EVALID;
1522 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001523 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001524 return ret;
1525}
1526
Michal Vaskoea5abea2018-09-18 13:10:54 +02001527/**
1528 * @brief Parse the anydata or anyxml statement.
1529 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001530 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001531 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001532 * @param[in] kw Type of this particular keyword.
1533 * @param[in,out] siblings Siblings to add to.
1534 *
1535 * @return LY_ERR values.
1536 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02001537LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001538parse_any(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt kw, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001539{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001540 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001541 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001542 size_t word_len;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001543 struct lysp_node_anydata *any;
1544
David Sedlák60adc092019-08-06 15:57:02 +02001545 /* create new structure and insert into siblings */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02001546 LY_LIST_NEW_RET(ctx->ctx, siblings, any, next, LY_EMEM);
David Sedlák60adc092019-08-06 15:57:02 +02001547
Radek Krejcid6b76452019-09-03 17:03:03 +02001548 any->nodetype = kw == LY_STMT_ANYDATA ? LYS_ANYDATA : LYS_ANYXML;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001549 any->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001550
Michal Vasko7fbc8162018-09-17 10:35:16 +02001551 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02001552 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02001553 INSERT_WORD(ctx, buf, any->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001554
1555 /* parse substatements */
Michal Vaskod989ba02020-08-24 10:59:24 +02001556 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001557 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001558 case LY_STMT_CONFIG:
Michal Vasko63f3d842020-07-08 10:10:14 +02001559 LY_CHECK_RET(parse_config(ctx, in, &any->flags, &any->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001560 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001561 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02001562 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &any->dsc, Y_STR_ARG, &any->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001563 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001564 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001565 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &any->iffeatures, Y_STR_ARG, &any->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001566 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001567 case LY_STMT_MANDATORY:
Michal Vasko63f3d842020-07-08 10:10:14 +02001568 LY_CHECK_RET(parse_mandatory(ctx, in, &any->flags, &any->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001569 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001570 case LY_STMT_MUST:
Michal Vasko63f3d842020-07-08 10:10:14 +02001571 LY_CHECK_RET(parse_restrs(ctx, in, kw, &any->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001572 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001573 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001574 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &any->ref, Y_STR_ARG, &any->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001575 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001576 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02001577 LY_CHECK_RET(parse_status(ctx, in, &any->flags, &any->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001578 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001579 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02001580 LY_CHECK_RET(parse_when(ctx, in, &any->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001581 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001582 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001583 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &any->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001584 break;
1585 default:
David Sedlákb3077192019-06-19 10:55:37 +02001586 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw),
Radek Krejci0f969882020-08-21 16:56:47 +02001587 (any->nodetype & LYS_ANYDATA) == LYS_ANYDATA ? ly_stmt2str(LY_STMT_ANYDATA) : ly_stmt2str(LY_STMT_ANYXML));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001588 return LY_EVALID;
1589 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001590 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001591 return ret;
1592}
1593
Michal Vaskoea5abea2018-09-18 13:10:54 +02001594/**
1595 * @brief Parse the value or position statement. Substatement of type enum statement.
1596 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001597 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001598 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001599 * @param[in] val_kw Type of this particular keyword.
1600 * @param[in,out] value Value to write to.
1601 * @param[in,out] flags Flags to write to.
1602 * @param[in,out] exts Extension instances to add to.
1603 *
1604 * @return LY_ERR values.
1605 */
David Sedlákd6ce6d72019-07-16 17:30:18 +02001606LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001607parse_type_enum_value_pos(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt val_kw, int64_t *value, uint16_t *flags,
Radek Krejci0f969882020-08-21 16:56:47 +02001608 struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001609{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001610 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001611 char *buf, *word, *ptr;
Radek Krejciefd22f62018-09-27 11:47:58 +02001612 size_t word_len;
Radek Krejci4ad42aa2019-07-23 16:55:58 +02001613 long int num = 0;
1614 unsigned long int unum = 0;
Radek Krejcid6b76452019-09-03 17:03:03 +02001615 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001616
1617 if (*flags & LYS_SET_VALUE) {
David Sedlákb3077192019-06-19 10:55:37 +02001618 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(val_kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001619 return LY_EVALID;
1620 }
1621 *flags |= LYS_SET_VALUE;
1622
1623 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001624 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001625
Radek Krejcid6b76452019-09-03 17:03:03 +02001626 if (!word_len || (word[0] == '+') || ((word[0] == '0') && (word_len > 1)) || ((val_kw == LY_STMT_POSITION) && !strncmp(word, "-0", 2))) {
David Sedlákb3077192019-06-19 10:55:37 +02001627 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
Radek Krejci8b764662018-11-14 14:15:13 +01001628 goto error;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001629 }
1630
1631 errno = 0;
Radek Krejcid6b76452019-09-03 17:03:03 +02001632 if (val_kw == LY_STMT_VALUE) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001633 num = strtol(word, &ptr, 10);
Radek Krejci8b764662018-11-14 14:15:13 +01001634 if (num < INT64_C(-2147483648) || num > INT64_C(2147483647)) {
David Sedlákb3077192019-06-19 10:55:37 +02001635 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
Radek Krejci8b764662018-11-14 14:15:13 +01001636 goto error;
1637 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001638 } else {
1639 unum = strtoul(word, &ptr, 10);
Radek Krejci8b764662018-11-14 14:15:13 +01001640 if (unum > UINT64_C(4294967295)) {
David Sedlákb3077192019-06-19 10:55:37 +02001641 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
Radek Krejci8b764662018-11-14 14:15:13 +01001642 goto error;
1643 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001644 }
1645 /* we have not parsed the whole argument */
Radek Krejciefd22f62018-09-27 11:47:58 +02001646 if ((size_t)(ptr - word) != word_len) {
David Sedlákb3077192019-06-19 10:55:37 +02001647 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, ly_stmt2str(val_kw));
Radek Krejci8b764662018-11-14 14:15:13 +01001648 goto error;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001649 }
1650 if (errno == ERANGE) {
David Sedlákb3077192019-06-19 10:55:37 +02001651 LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, ly_stmt2str(val_kw));
Radek Krejci8b764662018-11-14 14:15:13 +01001652 goto error;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001653 }
Radek Krejcid6b76452019-09-03 17:03:03 +02001654 if (val_kw == LY_STMT_VALUE) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001655 *value = num;
1656 } else {
1657 *value = unum;
1658 }
1659 free(buf);
1660
Michal Vaskod989ba02020-08-24 10:59:24 +02001661 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001662 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001663 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001664 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, val_kw == LY_STMT_VALUE ? LYEXT_SUBSTMT_VALUE : LYEXT_SUBSTMT_POSITION, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001665 break;
1666 default:
David Sedlákb3077192019-06-19 10:55:37 +02001667 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(val_kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001668 return LY_EVALID;
1669 }
1670 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001671 return ret;
Radek Krejci8b764662018-11-14 14:15:13 +01001672
1673error:
1674 free(buf);
1675 return LY_EVALID;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001676}
1677
Michal Vaskoea5abea2018-09-18 13:10:54 +02001678/**
1679 * @brief Parse the enum or bit statement. Substatement of type statement.
1680 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001681 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001682 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001683 * @param[in] enum_kw Type of this particular keyword.
1684 * @param[in,out] enums Enums or bits to add to.
1685 *
1686 * @return LY_ERR values.
1687 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001688static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001689parse_type_enum(struct lys_yang_parser_ctx *ctx, struct ly_in *in, enum ly_stmt enum_kw, struct lysp_type_enum **enums)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001690{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001691 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001692 char *buf, *word;
David Sedlák6544c182019-07-12 13:17:33 +02001693 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001694 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001695 struct lysp_type_enum *enm;
1696
Radek Krejci2c4e7172018-10-19 15:56:26 +02001697 LY_ARRAY_NEW_RET(ctx->ctx, *enums, enm, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001698
1699 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001700 LY_CHECK_RET(get_argument(ctx, in, enum_kw == LY_STMT_ENUM ? Y_STR_ARG : Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejcid6b76452019-09-03 17:03:03 +02001701 if (enum_kw == LY_STMT_ENUM) {
Michal Vaskob36053d2020-03-26 15:49:30 +01001702 ret = lysp_check_enum_name((struct lys_parser_ctx *)ctx, (const char *)word, word_len);
David Sedlák6544c182019-07-12 13:17:33 +02001703 LY_CHECK_ERR_RET(ret, free(buf), ret);
Radek Krejci335332a2019-09-05 13:03:35 +02001704 } /* else nothing specific for YANG_BIT */
Radek Krejci8b764662018-11-14 14:15:13 +01001705
Radek Krejci44ceedc2018-10-02 15:54:31 +02001706 INSERT_WORD(ctx, buf, enm->name, word, word_len);
Radek Krejci8b764662018-11-14 14:15:13 +01001707 CHECK_UNIQUENESS(ctx, *enums, name, ly_stmt2str(enum_kw), enm->name);
1708
Michal Vaskod989ba02020-08-24 10:59:24 +02001709 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001710 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001711 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02001712 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001713 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001714 case LY_STMT_IF_FEATURE:
Radek Krejci335332a2019-09-05 13:03:35 +02001715 PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", ly_stmt2str(enum_kw));
Michal Vasko63f3d842020-07-08 10:10:14 +02001716 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &enm->iffeatures, Y_STR_ARG, &enm->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001717 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001718 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001719 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &enm->ref, Y_STR_ARG, &enm->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001720 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001721 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02001722 LY_CHECK_RET(parse_status(ctx, in, &enm->flags, &enm->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001723 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001724 case LY_STMT_VALUE:
1725 LY_CHECK_ERR_RET(enum_kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw),
David Sedlák9fb515f2019-07-11 10:33:58 +02001726 ly_stmt2str(enum_kw)), LY_EVALID);
Michal Vasko63f3d842020-07-08 10:10:14 +02001727 LY_CHECK_RET(parse_type_enum_value_pos(ctx, in, kw, &enm->value, &enm->flags, &enm->exts));
David Sedlák9fb515f2019-07-11 10:33:58 +02001728 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001729 case LY_STMT_POSITION:
1730 LY_CHECK_ERR_RET(enum_kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw),
David Sedlák9fb515f2019-07-11 10:33:58 +02001731 ly_stmt2str(enum_kw)), LY_EVALID);
Michal Vasko63f3d842020-07-08 10:10:14 +02001732 LY_CHECK_RET(parse_type_enum_value_pos(ctx, in, kw, &enm->value, &enm->flags, &enm->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001733 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001734 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001735 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &enm->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001736 break;
1737 default:
David Sedlákb3077192019-06-19 10:55:37 +02001738 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(enum_kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001739 return LY_EVALID;
1740 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001741 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001742 return ret;
1743}
1744
Michal Vaskoea5abea2018-09-18 13:10:54 +02001745/**
1746 * @brief Parse the fraction-digits statement. Substatement of type statement.
1747 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001748 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001749 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001750 * @param[in,out] fracdig Value to write to.
1751 * @param[in,out] exts Extension instances to add to.
1752 *
1753 * @return LY_ERR values.
1754 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001755static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001756parse_type_fracdigits(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint8_t *fracdig, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001757{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001758 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001759 char *buf, *word, *ptr;
Radek Krejciefd22f62018-09-27 11:47:58 +02001760 size_t word_len;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001761 unsigned long int num;
Radek Krejcid6b76452019-09-03 17:03:03 +02001762 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001763
1764 if (*fracdig) {
David Sedlákb3077192019-06-19 10:55:37 +02001765 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "fraction-digits");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001766 return LY_EVALID;
1767 }
1768
1769 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001770 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001771
1772 if (!word_len || (word[0] == '0') || !isdigit(word[0])) {
David Sedlákb3077192019-06-19 10:55:37 +02001773 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "fraction-digits");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001774 free(buf);
1775 return LY_EVALID;
1776 }
1777
1778 errno = 0;
1779 num = strtoul(word, &ptr, 10);
1780 /* we have not parsed the whole argument */
Radek Krejciefd22f62018-09-27 11:47:58 +02001781 if ((size_t)(ptr - word) != word_len) {
David Sedlákb3077192019-06-19 10:55:37 +02001782 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "fraction-digits");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001783 free(buf);
1784 return LY_EVALID;
1785 }
1786 if ((errno == ERANGE) || (num > 18)) {
David Sedlákb3077192019-06-19 10:55:37 +02001787 LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, "fraction-digits");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001788 free(buf);
1789 return LY_EVALID;
1790 }
1791 *fracdig = num;
1792 free(buf);
1793
Michal Vaskod989ba02020-08-24 10:59:24 +02001794 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001795 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001796 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001797 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_FRACDIGITS, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001798 break;
1799 default:
David Sedlákb3077192019-06-19 10:55:37 +02001800 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "fraction-digits");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001801 return LY_EVALID;
1802 }
1803 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001804 return ret;
1805}
1806
Michal Vaskoea5abea2018-09-18 13:10:54 +02001807/**
1808 * @brief Parse the require-instance statement. Substatement of type statement.
1809 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001810 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001811 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001812 * @param[in,out] reqinst Value to write to.
1813 * @param[in,out] flags Flags to write to.
1814 * @param[in,out] exts Extension instances to add to.
1815 *
1816 * @return LY_ERR values.
1817 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001818static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001819parse_type_reqinstance(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint8_t *reqinst, uint16_t *flags,
Radek Krejci0f969882020-08-21 16:56:47 +02001820 struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001821{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001822 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001823 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001824 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001825 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001826
1827 if (*flags & LYS_SET_REQINST) {
David Sedlákb3077192019-06-19 10:55:37 +02001828 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "require-instance");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001829 return LY_EVALID;
1830 }
1831 *flags |= LYS_SET_REQINST;
1832
1833 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001834 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001835
1836 if ((word_len == 4) && !strncmp(word, "true", word_len)) {
1837 *reqinst = 1;
1838 } else if ((word_len != 5) || strncmp(word, "false", word_len)) {
David Sedlákb3077192019-06-19 10:55:37 +02001839 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "require-instance");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001840 free(buf);
1841 return LY_EVALID;
1842 }
1843 free(buf);
1844
Michal Vaskod989ba02020-08-24 10:59:24 +02001845 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001846 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001847 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001848 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_REQINSTANCE, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001849 break;
1850 default:
David Sedlákb3077192019-06-19 10:55:37 +02001851 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "require-instance");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001852 return LY_EVALID;
1853 }
1854 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001855 return ret;
1856}
1857
Michal Vaskoea5abea2018-09-18 13:10:54 +02001858/**
1859 * @brief Parse the modifier statement. Substatement of type pattern statement.
1860 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001861 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001862 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001863 * @param[in,out] pat Value to write to.
1864 * @param[in,out] exts Extension instances to add to.
1865 *
1866 * @return LY_ERR values.
1867 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001868static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001869parse_type_pattern_modifier(struct lys_yang_parser_ctx *ctx, struct ly_in *in, const char **pat,
Radek Krejci0f969882020-08-21 16:56:47 +02001870 struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001871{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001872 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001873 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001874 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001875 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001876
1877 if ((*pat)[0] == 0x15) {
David Sedlákb3077192019-06-19 10:55:37 +02001878 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "modifier");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001879 return LY_EVALID;
1880 }
1881
1882 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001883 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001884
1885 if ((word_len != 12) || strncmp(word, "invert-match", word_len)) {
David Sedlákb3077192019-06-19 10:55:37 +02001886 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "modifier");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001887 free(buf);
1888 return LY_EVALID;
1889 }
1890 free(buf);
1891
1892 /* replace the value in the dictionary */
1893 buf = malloc(strlen(*pat) + 1);
Radek Krejci44ceedc2018-10-02 15:54:31 +02001894 LY_CHECK_ERR_RET(!buf, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001895 strcpy(buf, *pat);
Radek Krejci44ceedc2018-10-02 15:54:31 +02001896 lydict_remove(ctx->ctx, *pat);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001897
1898 assert(buf[0] == 0x06);
1899 buf[0] = 0x15;
Radek Krejci44ceedc2018-10-02 15:54:31 +02001900 *pat = lydict_insert_zc(ctx->ctx, buf);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001901
Michal Vaskod989ba02020-08-24 10:59:24 +02001902 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001903 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001904 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001905 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_MODIFIER, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001906 break;
1907 default:
David Sedlákb3077192019-06-19 10:55:37 +02001908 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "modifier");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001909 return LY_EVALID;
1910 }
1911 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001912 return ret;
1913}
1914
Michal Vaskoea5abea2018-09-18 13:10:54 +02001915/**
1916 * @brief Parse the pattern statement. Substatement of type statement.
1917 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001918 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001919 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001920 * @param[in,out] patterns Restrictions to add to.
1921 *
1922 * @return LY_ERR values.
1923 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001924static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001925parse_type_pattern(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_restr **patterns)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001926{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001927 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001928 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02001929 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001930 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001931 struct lysp_restr *restr;
1932
Radek Krejci2c4e7172018-10-19 15:56:26 +02001933 LY_ARRAY_NEW_RET(ctx->ctx, *patterns, restr, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001934
1935 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02001936 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001937
1938 /* add special meaning first byte */
1939 if (buf) {
1940 buf = realloc(buf, word_len + 2);
1941 word = buf;
1942 } else {
1943 buf = malloc(word_len + 2);
1944 }
Radek Krejci44ceedc2018-10-02 15:54:31 +02001945 LY_CHECK_ERR_RET(!buf, LOGMEM(ctx->ctx), LY_EMEM);
Radek Krejci86d106e2018-10-18 09:53:19 +02001946 memmove(buf + 1, word, word_len);
1947 buf[0] = 0x06; /* pattern's default regular-match flag */
1948 buf[word_len + 1] = '\0'; /* terminating NULL byte */
1949 restr->arg = lydict_insert_zc(ctx->ctx, buf);
Michal Vasko7fbc8162018-09-17 10:35:16 +02001950
Michal Vaskod989ba02020-08-24 10:59:24 +02001951 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02001952 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02001953 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02001954 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001955 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001956 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001957 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &restr->ref, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001958 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001959 case LY_STMT_ERROR_APP_TAG:
Michal Vasko63f3d842020-07-08 10:10:14 +02001960 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_ERRTAG, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001961 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001962 case LY_STMT_ERROR_MESSAGE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001963 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_ERRMSG, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001964 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001965 case LY_STMT_MODIFIER:
Radek Krejci335332a2019-09-05 13:03:35 +02001966 PARSER_CHECK_STMTVER2_RET(ctx, "modifier", "pattern");
Michal Vasko63f3d842020-07-08 10:10:14 +02001967 LY_CHECK_RET(parse_type_pattern_modifier(ctx, in, &restr->arg, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001968 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02001969 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02001970 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &restr->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02001971 break;
1972 default:
David Sedlákb3077192019-06-19 10:55:37 +02001973 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "pattern");
Michal Vasko7fbc8162018-09-17 10:35:16 +02001974 return LY_EVALID;
1975 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001976 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02001977 return ret;
1978}
1979
Michal Vaskoea5abea2018-09-18 13:10:54 +02001980/**
1981 * @brief Parse the type statement.
1982 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02001983 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02001984 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02001985 * @param[in,out] type Type to wrote to.
1986 *
1987 * @return LY_ERR values.
1988 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02001989static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02001990parse_type(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_type *type)
Michal Vasko7fbc8162018-09-17 10:35:16 +02001991{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01001992 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001993 char *buf, *word;
Michal Vasko004d3152020-06-11 19:59:22 +02001994 const char *str_path = NULL;
Radek Krejciefd22f62018-09-27 11:47:58 +02001995 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02001996 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02001997 struct lysp_type *nest_type;
1998
1999 if (type->name) {
David Sedlákb3077192019-06-19 10:55:37 +02002000 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "type");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002001 return LY_EVALID;
2002 }
2003
2004 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002005 LY_CHECK_RET(get_argument(ctx, in, Y_PREF_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02002006 INSERT_WORD(ctx, buf, type->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002007
Michal Vaskod989ba02020-08-24 10:59:24 +02002008 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002009 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002010 case LY_STMT_BASE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002011 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_BASE, &type->bases, Y_PREF_IDENTIF_ARG, &type->exts));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002012 type->flags |= LYS_SET_BASE;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002013 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002014 case LY_STMT_BIT:
Michal Vasko63f3d842020-07-08 10:10:14 +02002015 LY_CHECK_RET(parse_type_enum(ctx, in, kw, &type->bits));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002016 type->flags |= LYS_SET_BIT;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002017 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002018 case LY_STMT_ENUM:
Michal Vasko63f3d842020-07-08 10:10:14 +02002019 LY_CHECK_RET(parse_type_enum(ctx, in, kw, &type->enums));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002020 type->flags |= LYS_SET_ENUM;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002021 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002022 case LY_STMT_FRACTION_DIGITS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002023 LY_CHECK_RET(parse_type_fracdigits(ctx, in, &type->fraction_digits, &type->exts));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002024 type->flags |= LYS_SET_FRDIGITS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002025 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002026 case LY_STMT_LENGTH:
Michal Vasko7fbc8162018-09-17 10:35:16 +02002027 if (type->length) {
David Sedlákb3077192019-06-19 10:55:37 +02002028 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002029 return LY_EVALID;
2030 }
2031 type->length = calloc(1, sizeof *type->length);
Radek Krejci44ceedc2018-10-02 15:54:31 +02002032 LY_CHECK_ERR_RET(!type->length, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002033
Michal Vasko63f3d842020-07-08 10:10:14 +02002034 LY_CHECK_RET(parse_restr(ctx, in, kw, type->length));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002035 type->flags |= LYS_SET_LENGTH;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002036 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002037 case LY_STMT_PATH:
Michal Vasko004d3152020-06-11 19:59:22 +02002038 if (type->path) {
2039 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyext_substmt2str(LYEXT_SUBSTMT_PATH));
2040 return LY_EVALID;
2041 }
2042
Michal Vasko63f3d842020-07-08 10:10:14 +02002043 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_PATH, 0, &str_path, Y_STR_ARG, &type->exts));
Michal Vasko6b26e742020-07-17 15:02:10 +02002044 ret = ly_path_parse(ctx->ctx, NULL, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
Michal Vasko004d3152020-06-11 19:59:22 +02002045 LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
2046 lydict_remove(ctx->ctx, str_path);
2047 LY_CHECK_RET(ret);
Radek Krejcid505e3d2018-11-13 09:04:17 +01002048 type->flags |= LYS_SET_PATH;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002049 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002050 case LY_STMT_PATTERN:
Michal Vasko63f3d842020-07-08 10:10:14 +02002051 LY_CHECK_RET(parse_type_pattern(ctx, in, &type->patterns));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002052 type->flags |= LYS_SET_PATTERN;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002053 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002054 case LY_STMT_RANGE:
Michal Vasko7fbc8162018-09-17 10:35:16 +02002055 if (type->range) {
David Sedlákb3077192019-06-19 10:55:37 +02002056 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002057 return LY_EVALID;
2058 }
2059 type->range = calloc(1, sizeof *type->range);
David Sedlák7a8b2472019-07-11 15:08:34 +02002060 LY_CHECK_ERR_RET(!type->range, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002061
Michal Vasko63f3d842020-07-08 10:10:14 +02002062 LY_CHECK_RET(parse_restr(ctx, in, kw, type->range));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002063 type->flags |= LYS_SET_RANGE;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002064 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002065 case LY_STMT_REQUIRE_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002066 LY_CHECK_RET(parse_type_reqinstance(ctx, in, &type->require_instance, &type->flags, &type->exts));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002067 /* LYS_SET_REQINST checked and set inside parse_type_reqinstance() */
Michal Vasko7fbc8162018-09-17 10:35:16 +02002068 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002069 case LY_STMT_TYPE:
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002070 LY_ARRAY_NEW_RET(ctx->ctx, type->types, nest_type, LY_EMEM);
Michal Vasko63f3d842020-07-08 10:10:14 +02002071 LY_CHECK_RET(parse_type(ctx, in, nest_type));
Radek Krejcid505e3d2018-11-13 09:04:17 +01002072 type->flags |= LYS_SET_TYPE;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002073 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002074 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002075 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &type->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002076 break;
2077 default:
David Sedlákb3077192019-06-19 10:55:37 +02002078 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "type");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002079 return LY_EVALID;
2080 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002081 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002082 return ret;
2083}
2084
Michal Vaskoea5abea2018-09-18 13:10:54 +02002085/**
2086 * @brief Parse the leaf statement.
2087 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002088 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002089 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002090 * @param[in,out] siblings Siblings to add to.
2091 *
2092 * @return LY_ERR values.
2093 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002094LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002095parse_leaf(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002096{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002097 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002098 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002099 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002100 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002101 struct lysp_node_leaf *leaf;
2102
David Sedlák60adc092019-08-06 15:57:02 +02002103 /* create new leaf structure */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02002104 LY_LIST_NEW_RET(ctx->ctx, siblings, leaf, next, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002105 leaf->nodetype = LYS_LEAF;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002106 leaf->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002107
Michal Vasko7fbc8162018-09-17 10:35:16 +02002108 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02002109 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02002110 INSERT_WORD(ctx, buf, leaf->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002111
2112 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02002113 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002114 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002115 case LY_STMT_CONFIG:
Michal Vasko63f3d842020-07-08 10:10:14 +02002116 LY_CHECK_RET(parse_config(ctx, in, &leaf->flags, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002117 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002118 case LY_STMT_DEFAULT:
Michal Vasko63f3d842020-07-08 10:10:14 +02002119 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &leaf->dflt, Y_STR_ARG, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002120 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002121 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002122 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &leaf->dsc, Y_STR_ARG, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002123 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002124 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002125 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &leaf->iffeatures, Y_STR_ARG, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002126 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002127 case LY_STMT_MANDATORY:
Michal Vasko63f3d842020-07-08 10:10:14 +02002128 LY_CHECK_RET(parse_mandatory(ctx, in, &leaf->flags, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002129 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002130 case LY_STMT_MUST:
Michal Vasko63f3d842020-07-08 10:10:14 +02002131 LY_CHECK_RET(parse_restrs(ctx, in, kw, &leaf->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002132 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002133 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002134 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &leaf->ref, Y_STR_ARG, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002135 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002136 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002137 LY_CHECK_RET(parse_status(ctx, in, &leaf->flags, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002138 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002139 case LY_STMT_TYPE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002140 LY_CHECK_RET(parse_type(ctx, in, &leaf->type));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002141 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002142 case LY_STMT_UNITS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002143 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_UNITS, 0, &leaf->units, Y_STR_ARG, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002144 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002145 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02002146 LY_CHECK_RET(parse_when(ctx, in, &leaf->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002147 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002148 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002149 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &leaf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002150 break;
2151 default:
David Sedlákb3077192019-06-19 10:55:37 +02002152 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "leaf");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002153 return LY_EVALID;
2154 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002155 }
Radek Krejcic59bc972018-09-17 16:13:06 +02002156 LY_CHECK_RET(ret);
Radek Krejci6d6556c2018-11-08 09:37:45 +01002157checks:
Michal Vasko7fbc8162018-09-17 10:35:16 +02002158 /* mandatory substatements */
2159 if (!leaf->type.name) {
David Sedlákb3077192019-06-19 10:55:37 +02002160 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002161 return LY_EVALID;
2162 }
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01002163 if ((leaf->flags & LYS_MAND_TRUE) && (leaf->dflt)) {
David Sedlákb3077192019-06-19 10:55:37 +02002164 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMSCOMB, "mandatory", "default", "leaf");
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01002165 return LY_EVALID;
2166 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002167
2168 return ret;
2169}
2170
Michal Vaskoea5abea2018-09-18 13:10:54 +02002171/**
2172 * @brief Parse the max-elements statement.
2173 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002174 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002175 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002176 * @param[in,out] max Value to write to.
2177 * @param[in,out] flags Flags to write to.
2178 * @param[in,out] exts Extension instances to add to.
2179 *
2180 * @return LY_ERR values.
2181 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002182LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002183parse_maxelements(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint32_t *max, uint16_t *flags,
Radek Krejci0f969882020-08-21 16:56:47 +02002184 struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002185{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002186 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002187 char *buf, *word, *ptr;
Radek Krejciefd22f62018-09-27 11:47:58 +02002188 size_t word_len;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002189 unsigned long int num;
Radek Krejcid6b76452019-09-03 17:03:03 +02002190 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002191
2192 if (*flags & LYS_SET_MAX) {
David Sedlákb3077192019-06-19 10:55:37 +02002193 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "max-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002194 return LY_EVALID;
2195 }
2196 *flags |= LYS_SET_MAX;
2197
2198 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002199 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002200
2201 if (!word_len || (word[0] == '0') || ((word[0] != 'u') && !isdigit(word[0]))) {
David Sedlákb3077192019-06-19 10:55:37 +02002202 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "max-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002203 free(buf);
2204 return LY_EVALID;
2205 }
2206
Radek Krejci7f9b6512019-09-18 13:11:09 +02002207 if (ly_strncmp("unbounded", word, word_len)) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002208 errno = 0;
2209 num = strtoul(word, &ptr, 10);
2210 /* we have not parsed the whole argument */
Radek Krejciefd22f62018-09-27 11:47:58 +02002211 if ((size_t)(ptr - word) != word_len) {
David Sedlákb3077192019-06-19 10:55:37 +02002212 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "max-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002213 free(buf);
2214 return LY_EVALID;
2215 }
2216 if ((errno == ERANGE) || (num > UINT32_MAX)) {
David Sedlákb3077192019-06-19 10:55:37 +02002217 LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, "max-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002218 free(buf);
2219 return LY_EVALID;
2220 }
2221
2222 *max = num;
2223 }
2224 free(buf);
2225
Michal Vaskod989ba02020-08-24 10:59:24 +02002226 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002227 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002228 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002229 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_MAX, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002230 break;
2231 default:
David Sedlákb3077192019-06-19 10:55:37 +02002232 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "max-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002233 return LY_EVALID;
2234 }
2235 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002236 return ret;
2237}
2238
Michal Vaskoea5abea2018-09-18 13:10:54 +02002239/**
2240 * @brief Parse the min-elements statement.
2241 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002242 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002243 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002244 * @param[in,out] min Value to write to.
2245 * @param[in,out] flags Flags to write to.
2246 * @param[in,out] exts Extension instances to add to.
2247 *
2248 * @return LY_ERR values.
2249 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002250LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002251parse_minelements(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint32_t *min, uint16_t *flags,
Radek Krejci0f969882020-08-21 16:56:47 +02002252 struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002253{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002254 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002255 char *buf, *word, *ptr;
Radek Krejciefd22f62018-09-27 11:47:58 +02002256 size_t word_len;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002257 unsigned long int num;
Radek Krejcid6b76452019-09-03 17:03:03 +02002258 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002259
2260 if (*flags & LYS_SET_MIN) {
David Sedlákb3077192019-06-19 10:55:37 +02002261 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "min-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002262 return LY_EVALID;
2263 }
2264 *flags |= LYS_SET_MIN;
2265
2266 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002267 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002268
2269 if (!word_len || !isdigit(word[0]) || ((word[0] == '0') && (word_len > 1))) {
David Sedlákb3077192019-06-19 10:55:37 +02002270 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "min-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002271 free(buf);
2272 return LY_EVALID;
2273 }
2274
2275 errno = 0;
2276 num = strtoul(word, &ptr, 10);
2277 /* we have not parsed the whole argument */
Radek Krejciefd22f62018-09-27 11:47:58 +02002278 if ((size_t)(ptr - word) != word_len) {
David Sedlákb3077192019-06-19 10:55:37 +02002279 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "min-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002280 free(buf);
2281 return LY_EVALID;
2282 }
2283 if ((errno == ERANGE) || (num > UINT32_MAX)) {
David Sedlákb3077192019-06-19 10:55:37 +02002284 LOGVAL_PARSER(ctx, LY_VCODE_OOB, word_len, word, "min-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002285 free(buf);
2286 return LY_EVALID;
2287 }
2288 *min = num;
2289 free(buf);
2290
Michal Vaskod989ba02020-08-24 10:59:24 +02002291 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002292 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002293 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002294 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_MIN, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002295 break;
2296 default:
David Sedlákb3077192019-06-19 10:55:37 +02002297 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "min-elements");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002298 return LY_EVALID;
2299 }
2300 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002301 return ret;
2302}
2303
Michal Vaskoea5abea2018-09-18 13:10:54 +02002304/**
2305 * @brief Parse the ordered-by statement.
2306 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002307 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002308 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002309 * @param[in,out] flags Flags to write to.
2310 * @param[in,out] exts Extension instances to add to.
2311 *
2312 * @return LY_ERR values.
2313 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02002314static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002315parse_orderedby(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint16_t *flags, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002316{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002317 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002318 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002319 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002320 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002321
2322 if (*flags & LYS_ORDBY_MASK) {
David Sedlákb3077192019-06-19 10:55:37 +02002323 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "ordered-by");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002324 return LY_EVALID;
2325 }
2326
2327 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002328 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002329
2330 if ((word_len == 6) && !strncmp(word, "system", word_len)) {
2331 *flags |= LYS_ORDBY_SYSTEM;
2332 } else if ((word_len == 4) && !strncmp(word, "user", word_len)) {
2333 *flags |= LYS_ORDBY_USER;
2334 } else {
David Sedlákb3077192019-06-19 10:55:37 +02002335 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "ordered-by");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002336 free(buf);
2337 return LY_EVALID;
2338 }
2339 free(buf);
2340
Michal Vaskod989ba02020-08-24 10:59:24 +02002341 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002342 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002343 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002344 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_ORDEREDBY, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002345 break;
2346 default:
David Sedlákb3077192019-06-19 10:55:37 +02002347 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "ordered-by");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002348 return LY_EVALID;
2349 }
2350 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002351 return ret;
2352}
2353
Michal Vaskoea5abea2018-09-18 13:10:54 +02002354/**
2355 * @brief Parse the leaf-list statement.
2356 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002357 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002358 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002359 * @param[in,out] siblings Siblings to add to.
2360 *
2361 * @return LY_ERR values.
2362 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002363LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002364parse_leaflist(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002365{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002366 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002367 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002368 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002369 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002370 struct lysp_node_leaflist *llist;
2371
David Sedlák60adc092019-08-06 15:57:02 +02002372 /* create new leaf-list structure */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02002373 LY_LIST_NEW_RET(ctx->ctx, siblings, llist, next, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002374 llist->nodetype = LYS_LEAFLIST;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002375 llist->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002376
Michal Vasko7fbc8162018-09-17 10:35:16 +02002377 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02002378 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02002379 INSERT_WORD(ctx, buf, llist->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002380
2381 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02002382 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002383 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002384 case LY_STMT_CONFIG:
Michal Vasko63f3d842020-07-08 10:10:14 +02002385 LY_CHECK_RET(parse_config(ctx, in, &llist->flags, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002386 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002387 case LY_STMT_DEFAULT:
Radek Krejci335332a2019-09-05 13:03:35 +02002388 PARSER_CHECK_STMTVER2_RET(ctx, "default", "leaf-list");
Michal Vasko63f3d842020-07-08 10:10:14 +02002389 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_DEFAULT, &llist->dflts, Y_STR_ARG, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002390 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002391 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002392 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &llist->dsc, Y_STR_ARG, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002393 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002394 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002395 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &llist->iffeatures, Y_STR_ARG, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002396 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002397 case LY_STMT_MAX_ELEMENTS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002398 LY_CHECK_RET(parse_maxelements(ctx, in, &llist->max, &llist->flags, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002399 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002400 case LY_STMT_MIN_ELEMENTS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002401 LY_CHECK_RET(parse_minelements(ctx, in, &llist->min, &llist->flags, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002402 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002403 case LY_STMT_MUST:
Michal Vasko63f3d842020-07-08 10:10:14 +02002404 LY_CHECK_RET(parse_restrs(ctx, in, kw, &llist->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002405 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002406 case LY_STMT_ORDERED_BY:
Michal Vasko63f3d842020-07-08 10:10:14 +02002407 LY_CHECK_RET(parse_orderedby(ctx, in, &llist->flags, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002408 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002409 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002410 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &llist->ref, Y_STR_ARG, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002411 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002412 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002413 LY_CHECK_RET(parse_status(ctx, in, &llist->flags, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002414 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002415 case LY_STMT_TYPE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002416 LY_CHECK_RET(parse_type(ctx, in, &llist->type));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002417 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002418 case LY_STMT_UNITS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002419 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_UNITS, 0, &llist->units, Y_STR_ARG, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002420 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002421 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02002422 LY_CHECK_RET(parse_when(ctx, in, &llist->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002423 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002424 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002425 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &llist->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002426 break;
2427 default:
David Sedlákb3077192019-06-19 10:55:37 +02002428 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "llist");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002429 return LY_EVALID;
2430 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002431 }
Radek Krejcic59bc972018-09-17 16:13:06 +02002432 LY_CHECK_RET(ret);
Radek Krejci6d6556c2018-11-08 09:37:45 +01002433checks:
Michal Vasko7fbc8162018-09-17 10:35:16 +02002434 /* mandatory substatements */
2435 if (!llist->type.name) {
David Sedlákb3077192019-06-19 10:55:37 +02002436 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf-list");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002437 return LY_EVALID;
2438 }
Radek Krejci0e5d8382018-11-28 16:37:53 +01002439 if ((llist->min) && (llist->dflts)) {
David Sedlákb3077192019-06-19 10:55:37 +02002440 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMSCOMB, "min-elements", "default", "leaf-list");
Radek Krejci0e5d8382018-11-28 16:37:53 +01002441 return LY_EVALID;
2442 }
Radek Krejcidf6cad12018-11-28 17:10:55 +01002443 if (llist->max && llist->min > llist->max) {
David Sedlákb3077192019-06-19 10:55:37 +02002444 LOGVAL_PARSER(ctx, LYVE_SEMANTICS,
Radek Krejcidf6cad12018-11-28 17:10:55 +01002445 "Invalid combination of min-elements and max-elements: min value %u is bigger than the max value %u.",
2446 llist->min, llist->max);
2447 return LY_EVALID;
2448 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002449
2450 return ret;
2451}
2452
Michal Vaskoea5abea2018-09-18 13:10:54 +02002453/**
2454 * @brief Parse the refine statement.
2455 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002456 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002457 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002458 * @param[in,out] refines Refines to add to.
2459 *
2460 * @return LY_ERR values.
2461 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02002462static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002463parse_refine(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_refine **refines)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002464{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002465 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002466 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002467 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002468 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002469 struct lysp_refine *rf;
2470
Radek Krejci2c4e7172018-10-19 15:56:26 +02002471 LY_ARRAY_NEW_RET(ctx->ctx, *refines, rf, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002472
2473 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002474 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vaskob36053d2020-03-26 15:49:30 +01002475 CHECK_NONEMPTY(ctx, word_len, "refine");
Radek Krejci44ceedc2018-10-02 15:54:31 +02002476 INSERT_WORD(ctx, buf, rf->nodeid, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002477
Michal Vaskod989ba02020-08-24 10:59:24 +02002478 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002479 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002480 case LY_STMT_CONFIG:
Michal Vasko63f3d842020-07-08 10:10:14 +02002481 LY_CHECK_RET(parse_config(ctx, in, &rf->flags, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002482 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002483 case LY_STMT_DEFAULT:
Michal Vasko63f3d842020-07-08 10:10:14 +02002484 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_DEFAULT, &rf->dflts, Y_STR_ARG, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002485 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002486 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002487 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &rf->dsc, Y_STR_ARG, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002488 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002489 case LY_STMT_IF_FEATURE:
Radek Krejci335332a2019-09-05 13:03:35 +02002490 PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "refine");
Michal Vasko63f3d842020-07-08 10:10:14 +02002491 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &rf->iffeatures, Y_STR_ARG, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002492 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002493 case LY_STMT_MAX_ELEMENTS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002494 LY_CHECK_RET(parse_maxelements(ctx, in, &rf->max, &rf->flags, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002495 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002496 case LY_STMT_MIN_ELEMENTS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002497 LY_CHECK_RET(parse_minelements(ctx, in, &rf->min, &rf->flags, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002498 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002499 case LY_STMT_MUST:
Michal Vasko63f3d842020-07-08 10:10:14 +02002500 LY_CHECK_RET(parse_restrs(ctx, in, kw, &rf->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002501 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002502 case LY_STMT_MANDATORY:
Michal Vasko63f3d842020-07-08 10:10:14 +02002503 LY_CHECK_RET(parse_mandatory(ctx, in, &rf->flags, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002504 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002505 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002506 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &rf->ref, Y_STR_ARG, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002507 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002508 case LY_STMT_PRESENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002509 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_PRESENCE, 0, &rf->presence, Y_STR_ARG, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002510 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002511 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002512 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &rf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002513 break;
2514 default:
David Sedlákb3077192019-06-19 10:55:37 +02002515 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "refine");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002516 return LY_EVALID;
2517 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002518 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002519 return ret;
2520}
2521
Michal Vaskoea5abea2018-09-18 13:10:54 +02002522/**
2523 * @brief Parse the typedef statement.
2524 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002525 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002526 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002527 * @param[in,out] typedefs Typedefs to add to.
2528 *
2529 * @return LY_ERR values.
2530 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02002531static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002532parse_typedef(struct lys_yang_parser_ctx *ctx, struct lysp_node *parent, struct ly_in *in, struct lysp_tpdf **typedefs)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002533{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002534 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002535 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002536 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002537 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002538 struct lysp_tpdf *tpdf;
2539
Radek Krejci2c4e7172018-10-19 15:56:26 +02002540 LY_ARRAY_NEW_RET(ctx->ctx, *typedefs, tpdf, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002541
2542 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002543 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02002544 INSERT_WORD(ctx, buf, tpdf->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002545
2546 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02002547 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002548 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002549 case LY_STMT_DEFAULT:
Michal Vasko63f3d842020-07-08 10:10:14 +02002550 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &tpdf->dflt, Y_STR_ARG, &tpdf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002551 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002552 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002553 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &tpdf->dsc, Y_STR_ARG, &tpdf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002554 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002555 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002556 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &tpdf->ref, Y_STR_ARG, &tpdf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002557 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002558 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002559 LY_CHECK_RET(parse_status(ctx, in, &tpdf->flags, &tpdf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002560 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002561 case LY_STMT_TYPE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002562 LY_CHECK_RET(parse_type(ctx, in, &tpdf->type));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002563 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002564 case LY_STMT_UNITS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002565 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_UNITS, 0, &tpdf->units, Y_STR_ARG, &tpdf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002566 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002567 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002568 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &tpdf->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002569 break;
2570 default:
David Sedlákb3077192019-06-19 10:55:37 +02002571 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "typedef");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002572 return LY_EVALID;
2573 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002574 }
Radek Krejcic59bc972018-09-17 16:13:06 +02002575 LY_CHECK_RET(ret);
Radek Krejcibbe09a92018-11-08 09:36:54 +01002576checks:
Michal Vasko7fbc8162018-09-17 10:35:16 +02002577 /* mandatory substatements */
2578 if (!tpdf->type.name) {
David Sedlákb3077192019-06-19 10:55:37 +02002579 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "typedef");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002580 return LY_EVALID;
2581 }
2582
Radek Krejcibbe09a92018-11-08 09:36:54 +01002583 /* store data for collision check */
Michal Vasko1bf09392020-03-27 12:38:10 +01002584 if (parent && !(parent->nodetype & (LYS_GROUPING | LYS_RPC | LYS_ACTION | LYS_INOUT | LYS_NOTIF))) {
David Sedláke8b74df2019-08-14 14:18:22 +02002585 LY_CHECK_RET(ly_set_add(&ctx->tpdfs_nodes, parent, 0) == -1, LY_EMEM);
Radek Krejcibbe09a92018-11-08 09:36:54 +01002586 }
2587
Michal Vasko7fbc8162018-09-17 10:35:16 +02002588 return ret;
2589}
2590
Michal Vaskoea5abea2018-09-18 13:10:54 +02002591/**
2592 * @brief Parse the input or output statement.
2593 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002594 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002595 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002596 * @param[in] kw Type of this particular keyword
2597 * @param[in,out] inout_p Input/output pointer to write to.
2598 *
2599 * @return LY_ERR values.
2600 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02002601static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002602parse_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)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002603{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002604 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002605 char *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002606 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002607 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002608
Radek Krejci6eeb58f2019-02-22 16:29:37 +01002609 if (inout_p->nodetype) {
David Sedlákb3077192019-06-19 10:55:37 +02002610 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(inout_kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002611 return LY_EVALID;
2612 }
2613
Radek Krejci6eeb58f2019-02-22 16:29:37 +01002614 /* initiate structure */
Michal Vasko22df3f02020-08-24 13:29:22 +02002615 inout_p->nodetype = &((struct lysp_action *)parent)->input == inout_p ? LYS_INPUT : LYS_OUTPUT;
Radek Krejci6eeb58f2019-02-22 16:29:37 +01002616 inout_p->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002617
2618 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02002619 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002620 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002621 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02002622 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", ly_stmt2str(inout_kw));
Radek Krejci0f969882020-08-21 16:56:47 +02002623 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02002624 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02002625 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)inout_p, &inout_p->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002626 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002627 case LY_STMT_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02002628 LY_CHECK_RET(parse_choice(ctx, in, (struct lysp_node *)inout_p, &inout_p->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002629 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002630 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02002631 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)inout_p, &inout_p->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002632 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002633 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002634 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)inout_p, &inout_p->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002635 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002636 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002637 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)inout_p, &inout_p->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002638 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002639 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002640 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)inout_p, &inout_p->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002641 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002642 case LY_STMT_USES:
Michal Vasko22df3f02020-08-24 13:29:22 +02002643 LY_CHECK_RET(parse_uses(ctx, in, (struct lysp_node *)inout_p, &inout_p->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002644 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002645 case LY_STMT_TYPEDEF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002646 LY_CHECK_RET(parse_typedef(ctx, (struct lysp_node *)inout_p, in, &inout_p->typedefs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002647 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002648 case LY_STMT_MUST:
Radek Krejci335332a2019-09-05 13:03:35 +02002649 PARSER_CHECK_STMTVER2_RET(ctx, "must", ly_stmt2str(inout_kw));
Michal Vasko63f3d842020-07-08 10:10:14 +02002650 LY_CHECK_RET(parse_restrs(ctx, in, kw, &inout_p->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002651 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002652 case LY_STMT_GROUPING:
Michal Vasko22df3f02020-08-24 13:29:22 +02002653 LY_CHECK_RET(parse_grouping(ctx, in, (struct lysp_node *)inout_p, &inout_p->groupings));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002654 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002655 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002656 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &inout_p->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002657 break;
2658 default:
David Sedlákb3077192019-06-19 10:55:37 +02002659 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), ly_stmt2str(inout_kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002660 return LY_EVALID;
2661 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002662 }
Radek Krejci7fc68292019-06-12 13:51:09 +02002663 LY_CHECK_RET(ret);
Michal Vaskob83af8a2020-01-06 09:49:22 +01002664
Radek Krejci7fc68292019-06-12 13:51:09 +02002665checks:
Radek Krejcie86bf772018-12-14 11:39:53 +01002666 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01002667 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, inout_p->groupings, NULL, NULL, NULL));
Radek Krejci7fc68292019-06-12 13:51:09 +02002668
Michal Vaskob83af8a2020-01-06 09:49:22 +01002669 if (!inout_p->data) {
2670 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(inout_kw));
2671 return LY_EVALID;
2672 }
2673
Michal Vasko7fbc8162018-09-17 10:35:16 +02002674 return ret;
2675}
2676
Michal Vaskoea5abea2018-09-18 13:10:54 +02002677/**
2678 * @brief Parse the action statement.
2679 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002680 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002681 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002682 * @param[in,out] actions Actions to add to.
2683 *
2684 * @return LY_ERR values.
2685 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002686LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002687parse_action(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_action **actions)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002688{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002689 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002690 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002691 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002692 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002693 struct lysp_action *act;
2694
Radek Krejci2c4e7172018-10-19 15:56:26 +02002695 LY_ARRAY_NEW_RET(ctx->ctx, *actions, act, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002696
2697 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002698 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02002699 INSERT_WORD(ctx, buf, act->name, word, word_len);
Michal Vasko1bf09392020-03-27 12:38:10 +01002700 act->nodetype = parent ? LYS_ACTION : LYS_RPC;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002701 act->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002702
Michal Vasko63f3d842020-07-08 10:10:14 +02002703 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002704 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002705 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002706 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &act->dsc, Y_STR_ARG, &act->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002707 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002708 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002709 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &act->iffeatures, Y_STR_ARG, &act->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002710 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002711 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002712 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &act->ref, Y_STR_ARG, &act->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002713 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002714 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002715 LY_CHECK_RET(parse_status(ctx, in, &act->flags, &act->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002716 break;
2717
Radek Krejcid6b76452019-09-03 17:03:03 +02002718 case LY_STMT_INPUT:
Michal Vasko22df3f02020-08-24 13:29:22 +02002719 LY_CHECK_RET(parse_inout(ctx, in, kw, (struct lysp_node *)act, &act->input));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002720 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002721 case LY_STMT_OUTPUT:
Michal Vasko22df3f02020-08-24 13:29:22 +02002722 LY_CHECK_RET(parse_inout(ctx, in, kw, (struct lysp_node *)act, &act->output));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002723 break;
2724
Radek Krejcid6b76452019-09-03 17:03:03 +02002725 case LY_STMT_TYPEDEF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002726 LY_CHECK_RET(parse_typedef(ctx, (struct lysp_node *)act, in, &act->typedefs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002727 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002728 case LY_STMT_GROUPING:
Michal Vasko22df3f02020-08-24 13:29:22 +02002729 LY_CHECK_RET(parse_grouping(ctx, in, (struct lysp_node *)act, &act->groupings));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002730 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002731 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002732 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &act->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002733 break;
2734 default:
David Sedlákb3077192019-06-19 10:55:37 +02002735 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), parent ? "action" : "rpc");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002736 return LY_EVALID;
2737 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002738 }
Radek Krejci7fc68292019-06-12 13:51:09 +02002739 LY_CHECK_RET(ret);
2740checks:
Radek Krejcie86bf772018-12-14 11:39:53 +01002741 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01002742 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, act->groupings, NULL, NULL, NULL));
Radek Krejci7fc68292019-06-12 13:51:09 +02002743
Michal Vasko7fbc8162018-09-17 10:35:16 +02002744 return ret;
2745}
2746
Michal Vaskoea5abea2018-09-18 13:10:54 +02002747/**
2748 * @brief Parse the notification statement.
2749 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002750 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002751 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002752 * @param[in,out] notifs Notifications to add to.
2753 *
2754 * @return LY_ERR values.
2755 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002756LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002757parse_notif(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_notif **notifs)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002758{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002759 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002760 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002761 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002762 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002763 struct lysp_notif *notif;
2764
Radek Krejci2c4e7172018-10-19 15:56:26 +02002765 LY_ARRAY_NEW_RET(ctx->ctx, *notifs, notif, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002766
2767 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002768 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02002769 INSERT_WORD(ctx, buf, notif->name, word, word_len);
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002770 notif->nodetype = LYS_NOTIF;
2771 notif->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002772
Michal Vasko63f3d842020-07-08 10:10:14 +02002773 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002774 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002775 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002776 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &notif->dsc, Y_STR_ARG, &notif->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002777 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002778 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002779 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &notif->iffeatures, Y_STR_ARG, &notif->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002780 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002781 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002782 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &notif->ref, Y_STR_ARG, &notif->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002783 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002784 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002785 LY_CHECK_RET(parse_status(ctx, in, &notif->flags, &notif->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002786 break;
2787
Radek Krejcid6b76452019-09-03 17:03:03 +02002788 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02002789 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "notification");
Radek Krejci0f969882020-08-21 16:56:47 +02002790 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02002791 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02002792 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)notif, &notif->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002793 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002794 case LY_STMT_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02002795 LY_CHECK_RET(parse_case(ctx, in, (struct lysp_node *)notif, &notif->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002796 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002797 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02002798 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)notif, &notif->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002799 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002800 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002801 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)notif, &notif->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002802 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002803 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002804 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)notif, &notif->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002805 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002806 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002807 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)notif, &notif->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002808 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002809 case LY_STMT_USES:
Michal Vasko22df3f02020-08-24 13:29:22 +02002810 LY_CHECK_RET(parse_uses(ctx, in, (struct lysp_node *)notif, &notif->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002811 break;
2812
Radek Krejcid6b76452019-09-03 17:03:03 +02002813 case LY_STMT_MUST:
Radek Krejci335332a2019-09-05 13:03:35 +02002814 PARSER_CHECK_STMTVER2_RET(ctx, "must", "notification");
Michal Vasko63f3d842020-07-08 10:10:14 +02002815 LY_CHECK_RET(parse_restrs(ctx, in, kw, &notif->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002816 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002817 case LY_STMT_TYPEDEF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002818 LY_CHECK_RET(parse_typedef(ctx, (struct lysp_node *)notif, in, &notif->typedefs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002819 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002820 case LY_STMT_GROUPING:
Michal Vasko22df3f02020-08-24 13:29:22 +02002821 LY_CHECK_RET(parse_grouping(ctx, in, (struct lysp_node *)notif, &notif->groupings));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002822 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002823 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002824 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &notif->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002825 break;
2826 default:
David Sedlákb3077192019-06-19 10:55:37 +02002827 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "notification");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002828 return LY_EVALID;
2829 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002830 }
Radek Krejci7fc68292019-06-12 13:51:09 +02002831 LY_CHECK_RET(ret);
2832checks:
Radek Krejcie86bf772018-12-14 11:39:53 +01002833 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01002834 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, notif->groupings, NULL, NULL, NULL));
Radek Krejci7fc68292019-06-12 13:51:09 +02002835
Michal Vasko7fbc8162018-09-17 10:35:16 +02002836 return ret;
2837}
2838
Michal Vaskoea5abea2018-09-18 13:10:54 +02002839/**
2840 * @brief Parse the grouping statement.
2841 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002842 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002843 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002844 * @param[in,out] groupings Groupings to add to.
2845 *
2846 * @return LY_ERR values.
2847 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002848LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002849parse_grouping(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_grp **groupings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002850{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002851 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002852 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002853 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002854 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002855 struct lysp_grp *grp;
2856
Radek Krejci2c4e7172018-10-19 15:56:26 +02002857 LY_ARRAY_NEW_RET(ctx->ctx, *groupings, grp, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002858
2859 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002860 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02002861 INSERT_WORD(ctx, buf, grp->name, word, word_len);
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002862 grp->nodetype = LYS_GROUPING;
2863 grp->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002864
Michal Vasko63f3d842020-07-08 10:10:14 +02002865 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002866 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002867 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002868 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &grp->dsc, Y_STR_ARG, &grp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002869 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002870 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002871 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &grp->ref, Y_STR_ARG, &grp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002872 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002873 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002874 LY_CHECK_RET(parse_status(ctx, in, &grp->flags, &grp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002875 break;
2876
Radek Krejcid6b76452019-09-03 17:03:03 +02002877 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02002878 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "grouping");
Radek Krejci0f969882020-08-21 16:56:47 +02002879 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02002880 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02002881 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)grp, &grp->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002882 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002883 case LY_STMT_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02002884 LY_CHECK_RET(parse_choice(ctx, in, (struct lysp_node *)grp, &grp->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002885 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002886 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02002887 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)grp, &grp->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002888 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002889 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002890 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)grp, &grp->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002891 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002892 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002893 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)grp, &grp->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002894 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002895 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002896 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)grp, &grp->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002897 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002898 case LY_STMT_USES:
Michal Vasko22df3f02020-08-24 13:29:22 +02002899 LY_CHECK_RET(parse_uses(ctx, in, (struct lysp_node *)grp, &grp->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002900 break;
2901
Radek Krejcid6b76452019-09-03 17:03:03 +02002902 case LY_STMT_TYPEDEF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002903 LY_CHECK_RET(parse_typedef(ctx, (struct lysp_node *)grp, in, &grp->typedefs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002904 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002905 case LY_STMT_ACTION:
Radek Krejci335332a2019-09-05 13:03:35 +02002906 PARSER_CHECK_STMTVER2_RET(ctx, "action", "grouping");
Michal Vasko22df3f02020-08-24 13:29:22 +02002907 LY_CHECK_RET(parse_action(ctx, in, (struct lysp_node *)grp, &grp->actions));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002908 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002909 case LY_STMT_GROUPING:
Michal Vasko22df3f02020-08-24 13:29:22 +02002910 LY_CHECK_RET(parse_grouping(ctx, in, (struct lysp_node *)grp, &grp->groupings));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002911 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002912 case LY_STMT_NOTIFICATION:
Radek Krejci335332a2019-09-05 13:03:35 +02002913 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "grouping");
Michal Vasko22df3f02020-08-24 13:29:22 +02002914 LY_CHECK_RET(parse_notif(ctx, in, (struct lysp_node *)grp, &grp->notifs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002915 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002916 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002917 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &grp->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002918 break;
2919 default:
David Sedlákb3077192019-06-19 10:55:37 +02002920 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "grouping");
Michal Vasko7fbc8162018-09-17 10:35:16 +02002921 return LY_EVALID;
2922 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02002923 }
Radek Krejci7fc68292019-06-12 13:51:09 +02002924 LY_CHECK_RET(ret);
2925checks:
Radek Krejcie86bf772018-12-14 11:39:53 +01002926 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01002927 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, grp->groupings, NULL, grp->actions, grp->notifs));
Radek Krejci7fc68292019-06-12 13:51:09 +02002928
Michal Vasko7fbc8162018-09-17 10:35:16 +02002929 return ret;
2930}
2931
Michal Vaskoea5abea2018-09-18 13:10:54 +02002932/**
David Sedlák0d6de5a2019-07-22 13:25:44 +02002933 * @brief Parse the augment statement.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002934 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02002935 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02002936 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02002937 * @param[in,out] augments Augments to add to.
2938 *
2939 * @return LY_ERR values.
2940 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02002941LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02002942parse_augment(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_augment **augments)
Michal Vasko7fbc8162018-09-17 10:35:16 +02002943{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002944 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002945 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02002946 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02002947 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002948 struct lysp_augment *aug;
2949
Radek Krejci2c4e7172018-10-19 15:56:26 +02002950 LY_ARRAY_NEW_RET(ctx->ctx, *augments, aug, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02002951
2952 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02002953 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vaskob36053d2020-03-26 15:49:30 +01002954 CHECK_NONEMPTY(ctx, word_len, "augment");
Radek Krejci44ceedc2018-10-02 15:54:31 +02002955 INSERT_WORD(ctx, buf, aug->nodeid, word, word_len);
Radek Krejci6d9b9b52018-11-02 12:43:39 +01002956 aug->nodetype = LYS_AUGMENT;
2957 aug->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02002958
Michal Vasko63f3d842020-07-08 10:10:14 +02002959 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02002960 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02002961 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02002962 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002963 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002964 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002965 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &aug->iffeatures, Y_STR_ARG, &aug->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002966 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002967 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02002968 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &aug->ref, Y_STR_ARG, &aug->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002969 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002970 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02002971 LY_CHECK_RET(parse_status(ctx, in, &aug->flags, &aug->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002972 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002973 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02002974 LY_CHECK_RET(parse_when(ctx, in, &aug->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002975 break;
2976
Radek Krejcid6b76452019-09-03 17:03:03 +02002977 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02002978 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "augment");
Radek Krejci0f969882020-08-21 16:56:47 +02002979 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02002980 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02002981 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002982 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002983 case LY_STMT_CASE:
Michal Vasko22df3f02020-08-24 13:29:22 +02002984 LY_CHECK_RET(parse_case(ctx, in, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002985 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002986 case LY_STMT_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02002987 LY_CHECK_RET(parse_choice(ctx, in, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002988 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002989 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02002990 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002991 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002992 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02002993 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002994 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002995 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002996 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02002997 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02002998 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02002999 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003000 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003001 case LY_STMT_USES:
Michal Vasko22df3f02020-08-24 13:29:22 +02003002 LY_CHECK_RET(parse_uses(ctx, in, (struct lysp_node *)aug, &aug->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003003 break;
3004
Radek Krejcid6b76452019-09-03 17:03:03 +02003005 case LY_STMT_ACTION:
Radek Krejci335332a2019-09-05 13:03:35 +02003006 PARSER_CHECK_STMTVER2_RET(ctx, "action", "augment");
Michal Vasko22df3f02020-08-24 13:29:22 +02003007 LY_CHECK_RET(parse_action(ctx, in, (struct lysp_node *)aug, &aug->actions));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003008 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003009 case LY_STMT_NOTIFICATION:
Radek Krejci335332a2019-09-05 13:03:35 +02003010 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "augment");
Michal Vasko22df3f02020-08-24 13:29:22 +02003011 LY_CHECK_RET(parse_notif(ctx, in, (struct lysp_node *)aug, &aug->notifs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003012 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003013 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003014 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &aug->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003015 break;
3016 default:
David Sedlákb3077192019-06-19 10:55:37 +02003017 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "augment");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003018 return LY_EVALID;
3019 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003020 }
Radek Krejci7fc68292019-06-12 13:51:09 +02003021 LY_CHECK_RET(ret);
3022checks:
3023 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01003024 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, NULL, NULL, aug->actions, aug->notifs));
Radek Krejci7fc68292019-06-12 13:51:09 +02003025
Michal Vasko7fbc8162018-09-17 10:35:16 +02003026 return ret;
3027}
3028
Michal Vaskoea5abea2018-09-18 13:10:54 +02003029/**
3030 * @brief Parse the uses statement.
3031 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003032 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003033 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003034 * @param[in,out] siblings Siblings to add to.
3035 *
3036 * @return LY_ERR values.
3037 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003038LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003039parse_uses(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003040{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003041 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003042 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003043 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003044 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003045 struct lysp_node_uses *uses;
3046
David Sedlák60adc092019-08-06 15:57:02 +02003047 /* create uses structure */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02003048 LY_LIST_NEW_RET(ctx->ctx, siblings, uses, next, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003049 uses->nodetype = LYS_USES;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003050 uses->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003051
Michal Vasko7fbc8162018-09-17 10:35:16 +02003052 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02003053 LY_CHECK_RET(get_argument(ctx, in, Y_PREF_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003054 INSERT_WORD(ctx, buf, uses->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003055
3056 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02003057 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003058 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003059 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003060 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003061 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003062 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003063 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &uses->iffeatures, Y_STR_ARG, &uses->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003064 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003065 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003066 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &uses->ref, Y_STR_ARG, &uses->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003067 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003068 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003069 LY_CHECK_RET(parse_status(ctx, in, &uses->flags, &uses->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003070 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003071 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02003072 LY_CHECK_RET(parse_when(ctx, in, &uses->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003073 break;
3074
Radek Krejcid6b76452019-09-03 17:03:03 +02003075 case LY_STMT_REFINE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003076 LY_CHECK_RET(parse_refine(ctx, in, &uses->refines));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003077 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003078 case LY_STMT_AUGMENT:
Michal Vasko22df3f02020-08-24 13:29:22 +02003079 LY_CHECK_RET(parse_augment(ctx, in, (struct lysp_node *)uses, &uses->augments));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003080 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003081 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003082 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &uses->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003083 break;
3084 default:
David Sedlákb3077192019-06-19 10:55:37 +02003085 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "uses");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003086 return LY_EVALID;
3087 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003088 }
Radek Krejci7fc68292019-06-12 13:51:09 +02003089checks:
3090 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01003091 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, NULL, uses->augments, NULL, NULL));
Radek Krejci7fc68292019-06-12 13:51:09 +02003092
Michal Vasko7fbc8162018-09-17 10:35:16 +02003093 return ret;
3094}
3095
Michal Vaskoea5abea2018-09-18 13:10:54 +02003096/**
3097 * @brief Parse the case statement.
3098 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003099 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003100 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003101 * @param[in,out] siblings Siblings to add to.
3102 *
3103 * @return LY_ERR values.
3104 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003105LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003106parse_case(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003107{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003108 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003109 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003110 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003111 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003112 struct lysp_node_case *cas;
3113
David Sedlák60adc092019-08-06 15:57:02 +02003114 /* create new case structure */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02003115 LY_LIST_NEW_RET(ctx->ctx, siblings, cas, next, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003116 cas->nodetype = LYS_CASE;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003117 cas->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003118
Michal Vasko7fbc8162018-09-17 10:35:16 +02003119 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02003120 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003121 INSERT_WORD(ctx, buf, cas->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003122
3123 /* parse substatements */
Michal Vaskod989ba02020-08-24 10:59:24 +02003124 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003125 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003126 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003127 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003128 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003129 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003130 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &cas->iffeatures, Y_STR_ARG, &cas->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003131 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003132 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003133 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &cas->ref, Y_STR_ARG, &cas->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003134 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003135 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003136 LY_CHECK_RET(parse_status(ctx, in, &cas->flags, &cas->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003137 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003138 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02003139 LY_CHECK_RET(parse_when(ctx, in, &cas->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003140 break;
3141
Radek Krejcid6b76452019-09-03 17:03:03 +02003142 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02003143 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "case");
Radek Krejci0f969882020-08-21 16:56:47 +02003144 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02003145 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02003146 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)cas, &cas->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003147 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003148 case LY_STMT_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02003149 LY_CHECK_RET(parse_choice(ctx, in, (struct lysp_node *)cas, &cas->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003150 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003151 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02003152 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)cas, &cas->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003153 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003154 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02003155 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)cas, &cas->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003156 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003157 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003158 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)cas, &cas->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003159 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003160 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003161 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)cas, &cas->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003162 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003163 case LY_STMT_USES:
Michal Vasko22df3f02020-08-24 13:29:22 +02003164 LY_CHECK_RET(parse_uses(ctx, in, (struct lysp_node *)cas, &cas->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003165 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003166 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003167 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &cas->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003168 break;
3169 default:
David Sedlákb3077192019-06-19 10:55:37 +02003170 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "case");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003171 return LY_EVALID;
3172 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003173 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003174 return ret;
3175}
3176
Michal Vaskoea5abea2018-09-18 13:10:54 +02003177/**
3178 * @brief Parse the choice statement.
3179 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003180 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003181 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003182 * @param[in,out] siblings Siblings to add to.
3183 *
3184 * @return LY_ERR values.
3185 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003186LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003187parse_choice(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003188{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003189 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003190 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003191 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003192 enum ly_stmt kw;
Radek Krejci44ceedc2018-10-02 15:54:31 +02003193 struct lysp_node_choice *choice;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003194
David Sedlák60adc092019-08-06 15:57:02 +02003195 /* create new choice structure */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02003196 LY_LIST_NEW_RET(ctx->ctx, siblings, choice, next, LY_EMEM);
Radek Krejci44ceedc2018-10-02 15:54:31 +02003197 choice->nodetype = LYS_CHOICE;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003198 choice->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003199
Michal Vasko7fbc8162018-09-17 10:35:16 +02003200 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02003201 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003202 INSERT_WORD(ctx, buf, choice->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003203
3204 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02003205 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003206 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003207 case LY_STMT_CONFIG:
Michal Vasko63f3d842020-07-08 10:10:14 +02003208 LY_CHECK_RET(parse_config(ctx, in, &choice->flags, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003209 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003210 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003211 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &choice->dsc, Y_STR_ARG, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003212 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003213 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003214 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &choice->iffeatures, Y_STR_ARG, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003215 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003216 case LY_STMT_MANDATORY:
Michal Vasko63f3d842020-07-08 10:10:14 +02003217 LY_CHECK_RET(parse_mandatory(ctx, in, &choice->flags, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003218 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003219 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003220 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &choice->ref, Y_STR_ARG, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003221 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003222 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003223 LY_CHECK_RET(parse_status(ctx, in, &choice->flags, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003224 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003225 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02003226 LY_CHECK_RET(parse_when(ctx, in, &choice->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003227 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003228 case LY_STMT_DEFAULT:
Michal Vasko63f3d842020-07-08 10:10:14 +02003229 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &choice->dflt, Y_PREF_IDENTIF_ARG, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003230 break;
3231
Radek Krejcid6b76452019-09-03 17:03:03 +02003232 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02003233 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "choice");
Radek Krejci0f969882020-08-21 16:56:47 +02003234 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02003235 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02003236 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)choice, &choice->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003237 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003238 case LY_STMT_CASE:
Michal Vasko22df3f02020-08-24 13:29:22 +02003239 LY_CHECK_RET(parse_case(ctx, in, (struct lysp_node *)choice, &choice->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003240 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003241 case LY_STMT_CHOICE:
Radek Krejci335332a2019-09-05 13:03:35 +02003242 PARSER_CHECK_STMTVER2_RET(ctx, "choice", "choice");
Michal Vasko22df3f02020-08-24 13:29:22 +02003243 LY_CHECK_RET(parse_choice(ctx, in, (struct lysp_node *)choice, &choice->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003244 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003245 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02003246 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)choice, &choice->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003247 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003248 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02003249 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)choice, &choice->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003250 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003251 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003252 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)choice, &choice->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003253 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003254 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003255 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)choice, &choice->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003256 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003257 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003258 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &choice->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003259 break;
3260 default:
David Sedlákb3077192019-06-19 10:55:37 +02003261 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "choice");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003262 return LY_EVALID;
3263 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003264 }
Radek Krejcia9026eb2018-12-12 16:04:47 +01003265 LY_CHECK_RET(ret);
3266checks:
3267 if ((choice->flags & LYS_MAND_TRUE) && choice->dflt) {
David Sedlákb3077192019-06-19 10:55:37 +02003268 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMSCOMB, "mandatory", "default", "choice");
Radek Krejcia9026eb2018-12-12 16:04:47 +01003269 return LY_EVALID;
3270 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003271 return ret;
3272}
3273
Michal Vaskoea5abea2018-09-18 13:10:54 +02003274/**
3275 * @brief Parse the container statement.
3276 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003277 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003278 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003279 * @param[in,out] siblings Siblings to add to.
3280 *
3281 * @return LY_ERR values.
3282 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003283LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003284parse_container(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003285{
3286 LY_ERR ret = 0;
3287 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003288 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003289 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003290 struct lysp_node_container *cont;
3291
David Sedlák60adc092019-08-06 15:57:02 +02003292 /* create new container structure */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02003293 LY_LIST_NEW_RET(ctx->ctx, siblings, cont, next, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003294 cont->nodetype = LYS_CONTAINER;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003295 cont->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003296
Michal Vasko7fbc8162018-09-17 10:35:16 +02003297 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02003298 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003299 INSERT_WORD(ctx, buf, cont->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003300
3301 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02003302 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003303 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003304 case LY_STMT_CONFIG:
Michal Vasko63f3d842020-07-08 10:10:14 +02003305 LY_CHECK_RET(parse_config(ctx, in, &cont->flags, &cont->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003306 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003307 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003308 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &cont->dsc, Y_STR_ARG, &cont->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003309 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003310 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003311 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &cont->iffeatures, Y_STR_ARG, &cont->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003312 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003313 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003314 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &cont->ref, Y_STR_ARG, &cont->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003315 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003316 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003317 LY_CHECK_RET(parse_status(ctx, in, &cont->flags, &cont->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003318 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003319 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02003320 LY_CHECK_RET(parse_when(ctx, in, &cont->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003321 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003322 case LY_STMT_PRESENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003323 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_PRESENCE, 0, &cont->presence, Y_STR_ARG, &cont->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003324 break;
3325
Radek Krejcid6b76452019-09-03 17:03:03 +02003326 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02003327 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "container");
Radek Krejci0f969882020-08-21 16:56:47 +02003328 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02003329 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02003330 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)cont, &cont->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003331 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003332 case LY_STMT_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02003333 LY_CHECK_RET(parse_choice(ctx, in, (struct lysp_node *)cont, &cont->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003334 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003335 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02003336 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)cont, &cont->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003337 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003338 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02003339 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)cont, &cont->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003340 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003341 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003342 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)cont, &cont->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003343 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003344 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003345 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)cont, &cont->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003346 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003347 case LY_STMT_USES:
Michal Vasko22df3f02020-08-24 13:29:22 +02003348 LY_CHECK_RET(parse_uses(ctx, in, (struct lysp_node *)cont, &cont->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003349 break;
3350
Radek Krejcid6b76452019-09-03 17:03:03 +02003351 case LY_STMT_TYPEDEF:
Michal Vasko22df3f02020-08-24 13:29:22 +02003352 LY_CHECK_RET(parse_typedef(ctx, (struct lysp_node *)cont, in, &cont->typedefs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003353 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003354 case LY_STMT_MUST:
Michal Vasko63f3d842020-07-08 10:10:14 +02003355 LY_CHECK_RET(parse_restrs(ctx, in, kw, &cont->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003356 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003357 case LY_STMT_ACTION:
Radek Krejci335332a2019-09-05 13:03:35 +02003358 PARSER_CHECK_STMTVER2_RET(ctx, "action", "container");
Michal Vasko22df3f02020-08-24 13:29:22 +02003359 LY_CHECK_RET(parse_action(ctx, in, (struct lysp_node *)cont, &cont->actions));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003360 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003361 case LY_STMT_GROUPING:
Michal Vasko22df3f02020-08-24 13:29:22 +02003362 LY_CHECK_RET(parse_grouping(ctx, in, (struct lysp_node *)cont, &cont->groupings));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003363 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003364 case LY_STMT_NOTIFICATION:
Radek Krejci335332a2019-09-05 13:03:35 +02003365 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "container");
Michal Vasko22df3f02020-08-24 13:29:22 +02003366 LY_CHECK_RET(parse_notif(ctx, in, (struct lysp_node *)cont, &cont->notifs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003367 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003368 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003369 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &cont->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003370 break;
3371 default:
David Sedlákb3077192019-06-19 10:55:37 +02003372 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "container");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003373 return LY_EVALID;
3374 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003375 }
Radek Krejci7fc68292019-06-12 13:51:09 +02003376checks:
Radek Krejcie86bf772018-12-14 11:39:53 +01003377 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01003378 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, cont->groupings, NULL, cont->actions, cont->notifs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003379 return ret;
3380}
3381
Michal Vaskoea5abea2018-09-18 13:10:54 +02003382/**
3383 * @brief Parse the list statement.
3384 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003385 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003386 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003387 * @param[in,out] siblings Siblings to add to.
3388 *
3389 * @return LY_ERR values.
3390 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003391LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003392parse_list(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_node *parent, struct lysp_node **siblings)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003393{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003394 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003395 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003396 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003397 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003398 struct lysp_node_list *list;
3399
David Sedlák60adc092019-08-06 15:57:02 +02003400 /* create new list structure */
David Sedlákb9eeb9c2019-09-13 11:17:19 +02003401 LY_LIST_NEW_RET(ctx->ctx, siblings, list, next, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003402 list->nodetype = LYS_LIST;
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003403 list->parent = parent;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003404
Michal Vasko7fbc8162018-09-17 10:35:16 +02003405 /* get name */
Michal Vasko63f3d842020-07-08 10:10:14 +02003406 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003407 INSERT_WORD(ctx, buf, list->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003408
3409 /* parse substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02003410 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003411 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003412 case LY_STMT_CONFIG:
Michal Vasko63f3d842020-07-08 10:10:14 +02003413 LY_CHECK_RET(parse_config(ctx, in, &list->flags, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003414 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003415 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003416 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &list->dsc, Y_STR_ARG, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003417 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003418 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003419 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &list->iffeatures, Y_STR_ARG, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003420 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003421 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003422 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &list->ref, Y_STR_ARG, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003423 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003424 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003425 LY_CHECK_RET(parse_status(ctx, in, &list->flags, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003426 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003427 case LY_STMT_WHEN:
Michal Vasko63f3d842020-07-08 10:10:14 +02003428 LY_CHECK_RET(parse_when(ctx, in, &list->when));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003429 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003430 case LY_STMT_KEY:
Michal Vasko63f3d842020-07-08 10:10:14 +02003431 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_KEY, 0, &list->key, Y_STR_ARG, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003432 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003433 case LY_STMT_MAX_ELEMENTS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003434 LY_CHECK_RET(parse_maxelements(ctx, in, &list->max, &list->flags, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003435 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003436 case LY_STMT_MIN_ELEMENTS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003437 LY_CHECK_RET(parse_minelements(ctx, in, &list->min, &list->flags, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003438 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003439 case LY_STMT_ORDERED_BY:
Michal Vasko63f3d842020-07-08 10:10:14 +02003440 LY_CHECK_RET(parse_orderedby(ctx, in, &list->flags, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003441 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003442 case LY_STMT_UNIQUE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003443 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_UNIQUE, &list->uniques, Y_STR_ARG, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003444 break;
3445
Radek Krejcid6b76452019-09-03 17:03:03 +02003446 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02003447 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "list");
Radek Krejci0f969882020-08-21 16:56:47 +02003448 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02003449 case LY_STMT_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02003450 LY_CHECK_RET(parse_any(ctx, in, kw, (struct lysp_node *)list, &list->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003451 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003452 case LY_STMT_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02003453 LY_CHECK_RET(parse_choice(ctx, in, (struct lysp_node *)list, &list->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003454 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003455 case LY_STMT_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02003456 LY_CHECK_RET(parse_container(ctx, in, (struct lysp_node *)list, &list->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003457 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003458 case LY_STMT_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02003459 LY_CHECK_RET(parse_leaf(ctx, in, (struct lysp_node *)list, &list->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003460 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003461 case LY_STMT_LEAF_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003462 LY_CHECK_RET(parse_leaflist(ctx, in, (struct lysp_node *)list, &list->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003463 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003464 case LY_STMT_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02003465 LY_CHECK_RET(parse_list(ctx, in, (struct lysp_node *)list, &list->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003466 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003467 case LY_STMT_USES:
Michal Vasko22df3f02020-08-24 13:29:22 +02003468 LY_CHECK_RET(parse_uses(ctx, in, (struct lysp_node *)list, &list->child));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003469 break;
3470
Radek Krejcid6b76452019-09-03 17:03:03 +02003471 case LY_STMT_TYPEDEF:
Michal Vasko22df3f02020-08-24 13:29:22 +02003472 LY_CHECK_RET(parse_typedef(ctx, (struct lysp_node *)list, in, &list->typedefs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003473 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003474 case LY_STMT_MUST:
Michal Vasko63f3d842020-07-08 10:10:14 +02003475 LY_CHECK_RET(parse_restrs(ctx, in, kw, &list->musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003476 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003477 case LY_STMT_ACTION:
Radek Krejci335332a2019-09-05 13:03:35 +02003478 PARSER_CHECK_STMTVER2_RET(ctx, "action", "list");
Michal Vasko22df3f02020-08-24 13:29:22 +02003479 LY_CHECK_RET(parse_action(ctx, in, (struct lysp_node *)list, &list->actions));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003480 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003481 case LY_STMT_GROUPING:
Michal Vasko22df3f02020-08-24 13:29:22 +02003482 LY_CHECK_RET(parse_grouping(ctx, in, (struct lysp_node *)list, &list->groupings));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003483 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003484 case LY_STMT_NOTIFICATION:
Radek Krejci335332a2019-09-05 13:03:35 +02003485 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "list");
Michal Vasko22df3f02020-08-24 13:29:22 +02003486 LY_CHECK_RET(parse_notif(ctx, in, (struct lysp_node *)list, &list->notifs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003487 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003488 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003489 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &list->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003490 break;
3491 default:
David Sedlákb3077192019-06-19 10:55:37 +02003492 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "list");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003493 return LY_EVALID;
3494 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003495 }
Radek Krejci9bb94eb2018-12-04 16:48:35 +01003496 LY_CHECK_RET(ret);
3497checks:
Radek Krejci7fc68292019-06-12 13:51:09 +02003498 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01003499 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, list->groupings, NULL, list->actions, list->notifs));
Radek Krejci7fc68292019-06-12 13:51:09 +02003500
Radek Krejci9bb94eb2018-12-04 16:48:35 +01003501 if (list->max && list->min > list->max) {
David Sedlákb3077192019-06-19 10:55:37 +02003502 LOGVAL_PARSER(ctx, LYVE_SEMANTICS,
Radek Krejci9bb94eb2018-12-04 16:48:35 +01003503 "Invalid combination of min-elements and max-elements: min value %u is bigger than the max value %u.",
3504 list->min, list->max);
3505 return LY_EVALID;
3506 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003507
3508 return ret;
3509}
3510
Michal Vaskoea5abea2018-09-18 13:10:54 +02003511/**
3512 * @brief Parse the yin-element statement.
3513 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003514 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003515 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003516 * @param[in,out] flags Flags to write to.
3517 * @param[in,out] exts Extension instances to add to.
3518 *
3519 * @return LY_ERR values.
3520 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02003521static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003522parse_yinelement(struct lys_yang_parser_ctx *ctx, struct ly_in *in, uint16_t *flags, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003523{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003524 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003525 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003526 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003527 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003528
3529 if (*flags & LYS_YINELEM_MASK) {
David Sedlákb3077192019-06-19 10:55:37 +02003530 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yin-element");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003531 return LY_EVALID;
3532 }
3533
3534 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02003535 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003536
3537 if ((word_len == 4) && !strncmp(word, "true", word_len)) {
3538 *flags |= LYS_YINELEM_TRUE;
3539 } else if ((word_len == 5) && !strncmp(word, "false", word_len)) {
3540 *flags |= LYS_YINELEM_FALSE;
3541 } else {
David Sedlákb3077192019-06-19 10:55:37 +02003542 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "yin-element");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003543 free(buf);
3544 return LY_EVALID;
3545 }
3546 free(buf);
3547
Michal Vaskod989ba02020-08-24 10:59:24 +02003548 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003549 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003550 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003551 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_YINELEM, 0, exts));
Michal Vaskod989ba02020-08-24 10:59:24 +02003552 LY_CHECK_RET(ret);
3553 break;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003554 default:
David Sedlákb3077192019-06-19 10:55:37 +02003555 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "yin-element");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003556 return LY_EVALID;
3557 }
3558 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003559 return ret;
3560}
3561
Michal Vaskoea5abea2018-09-18 13:10:54 +02003562/**
David Sedlák2444f8f2019-07-09 11:02:47 +02003563 * @brief Parse the argument statement.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003564 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003565 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003566 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003567 * @param[in,out] argument Value to write to.
3568 * @param[in,out] flags Flags to write to.
3569 * @param[in,out] exts Extension instances to add to.
3570 *
3571 * @return LY_ERR values.
3572 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02003573static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003574parse_argument(struct lys_yang_parser_ctx *ctx, struct ly_in *in, const char **argument, uint16_t *flags, struct lysp_ext_instance **exts)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003575{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003576 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003577 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003578 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003579 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003580
3581 if (*argument) {
David Sedlákb3077192019-06-19 10:55:37 +02003582 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "argument");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003583 return LY_EVALID;
3584 }
3585
3586 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02003587 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003588 INSERT_WORD(ctx, buf, *argument, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003589
Michal Vaskod989ba02020-08-24 10:59:24 +02003590 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003591 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003592 case LY_STMT_YIN_ELEMENT:
Michal Vasko63f3d842020-07-08 10:10:14 +02003593 LY_CHECK_RET(parse_yinelement(ctx, in, flags, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003594 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003595 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003596 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_ARGUMENT, 0, exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003597 break;
3598 default:
David Sedlákb3077192019-06-19 10:55:37 +02003599 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "argument");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003600 return LY_EVALID;
3601 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003602 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003603 return ret;
3604}
3605
Michal Vaskoea5abea2018-09-18 13:10:54 +02003606/**
3607 * @brief Parse the extension statement.
3608 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003609 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003610 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003611 * @param[in,out] extensions Extensions to add to.
3612 *
3613 * @return LY_ERR values.
3614 */
Michal Vasko7fbc8162018-09-17 10:35:16 +02003615static LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003616parse_extension(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_ext **extensions)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003617{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003618 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003619 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003620 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003621 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003622 struct lysp_ext *ex;
3623
Radek Krejci2c4e7172018-10-19 15:56:26 +02003624 LY_ARRAY_NEW_RET(ctx->ctx, *extensions, ex, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003625
3626 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02003627 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003628 INSERT_WORD(ctx, buf, ex->name, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003629
Michal Vaskod989ba02020-08-24 10:59:24 +02003630 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003631 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003632 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003633 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &ex->dsc, Y_STR_ARG, &ex->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003634 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003635 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003636 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &ex->ref, Y_STR_ARG, &ex->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003637 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003638 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003639 LY_CHECK_RET(parse_status(ctx, in, &ex->flags, &ex->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003640 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003641 case LY_STMT_ARGUMENT:
Michal Vasko63f3d842020-07-08 10:10:14 +02003642 LY_CHECK_RET(parse_argument(ctx, in, &ex->argument, &ex->flags, &ex->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003643 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003644 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003645 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &ex->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003646 break;
3647 default:
David Sedlákb3077192019-06-19 10:55:37 +02003648 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "extension");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003649 return LY_EVALID;
3650 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003651 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003652 return ret;
3653}
3654
Michal Vaskoea5abea2018-09-18 13:10:54 +02003655/**
3656 * @brief Parse the deviate statement.
3657 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003658 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003659 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003660 * @param[in,out] deviates Deviates to add to.
3661 *
3662 * @return LY_ERR values.
3663 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003664LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003665parse_deviate(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_deviate **deviates)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003666{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003667 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003668 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003669 size_t word_len, dev_mod;
Radek Krejcid6b76452019-09-03 17:03:03 +02003670 enum ly_stmt kw;
David Sedlák60adc092019-08-06 15:57:02 +02003671 struct lysp_deviate *d;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003672 struct lysp_deviate_add *d_add = NULL;
3673 struct lysp_deviate_rpl *d_rpl = NULL;
3674 struct lysp_deviate_del *d_del = NULL;
Radek Krejci4ad42aa2019-07-23 16:55:58 +02003675 const char **d_units = NULL, ***d_uniques = NULL, ***d_dflts = NULL;
3676 struct lysp_restr **d_musts = NULL;
3677 uint16_t *d_flags = 0;
3678 uint32_t *d_min = 0, *d_max = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003679
3680 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02003681 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003682
3683 if ((word_len == 13) && !strncmp(word, "not-supported", word_len)) {
3684 dev_mod = LYS_DEV_NOT_SUPPORTED;
3685 } else if ((word_len == 3) && !strncmp(word, "add", word_len)) {
3686 dev_mod = LYS_DEV_ADD;
3687 } else if ((word_len == 7) && !strncmp(word, "replace", word_len)) {
3688 dev_mod = LYS_DEV_REPLACE;
3689 } else if ((word_len == 6) && !strncmp(word, "delete", word_len)) {
3690 dev_mod = LYS_DEV_DELETE;
3691 } else {
David Sedlákb3077192019-06-19 10:55:37 +02003692 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, word_len, word, "deviate");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003693 free(buf);
3694 return LY_EVALID;
3695 }
3696 free(buf);
3697
3698 /* create structure */
3699 switch (dev_mod) {
3700 case LYS_DEV_NOT_SUPPORTED:
3701 d = calloc(1, sizeof *d);
Radek Krejci44ceedc2018-10-02 15:54:31 +02003702 LY_CHECK_ERR_RET(!d, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003703 break;
3704 case LYS_DEV_ADD:
3705 d_add = calloc(1, sizeof *d_add);
Radek Krejci44ceedc2018-10-02 15:54:31 +02003706 LY_CHECK_ERR_RET(!d_add, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003707 d = (struct lysp_deviate *)d_add;
3708 d_units = &d_add->units;
3709 d_uniques = &d_add->uniques;
3710 d_dflts = &d_add->dflts;
3711 d_musts = &d_add->musts;
3712 d_flags = &d_add->flags;
3713 d_min = &d_add->min;
3714 d_max = &d_add->max;
3715 break;
3716 case LYS_DEV_REPLACE:
3717 d_rpl = calloc(1, sizeof *d_rpl);
Radek Krejci44ceedc2018-10-02 15:54:31 +02003718 LY_CHECK_ERR_RET(!d_rpl, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003719 d = (struct lysp_deviate *)d_rpl;
3720 d_units = &d_rpl->units;
3721 d_flags = &d_rpl->flags;
3722 d_min = &d_rpl->min;
3723 d_max = &d_rpl->max;
3724 break;
3725 case LYS_DEV_DELETE:
3726 d_del = calloc(1, sizeof *d_del);
Radek Krejci44ceedc2018-10-02 15:54:31 +02003727 LY_CHECK_ERR_RET(!d_del, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003728 d = (struct lysp_deviate *)d_del;
3729 d_units = &d_del->units;
3730 d_uniques = &d_del->uniques;
3731 d_dflts = &d_del->dflts;
3732 d_musts = &d_del->musts;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003733 break;
3734 default:
3735 assert(0);
Radek Krejci44ceedc2018-10-02 15:54:31 +02003736 LOGINT_RET(ctx->ctx);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003737 }
3738 d->mod = dev_mod;
3739
3740 /* insert into siblings */
David Sedlák60adc092019-08-06 15:57:02 +02003741 LY_LIST_INSERT(deviates, d, next);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003742
Michal Vaskod989ba02020-08-24 10:59:24 +02003743 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003744 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003745 case LY_STMT_CONFIG:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003746 switch (dev_mod) {
3747 case LYS_DEV_NOT_SUPPORTED:
Michal Vasko492bec72018-09-18 13:11:10 +02003748 case LYS_DEV_DELETE:
David Sedlákb3077192019-06-19 10:55:37 +02003749 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003750 return LY_EVALID;
3751 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003752 LY_CHECK_RET(parse_config(ctx, in, d_flags, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003753 break;
3754 }
3755 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003756 case LY_STMT_DEFAULT:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003757 switch (dev_mod) {
3758 case LYS_DEV_NOT_SUPPORTED:
David Sedlákb3077192019-06-19 10:55:37 +02003759 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003760 return LY_EVALID;
3761 case LYS_DEV_REPLACE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003762 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DEFAULT, 0, &d_rpl->dflt, Y_STR_ARG, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003763 break;
3764 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003765 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_DEFAULT, d_dflts, Y_STR_ARG, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003766 break;
3767 }
3768 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003769 case LY_STMT_MANDATORY:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003770 switch (dev_mod) {
3771 case LYS_DEV_NOT_SUPPORTED:
Michal Vasko492bec72018-09-18 13:11:10 +02003772 case LYS_DEV_DELETE:
David Sedlákb3077192019-06-19 10:55:37 +02003773 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003774 return LY_EVALID;
3775 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003776 LY_CHECK_RET(parse_mandatory(ctx, in, d_flags, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003777 break;
3778 }
3779 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003780 case LY_STMT_MAX_ELEMENTS:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003781 switch (dev_mod) {
3782 case LYS_DEV_NOT_SUPPORTED:
Michal Vasko492bec72018-09-18 13:11:10 +02003783 case LYS_DEV_DELETE:
David Sedlákb3077192019-06-19 10:55:37 +02003784 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003785 return LY_EVALID;
3786 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003787 LY_CHECK_RET(parse_maxelements(ctx, in, d_max, d_flags, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003788 break;
3789 }
3790 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003791 case LY_STMT_MIN_ELEMENTS:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003792 switch (dev_mod) {
3793 case LYS_DEV_NOT_SUPPORTED:
Michal Vasko492bec72018-09-18 13:11:10 +02003794 case LYS_DEV_DELETE:
David Sedlákb3077192019-06-19 10:55:37 +02003795 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003796 return LY_EVALID;
3797 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003798 LY_CHECK_RET(parse_minelements(ctx, in, d_min, d_flags, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003799 break;
3800 }
3801 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003802 case LY_STMT_MUST:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003803 switch (dev_mod) {
3804 case LYS_DEV_NOT_SUPPORTED:
Michal Vasko492bec72018-09-18 13:11:10 +02003805 case LYS_DEV_REPLACE:
David Sedlákb3077192019-06-19 10:55:37 +02003806 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003807 return LY_EVALID;
3808 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003809 LY_CHECK_RET(parse_restrs(ctx, in, kw, d_musts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003810 break;
3811 }
3812 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003813 case LY_STMT_TYPE:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003814 switch (dev_mod) {
3815 case LYS_DEV_NOT_SUPPORTED:
3816 case LYS_DEV_ADD:
3817 case LYS_DEV_DELETE:
David Sedlákb3077192019-06-19 10:55:37 +02003818 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003819 return LY_EVALID;
3820 default:
Radek Krejci2c02f3e2018-10-16 10:54:38 +02003821 if (d_rpl->type) {
David Sedlákb3077192019-06-19 10:55:37 +02003822 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(kw));
Radek Krejci2c02f3e2018-10-16 10:54:38 +02003823 return LY_EVALID;
3824 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003825 d_rpl->type = calloc(1, sizeof *d_rpl->type);
Radek Krejci44ceedc2018-10-02 15:54:31 +02003826 LY_CHECK_ERR_RET(!d_rpl->type, LOGMEM(ctx->ctx), LY_EMEM);
Michal Vasko63f3d842020-07-08 10:10:14 +02003827 LY_CHECK_RET(parse_type(ctx, in, d_rpl->type));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003828 break;
3829 }
3830 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003831 case LY_STMT_UNIQUE:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003832 switch (dev_mod) {
3833 case LYS_DEV_NOT_SUPPORTED:
3834 case LYS_DEV_REPLACE:
David Sedlákb3077192019-06-19 10:55:37 +02003835 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003836 return LY_EVALID;
3837 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003838 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_UNIQUE, d_uniques, Y_STR_ARG, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003839 break;
3840 }
3841 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003842 case LY_STMT_UNITS:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003843 switch (dev_mod) {
3844 case LYS_DEV_NOT_SUPPORTED:
David Sedlákb3077192019-06-19 10:55:37 +02003845 LOGVAL_PARSER(ctx, LY_VCODE_INDEV, ly_devmod2str(dev_mod), ly_stmt2str(kw));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003846 return LY_EVALID;
3847 default:
Michal Vasko63f3d842020-07-08 10:10:14 +02003848 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_UNITS, 0, d_units, Y_STR_ARG, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003849 break;
3850 }
3851 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003852 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003853 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &d->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003854 break;
3855 default:
David Sedlákb3077192019-06-19 10:55:37 +02003856 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "deviate");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003857 return LY_EVALID;
3858 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003859 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003860 return ret;
3861}
3862
Michal Vaskoea5abea2018-09-18 13:10:54 +02003863/**
3864 * @brief Parse the deviation statement.
3865 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003866 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003867 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003868 * @param[in,out] deviations Deviations to add to.
3869 *
3870 * @return LY_ERR values.
3871 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003872LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003873parse_deviation(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_deviation **deviations)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003874{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003875 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003876 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003877 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003878 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003879 struct lysp_deviation *dev;
3880
Radek Krejci2c4e7172018-10-19 15:56:26 +02003881 LY_ARRAY_NEW_RET(ctx->ctx, *deviations, dev, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003882
3883 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02003884 LY_CHECK_RET(get_argument(ctx, in, Y_STR_ARG, NULL, &word, &buf, &word_len));
Michal Vaskob36053d2020-03-26 15:49:30 +01003885 CHECK_NONEMPTY(ctx, word_len, "deviation");
Radek Krejci44ceedc2018-10-02 15:54:31 +02003886 INSERT_WORD(ctx, buf, dev->nodeid, word, word_len);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003887
Michal Vasko63f3d842020-07-08 10:10:14 +02003888 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003889 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003890 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003891 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &dev->dsc, Y_STR_ARG, &dev->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003892 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003893 case LY_STMT_DEVIATE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003894 LY_CHECK_RET(parse_deviate(ctx, in, &dev->deviates));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003895 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003896 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003897 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &dev->ref, Y_STR_ARG, &dev->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003898 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003899 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003900 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &dev->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003901 break;
3902 default:
David Sedlákb3077192019-06-19 10:55:37 +02003903 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "deviation");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003904 return LY_EVALID;
3905 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003906 }
Radek Krejcic59bc972018-09-17 16:13:06 +02003907 LY_CHECK_RET(ret);
Radek Krejci6d6556c2018-11-08 09:37:45 +01003908checks:
Michal Vasko7fbc8162018-09-17 10:35:16 +02003909 /* mandatory substatements */
3910 if (!dev->deviates) {
David Sedlákb3077192019-06-19 10:55:37 +02003911 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "deviate", "deviation");
Michal Vasko7fbc8162018-09-17 10:35:16 +02003912 return LY_EVALID;
3913 }
3914
3915 return ret;
3916}
3917
Michal Vaskoea5abea2018-09-18 13:10:54 +02003918/**
3919 * @brief Parse the feature statement.
3920 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003921 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003922 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003923 * @param[in,out] features Features to add to.
3924 *
3925 * @return LY_ERR values.
3926 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003927LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003928parse_feature(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_feature **features)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003929{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003930 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003931 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003932 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003933 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003934 struct lysp_feature *feat;
3935
Radek Krejci2c4e7172018-10-19 15:56:26 +02003936 LY_ARRAY_NEW_RET(ctx->ctx, *features, feat, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003937
3938 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02003939 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003940 INSERT_WORD(ctx, buf, feat->name, word, word_len);
Radek Krejcifaa1eac2018-10-30 14:34:55 +01003941
Michal Vaskod989ba02020-08-24 10:59:24 +02003942 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003943 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003944 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003945 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &feat->dsc, Y_STR_ARG, &feat->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003946 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003947 case LY_STMT_IF_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003948 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &feat->iffeatures, Y_STR_ARG, &feat->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003949 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003950 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003951 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &feat->ref, Y_STR_ARG, &feat->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003952 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003953 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02003954 LY_CHECK_RET(parse_status(ctx, in, &feat->flags, &feat->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003955 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003956 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02003957 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &feat->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003958 break;
3959 default:
David Sedlákb3077192019-06-19 10:55:37 +02003960 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "feature");
Radek Krejci2c02f3e2018-10-16 10:54:38 +02003961 return LY_EVALID;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003962 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003963 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02003964 return ret;
3965}
3966
Michal Vaskoea5abea2018-09-18 13:10:54 +02003967/**
3968 * @brief Parse the identity statement.
3969 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02003970 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02003971 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02003972 * @param[in,out] identities Identities to add to.
3973 *
3974 * @return LY_ERR values.
3975 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02003976LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02003977parse_identity(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_ident **identities)
Michal Vasko7fbc8162018-09-17 10:35:16 +02003978{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01003979 LY_ERR ret = LY_SUCCESS;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003980 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02003981 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02003982 enum ly_stmt kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02003983 struct lysp_ident *ident;
3984
Radek Krejci2c4e7172018-10-19 15:56:26 +02003985 LY_ARRAY_NEW_RET(ctx->ctx, *identities, ident, LY_EMEM);
Michal Vasko7fbc8162018-09-17 10:35:16 +02003986
3987 /* get value */
Michal Vasko63f3d842020-07-08 10:10:14 +02003988 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci44ceedc2018-10-02 15:54:31 +02003989 INSERT_WORD(ctx, buf, ident->name, word, word_len);
Radek Krejcifaa1eac2018-10-30 14:34:55 +01003990
Michal Vaskod989ba02020-08-24 10:59:24 +02003991 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, ) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02003992 switch (kw) {
Radek Krejcid6b76452019-09-03 17:03:03 +02003993 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02003994 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &ident->dsc, Y_STR_ARG, &ident->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003995 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02003996 case LY_STMT_IF_FEATURE:
Radek Krejci335332a2019-09-05 13:03:35 +02003997 PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "identity");
Michal Vasko63f3d842020-07-08 10:10:14 +02003998 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_IFFEATURE, &ident->iffeatures, Y_STR_ARG, &ident->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02003999 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004000 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004001 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &ident->ref, Y_STR_ARG, &ident->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004002 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004003 case LY_STMT_STATUS:
Michal Vasko63f3d842020-07-08 10:10:14 +02004004 LY_CHECK_RET(parse_status(ctx, in, &ident->flags, &ident->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004005 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004006 case LY_STMT_BASE:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004007 if (ident->bases && ctx->mod_version < 2) {
David Sedlákb3077192019-06-19 10:55:37 +02004008 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Identity can be derived from multiple base identities only in YANG 1.1 modules");
Radek Krejci10113652018-11-14 16:56:50 +01004009 return LY_EVALID;
4010 }
Michal Vasko63f3d842020-07-08 10:10:14 +02004011 LY_CHECK_RET(parse_text_fields(ctx, in, LYEXT_SUBSTMT_BASE, &ident->bases, Y_PREF_IDENTIF_ARG, &ident->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004012 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004013 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004014 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &ident->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004015 break;
4016 default:
David Sedlákb3077192019-06-19 10:55:37 +02004017 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "identity");
Michal Vasko7fbc8162018-09-17 10:35:16 +02004018 return LY_EVALID;
4019 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02004020 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02004021 return ret;
4022}
4023
Michal Vaskoea5abea2018-09-18 13:10:54 +02004024/**
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004025 * @brief Parse module substatements.
Michal Vaskoea5abea2018-09-18 13:10:54 +02004026 *
Radek Krejci44ceedc2018-10-02 15:54:31 +02004027 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02004028 * @param[in,out] in Input structure.
Michal Vaskoea5abea2018-09-18 13:10:54 +02004029 * @param[in,out] mod Module to write to.
4030 *
4031 * @return LY_ERR values.
4032 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02004033LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02004034parse_module(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_module *mod)
Michal Vasko7fbc8162018-09-17 10:35:16 +02004035{
4036 LY_ERR ret = 0;
4037 char *buf, *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02004038 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02004039 enum ly_stmt kw, prev_kw = 0;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004040 enum yang_module_stmt mod_stmt = Y_MOD_MODULE_HEADER;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004041 struct lysp_submodule *dup;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004042
4043 /* (sub)module name */
Michal Vasko63f3d842020-07-08 10:10:14 +02004044 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004045 INSERT_WORD(ctx, buf, mod->mod->name, word, word_len);
Radek Krejcifaa1eac2018-10-30 14:34:55 +01004046
Michal Vasko63f3d842020-07-08 10:10:14 +02004047 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Michal Vasko7fbc8162018-09-17 10:35:16 +02004048
Radek Krejcie3846472018-10-15 15:24:51 +02004049#define CHECK_ORDER(SECTION) \
David Sedlákb3077192019-06-19 10:55:37 +02004050 if (mod_stmt > SECTION) {LOGVAL_PARSER(ctx, LY_VCODE_INORD, ly_stmt2str(kw), ly_stmt2str(prev_kw)); return LY_EVALID;}mod_stmt = SECTION
Radek Krejcie3846472018-10-15 15:24:51 +02004051
Michal Vasko7fbc8162018-09-17 10:35:16 +02004052 switch (kw) {
4053 /* module header */
Radek Krejcid6b76452019-09-03 17:03:03 +02004054 case LY_STMT_NAMESPACE:
4055 case LY_STMT_PREFIX:
Radek Krejcie3846472018-10-15 15:24:51 +02004056 CHECK_ORDER(Y_MOD_MODULE_HEADER);
4057 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004058 case LY_STMT_YANG_VERSION:
Radek Krejcie3846472018-10-15 15:24:51 +02004059 CHECK_ORDER(Y_MOD_MODULE_HEADER);
Michal Vasko7fbc8162018-09-17 10:35:16 +02004060 break;
4061 /* linkage */
Radek Krejcid6b76452019-09-03 17:03:03 +02004062 case LY_STMT_INCLUDE:
4063 case LY_STMT_IMPORT:
Radek Krejcie3846472018-10-15 15:24:51 +02004064 CHECK_ORDER(Y_MOD_LINKAGE);
Michal Vasko7fbc8162018-09-17 10:35:16 +02004065 break;
4066 /* meta */
Radek Krejcid6b76452019-09-03 17:03:03 +02004067 case LY_STMT_ORGANIZATION:
4068 case LY_STMT_CONTACT:
4069 case LY_STMT_DESCRIPTION:
4070 case LY_STMT_REFERENCE:
Radek Krejcie3846472018-10-15 15:24:51 +02004071 CHECK_ORDER(Y_MOD_META);
Michal Vasko7fbc8162018-09-17 10:35:16 +02004072 break;
4073
4074 /* revision */
Radek Krejcid6b76452019-09-03 17:03:03 +02004075 case LY_STMT_REVISION:
Radek Krejcie3846472018-10-15 15:24:51 +02004076 CHECK_ORDER(Y_MOD_REVISION);
Michal Vasko7fbc8162018-09-17 10:35:16 +02004077 break;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004078 /* body */
Radek Krejcid6b76452019-09-03 17:03:03 +02004079 case LY_STMT_ANYDATA:
4080 case LY_STMT_ANYXML:
4081 case LY_STMT_AUGMENT:
4082 case LY_STMT_CHOICE:
4083 case LY_STMT_CONTAINER:
4084 case LY_STMT_DEVIATION:
4085 case LY_STMT_EXTENSION:
4086 case LY_STMT_FEATURE:
4087 case LY_STMT_GROUPING:
4088 case LY_STMT_IDENTITY:
4089 case LY_STMT_LEAF:
4090 case LY_STMT_LEAF_LIST:
4091 case LY_STMT_LIST:
4092 case LY_STMT_NOTIFICATION:
4093 case LY_STMT_RPC:
4094 case LY_STMT_TYPEDEF:
4095 case LY_STMT_USES:
4096 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko7fbc8162018-09-17 10:35:16 +02004097 mod_stmt = Y_MOD_BODY;
4098 break;
4099 default:
4100 /* error handled in the next switch */
4101 break;
4102 }
Radek Krejcie3846472018-10-15 15:24:51 +02004103#undef CHECK_ORDER
Michal Vasko7fbc8162018-09-17 10:35:16 +02004104
Radek Krejcie3846472018-10-15 15:24:51 +02004105 prev_kw = kw;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004106 switch (kw) {
4107 /* module header */
Radek Krejcid6b76452019-09-03 17:03:03 +02004108 case LY_STMT_YANG_VERSION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004109 LY_CHECK_RET(parse_yangversion(ctx, in, &mod->mod->version, &mod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004110 ctx->mod_version = mod->mod->version;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004111 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004112 case LY_STMT_NAMESPACE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004113 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_NAMESPACE, 0, &mod->mod->ns, Y_STR_ARG, &mod->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004114 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004115 case LY_STMT_PREFIX:
Michal Vasko63f3d842020-07-08 10:10:14 +02004116 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_PREFIX, 0, &mod->mod->prefix, Y_IDENTIF_ARG, &mod->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004117 break;
4118
4119 /* linkage */
Radek Krejcid6b76452019-09-03 17:03:03 +02004120 case LY_STMT_INCLUDE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004121 LY_CHECK_RET(parse_include(ctx, mod->mod->name, in, &mod->includes));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004122 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004123 case LY_STMT_IMPORT:
Michal Vasko63f3d842020-07-08 10:10:14 +02004124 LY_CHECK_RET(parse_import(ctx, mod->mod->prefix, in, &mod->imports));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004125 break;
4126
4127 /* meta */
Radek Krejcid6b76452019-09-03 17:03:03 +02004128 case LY_STMT_ORGANIZATION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004129 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_ORGANIZATION, 0, &mod->mod->org, Y_STR_ARG, &mod->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004130 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004131 case LY_STMT_CONTACT:
Michal Vasko63f3d842020-07-08 10:10:14 +02004132 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_CONTACT, 0, &mod->mod->contact, Y_STR_ARG, &mod->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004133 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004134 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004135 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &mod->mod->dsc, Y_STR_ARG, &mod->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004136 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004137 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004138 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &mod->mod->ref, Y_STR_ARG, &mod->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004139 break;
4140
4141 /* revision */
Radek Krejcid6b76452019-09-03 17:03:03 +02004142 case LY_STMT_REVISION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004143 LY_CHECK_RET(parse_revision(ctx, in, &mod->revs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004144 break;
4145
4146 /* body */
Radek Krejcid6b76452019-09-03 17:03:03 +02004147 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02004148 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "module");
Radek Krejci0f969882020-08-21 16:56:47 +02004149 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02004150 case LY_STMT_ANYXML:
Michal Vasko63f3d842020-07-08 10:10:14 +02004151 LY_CHECK_RET(parse_any(ctx, in, kw, NULL, &mod->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004152 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004153 case LY_STMT_CHOICE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004154 LY_CHECK_RET(parse_choice(ctx, in, NULL, &mod->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004155 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004156 case LY_STMT_CONTAINER:
Michal Vasko63f3d842020-07-08 10:10:14 +02004157 LY_CHECK_RET(parse_container(ctx, in, NULL, &mod->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004158 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004159 case LY_STMT_LEAF:
Michal Vasko63f3d842020-07-08 10:10:14 +02004160 LY_CHECK_RET(parse_leaf(ctx, in, NULL, &mod->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004161 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004162 case LY_STMT_LEAF_LIST:
Michal Vasko63f3d842020-07-08 10:10:14 +02004163 LY_CHECK_RET(parse_leaflist(ctx, in, NULL, &mod->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004164 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004165 case LY_STMT_LIST:
Michal Vasko63f3d842020-07-08 10:10:14 +02004166 LY_CHECK_RET(parse_list(ctx, in, NULL, &mod->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004167 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004168 case LY_STMT_USES:
Michal Vasko63f3d842020-07-08 10:10:14 +02004169 LY_CHECK_RET(parse_uses(ctx, in, NULL, &mod->data));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004170 break;
4171
Radek Krejcid6b76452019-09-03 17:03:03 +02004172 case LY_STMT_AUGMENT:
Michal Vasko63f3d842020-07-08 10:10:14 +02004173 LY_CHECK_RET(parse_augment(ctx, in, NULL, &mod->augments));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004174 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004175 case LY_STMT_DEVIATION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004176 LY_CHECK_RET(parse_deviation(ctx, in, &mod->deviations));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004177 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004178 case LY_STMT_EXTENSION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004179 LY_CHECK_RET(parse_extension(ctx, in, &mod->extensions));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004180 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004181 case LY_STMT_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004182 LY_CHECK_RET(parse_feature(ctx, in, &mod->features));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004183 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004184 case LY_STMT_GROUPING:
Michal Vasko63f3d842020-07-08 10:10:14 +02004185 LY_CHECK_RET(parse_grouping(ctx, in, NULL, &mod->groupings));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004186 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004187 case LY_STMT_IDENTITY:
Michal Vasko63f3d842020-07-08 10:10:14 +02004188 LY_CHECK_RET(parse_identity(ctx, in, &mod->identities));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004189 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004190 case LY_STMT_NOTIFICATION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004191 LY_CHECK_RET(parse_notif(ctx, in, NULL, &mod->notifs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004192 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004193 case LY_STMT_RPC:
Michal Vasko63f3d842020-07-08 10:10:14 +02004194 LY_CHECK_RET(parse_action(ctx, in, NULL, &mod->rpcs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004195 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004196 case LY_STMT_TYPEDEF:
Michal Vasko63f3d842020-07-08 10:10:14 +02004197 LY_CHECK_RET(parse_typedef(ctx, NULL, in, &mod->typedefs));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004198 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004199 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004200 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &mod->exts));
Michal Vasko7fbc8162018-09-17 10:35:16 +02004201 break;
4202
4203 default:
David Sedlákb3077192019-06-19 10:55:37 +02004204 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "module");
Michal Vasko7fbc8162018-09-17 10:35:16 +02004205 return LY_EVALID;
4206 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02004207 }
Radek Krejcic59bc972018-09-17 16:13:06 +02004208 LY_CHECK_RET(ret);
Radek Krejcie86bf772018-12-14 11:39:53 +01004209
Radek Krejci6d6556c2018-11-08 09:37:45 +01004210checks:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004211 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01004212 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, mod->groupings, mod->augments, mod->rpcs, mod->notifs));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004213
Michal Vasko7fbc8162018-09-17 10:35:16 +02004214 /* mandatory substatements */
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004215 if (!mod->mod->ns) {
David Sedlákb3077192019-06-19 10:55:37 +02004216 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "namespace", "module");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004217 return LY_EVALID;
4218 } else if (!mod->mod->prefix) {
David Sedlákb3077192019-06-19 10:55:37 +02004219 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "prefix", "module");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004220 return LY_EVALID;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004221 }
4222
Radek Krejcie9e987e2018-10-31 12:50:27 +01004223 /* submodules share the namespace with the module names, so there must not be
4224 * a submodule of the same name in the context, no need for revision matching */
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004225 dup = ly_ctx_get_submodule(ctx->ctx, NULL, mod->mod->name, NULL);
4226 if (dup) {
David Sedlákb3077192019-06-19 10:55:37 +02004227 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Name collision between module and submodule of name \"%s\".", mod->mod->name);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004228 return LY_EVALID;
4229 }
4230
4231 return ret;
4232}
4233
4234/**
4235 * @brief Parse submodule substatements.
4236 *
4237 * @param[in] ctx yang parser context for logging.
Michal Vasko63f3d842020-07-08 10:10:14 +02004238 * @param[in,out] in Input structure.
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004239 * @param[out] submod Parsed submodule structure.
4240 *
4241 * @return LY_ERR values.
4242 */
Radek Krejci2d7a47b2019-05-16 13:34:10 +02004243LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02004244parse_submodule(struct lys_yang_parser_ctx *ctx, struct ly_in *in, struct lysp_submodule *submod)
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004245{
4246 LY_ERR ret = 0;
4247 char *buf, *word;
4248 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02004249 enum ly_stmt kw, prev_kw = 0;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004250 enum yang_module_stmt mod_stmt = Y_MOD_MODULE_HEADER;
4251 struct lysp_submodule *dup;
4252
4253 /* submodule name */
Michal Vasko63f3d842020-07-08 10:10:14 +02004254 LY_CHECK_RET(get_argument(ctx, in, Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004255 INSERT_WORD(ctx, buf, submod->name, word, word_len);
4256
Michal Vasko63f3d842020-07-08 10:10:14 +02004257 YANG_READ_SUBSTMT_FOR(ctx, in, kw, word, word_len, ret, goto checks) {
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004258
4259#define CHECK_ORDER(SECTION) \
David Sedlákb3077192019-06-19 10:55:37 +02004260 if (mod_stmt > SECTION) {LOGVAL_PARSER(ctx, LY_VCODE_INORD, ly_stmt2str(kw), ly_stmt2str(prev_kw)); return LY_EVALID;}mod_stmt = SECTION
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004261
4262 switch (kw) {
4263 /* module header */
Radek Krejcid6b76452019-09-03 17:03:03 +02004264 case LY_STMT_BELONGS_TO:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004265 CHECK_ORDER(Y_MOD_MODULE_HEADER);
4266 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004267 case LY_STMT_YANG_VERSION:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004268 CHECK_ORDER(Y_MOD_MODULE_HEADER);
4269 break;
4270 /* linkage */
Radek Krejcid6b76452019-09-03 17:03:03 +02004271 case LY_STMT_INCLUDE:
4272 case LY_STMT_IMPORT:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004273 CHECK_ORDER(Y_MOD_LINKAGE);
4274 break;
4275 /* meta */
Radek Krejcid6b76452019-09-03 17:03:03 +02004276 case LY_STMT_ORGANIZATION:
4277 case LY_STMT_CONTACT:
4278 case LY_STMT_DESCRIPTION:
4279 case LY_STMT_REFERENCE:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004280 CHECK_ORDER(Y_MOD_META);
4281 break;
4282
4283 /* revision */
Radek Krejcid6b76452019-09-03 17:03:03 +02004284 case LY_STMT_REVISION:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004285 CHECK_ORDER(Y_MOD_REVISION);
4286 break;
4287 /* body */
Radek Krejcid6b76452019-09-03 17:03:03 +02004288 case LY_STMT_ANYDATA:
4289 case LY_STMT_ANYXML:
4290 case LY_STMT_AUGMENT:
4291 case LY_STMT_CHOICE:
4292 case LY_STMT_CONTAINER:
4293 case LY_STMT_DEVIATION:
4294 case LY_STMT_EXTENSION:
4295 case LY_STMT_FEATURE:
4296 case LY_STMT_GROUPING:
4297 case LY_STMT_IDENTITY:
4298 case LY_STMT_LEAF:
4299 case LY_STMT_LEAF_LIST:
4300 case LY_STMT_LIST:
4301 case LY_STMT_NOTIFICATION:
4302 case LY_STMT_RPC:
4303 case LY_STMT_TYPEDEF:
4304 case LY_STMT_USES:
4305 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004306 mod_stmt = Y_MOD_BODY;
4307 break;
4308 default:
4309 /* error handled in the next switch */
4310 break;
4311 }
4312#undef CHECK_ORDER
4313
4314 prev_kw = kw;
4315 switch (kw) {
4316 /* module header */
Radek Krejcid6b76452019-09-03 17:03:03 +02004317 case LY_STMT_YANG_VERSION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004318 LY_CHECK_RET(parse_yangversion(ctx, in, &submod->version, &submod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004319 ctx->mod_version = submod->version;
4320 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004321 case LY_STMT_BELONGS_TO:
Michal Vasko63f3d842020-07-08 10:10:14 +02004322 LY_CHECK_RET(parse_belongsto(ctx, in, &submod->belongsto, &submod->prefix, &submod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004323 break;
4324
4325 /* linkage */
Radek Krejcid6b76452019-09-03 17:03:03 +02004326 case LY_STMT_INCLUDE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004327 LY_CHECK_RET(parse_include(ctx, submod->name, in, &submod->includes));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004328 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004329 case LY_STMT_IMPORT:
Michal Vasko63f3d842020-07-08 10:10:14 +02004330 LY_CHECK_RET(parse_import(ctx, submod->prefix, in, &submod->imports));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004331 break;
4332
4333 /* meta */
Radek Krejcid6b76452019-09-03 17:03:03 +02004334 case LY_STMT_ORGANIZATION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004335 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_ORGANIZATION, 0, &submod->org, Y_STR_ARG, &submod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004336 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004337 case LY_STMT_CONTACT:
Michal Vasko63f3d842020-07-08 10:10:14 +02004338 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_CONTACT, 0, &submod->contact, Y_STR_ARG, &submod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004339 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004340 case LY_STMT_DESCRIPTION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004341 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_DESCRIPTION, 0, &submod->dsc, Y_STR_ARG, &submod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004342 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004343 case LY_STMT_REFERENCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004344 LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_REFERENCE, 0, &submod->ref, Y_STR_ARG, &submod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004345 break;
4346
4347 /* revision */
Radek Krejcid6b76452019-09-03 17:03:03 +02004348 case LY_STMT_REVISION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004349 LY_CHECK_RET(parse_revision(ctx, in, &submod->revs));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004350 break;
4351
4352 /* body */
Radek Krejcid6b76452019-09-03 17:03:03 +02004353 case LY_STMT_ANYDATA:
Radek Krejci335332a2019-09-05 13:03:35 +02004354 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "submodule");
Radek Krejci0f969882020-08-21 16:56:47 +02004355 /* fall through */
Radek Krejcid6b76452019-09-03 17:03:03 +02004356 case LY_STMT_ANYXML:
Michal Vasko63f3d842020-07-08 10:10:14 +02004357 LY_CHECK_RET(parse_any(ctx, in, kw, NULL, &submod->data));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004358 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004359 case LY_STMT_CHOICE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004360 LY_CHECK_RET(parse_choice(ctx, in, NULL, &submod->data));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004361 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004362 case LY_STMT_CONTAINER:
Michal Vasko63f3d842020-07-08 10:10:14 +02004363 LY_CHECK_RET(parse_container(ctx, in, NULL, &submod->data));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004364 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004365 case LY_STMT_LEAF:
Michal Vasko63f3d842020-07-08 10:10:14 +02004366 LY_CHECK_RET(parse_leaf(ctx, in, NULL, &submod->data));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004367 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004368 case LY_STMT_LEAF_LIST:
Michal Vasko63f3d842020-07-08 10:10:14 +02004369 LY_CHECK_RET(parse_leaflist(ctx, in, NULL, &submod->data));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004370 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004371 case LY_STMT_LIST:
Michal Vasko63f3d842020-07-08 10:10:14 +02004372 LY_CHECK_RET(parse_list(ctx, in, NULL, &submod->data));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004373 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004374 case LY_STMT_USES:
Michal Vasko63f3d842020-07-08 10:10:14 +02004375 LY_CHECK_RET(parse_uses(ctx, in, NULL, &submod->data));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004376 break;
4377
Radek Krejcid6b76452019-09-03 17:03:03 +02004378 case LY_STMT_AUGMENT:
Michal Vasko63f3d842020-07-08 10:10:14 +02004379 LY_CHECK_RET(parse_augment(ctx, in, NULL, &submod->augments));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004380 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004381 case LY_STMT_DEVIATION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004382 LY_CHECK_RET(parse_deviation(ctx, in, &submod->deviations));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004383 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004384 case LY_STMT_EXTENSION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004385 LY_CHECK_RET(parse_extension(ctx, in, &submod->extensions));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004386 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004387 case LY_STMT_FEATURE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004388 LY_CHECK_RET(parse_feature(ctx, in, &submod->features));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004389 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004390 case LY_STMT_GROUPING:
Michal Vasko63f3d842020-07-08 10:10:14 +02004391 LY_CHECK_RET(parse_grouping(ctx, in, NULL, &submod->groupings));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004392 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004393 case LY_STMT_IDENTITY:
Michal Vasko63f3d842020-07-08 10:10:14 +02004394 LY_CHECK_RET(parse_identity(ctx, in, &submod->identities));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004395 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004396 case LY_STMT_NOTIFICATION:
Michal Vasko63f3d842020-07-08 10:10:14 +02004397 LY_CHECK_RET(parse_notif(ctx, in, NULL, &submod->notifs));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004398 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004399 case LY_STMT_RPC:
Michal Vasko63f3d842020-07-08 10:10:14 +02004400 LY_CHECK_RET(parse_action(ctx, in, NULL, &submod->rpcs));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004401 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004402 case LY_STMT_TYPEDEF:
Michal Vasko63f3d842020-07-08 10:10:14 +02004403 LY_CHECK_RET(parse_typedef(ctx, NULL, in, &submod->typedefs));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004404 break;
Radek Krejcid6b76452019-09-03 17:03:03 +02004405 case LY_STMT_EXTENSION_INSTANCE:
Michal Vasko63f3d842020-07-08 10:10:14 +02004406 LY_CHECK_RET(parse_ext(ctx, in, word, word_len, LYEXT_SUBSTMT_SELF, 0, &submod->exts));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004407 break;
4408
4409 default:
David Sedlákb3077192019-06-19 10:55:37 +02004410 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "submodule");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004411 return LY_EVALID;
4412 }
4413 }
4414 LY_CHECK_RET(ret);
4415
4416checks:
4417 /* finalize parent pointers to the reallocated items */
Michal Vaskob36053d2020-03-26 15:49:30 +01004418 LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, submod->groupings, submod->augments,
4419 submod->rpcs, submod->notifs));
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004420
4421 /* mandatory substatements */
4422 if (!submod->belongsto) {
David Sedlákb3077192019-06-19 10:55:37 +02004423 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "belongs-to", "submodule");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004424 return LY_EVALID;
4425 }
4426
4427 /* submodules share the namespace with the module names, so there must not be
4428 * a submodule of the same name in the context, no need for revision matching */
4429 dup = ly_ctx_get_submodule(ctx->ctx, NULL, submod->name, NULL);
4430 if (dup && strcmp(dup->belongsto, submod->belongsto)) {
David Sedlákb3077192019-06-19 10:55:37 +02004431 LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Name collision between submodules of name \"%s\".", dup->name);
Radek Krejcie9e987e2018-10-31 12:50:27 +01004432 return LY_EVALID;
4433 }
4434
Michal Vasko7fbc8162018-09-17 10:35:16 +02004435 return ret;
4436}
4437
Radek Krejcid4557c62018-09-17 11:42:09 +02004438LY_ERR
Michal Vaskob36053d2020-03-26 15:49:30 +01004439yang_parse_submodule(struct lys_yang_parser_ctx **context, struct ly_ctx *ly_ctx, struct lys_parser_ctx *main_ctx,
Radek Krejci0f969882020-08-21 16:56:47 +02004440 struct ly_in *in, struct lysp_submodule **submod)
Michal Vasko7fbc8162018-09-17 10:35:16 +02004441{
Radek Krejci6d9b9b52018-11-02 12:43:39 +01004442 LY_ERR ret = LY_SUCCESS;
Radek Krejci0a1d0d42019-05-16 15:14:51 +02004443 char *word;
Radek Krejciefd22f62018-09-27 11:47:58 +02004444 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02004445 enum ly_stmt kw;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004446 struct lysp_submodule *mod_p = NULL;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004447
David Sedlák1b623122019-08-05 15:27:49 +02004448 /* create context */
4449 *context = calloc(1, sizeof **context);
4450 LY_CHECK_ERR_RET(!(*context), LOGMEM(ly_ctx), LY_EMEM);
Michal Vaskob36053d2020-03-26 15:49:30 +01004451 (*context)->format = LYS_IN_YANG;
Michal Vasko7c8439f2020-08-05 13:25:19 +02004452 (*context)->main_mod = main_ctx->main_mod;
David Sedlák1b623122019-08-05 15:27:49 +02004453 (*context)->ctx = ly_ctx;
Radek Krejci99435242019-09-05 16:19:15 +02004454 (*context)->pos_type = LY_VLOG_LINE;
David Sedlák1b623122019-08-05 15:27:49 +02004455 (*context)->line = 1;
4456
4457 /* map the typedefs and groupings list from main context to the submodule's context */
4458 memcpy(&(*context)->tpdfs_nodes, &main_ctx->tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
4459 memcpy(&(*context)->grps_nodes, &main_ctx->grps_nodes, sizeof main_ctx->grps_nodes);
4460
Michal Vasko7fbc8162018-09-17 10:35:16 +02004461 /* "module"/"submodule" */
Michal Vasko63f3d842020-07-08 10:10:14 +02004462 ret = get_keyword(*context, in, &kw, &word, &word_len);
Radek Krejcibbe09a92018-11-08 09:36:54 +01004463 LY_CHECK_GOTO(ret, cleanup);
Michal Vasko7fbc8162018-09-17 10:35:16 +02004464
Radek Krejcid6b76452019-09-03 17:03:03 +02004465 if (kw == LY_STMT_MODULE) {
David Sedlák1b623122019-08-05 15:27:49 +02004466 LOGERR((*context)->ctx, LY_EDENIED, "Input data contains module in situation when a submodule is expected.");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004467 ret = LY_EINVAL;
4468 goto cleanup;
Radek Krejcid6b76452019-09-03 17:03:03 +02004469 } else if (kw != LY_STMT_SUBMODULE) {
David Sedlák1538a842019-08-08 15:38:51 +02004470 LOGVAL_PARSER(*context, LY_VCODE_MOD_SUBOMD, ly_stmt2str(kw));
Radek Krejci40544fa2019-01-11 09:38:37 +01004471 ret = LY_EVALID;
Radek Krejcibbe09a92018-11-08 09:36:54 +01004472 goto cleanup;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004473 }
4474
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004475 mod_p = calloc(1, sizeof *mod_p);
David Sedlák1b623122019-08-05 15:27:49 +02004476 LY_CHECK_ERR_GOTO(!mod_p, LOGMEM((*context)->ctx), cleanup);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004477 mod_p->parsing = 1;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004478
4479 /* substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02004480 ret = parse_submodule(*context, in, mod_p);
Radek Krejcibbe09a92018-11-08 09:36:54 +01004481 LY_CHECK_GOTO(ret, cleanup);
Michal Vasko7fbc8162018-09-17 10:35:16 +02004482
4483 /* read some trailing spaces or new lines */
Michal Vasko63f3d842020-07-08 10:10:14 +02004484 while (isspace(in->current[0])) {
4485 ++in->current;
Radek Krejci0a1d0d42019-05-16 15:14:51 +02004486 }
Michal Vasko63f3d842020-07-08 10:10:14 +02004487 if (in->current[0]) {
4488 LOGVAL_PARSER(*context, LY_VCODE_TRAILING_SUBMOD, 15, in->current, strlen(in->current) > 15 ? "..." : "");
Radek Krejci40544fa2019-01-11 09:38:37 +01004489 ret = LY_EVALID;
Radek Krejcibbe09a92018-11-08 09:36:54 +01004490 goto cleanup;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004491 }
Michal Vasko7fbc8162018-09-17 10:35:16 +02004492
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004493 mod_p->parsing = 0;
4494 *submod = mod_p;
Michal Vasko7fbc8162018-09-17 10:35:16 +02004495
Radek Krejcibbe09a92018-11-08 09:36:54 +01004496cleanup:
4497 if (ret) {
David Sedlák1b623122019-08-05 15:27:49 +02004498 lysp_submodule_free((*context)->ctx, mod_p);
Michal Vaskob36053d2020-03-26 15:49:30 +01004499 yang_parser_ctx_free(*context);
David Sedlák1b623122019-08-05 15:27:49 +02004500 *context = NULL;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004501 }
4502
4503 return ret;
4504}
4505
4506LY_ERR
Michal Vasko63f3d842020-07-08 10:10:14 +02004507yang_parse_module(struct lys_yang_parser_ctx **context, struct ly_in *in, struct lys_module *mod)
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004508{
4509 LY_ERR ret = LY_SUCCESS;
Radek Krejci0a1d0d42019-05-16 15:14:51 +02004510 char *word;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004511 size_t word_len;
Radek Krejcid6b76452019-09-03 17:03:03 +02004512 enum ly_stmt kw;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004513 struct lysp_module *mod_p = NULL;
4514
David Sedlák1b623122019-08-05 15:27:49 +02004515 /* create context */
4516 *context = calloc(1, sizeof **context);
4517 LY_CHECK_ERR_RET(!(*context), LOGMEM(mod->ctx), LY_EMEM);
Michal Vaskob36053d2020-03-26 15:49:30 +01004518 (*context)->format = LYS_IN_YANG;
Michal Vasko7c8439f2020-08-05 13:25:19 +02004519 (*context)->main_mod = mod;
David Sedlák1b623122019-08-05 15:27:49 +02004520 (*context)->ctx = mod->ctx;
Radek Krejci335332a2019-09-05 13:03:35 +02004521 (*context)->pos_type = LY_VLOG_LINE;
David Sedlák1b623122019-08-05 15:27:49 +02004522 (*context)->line = 1;
4523
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004524 /* "module"/"submodule" */
Michal Vasko63f3d842020-07-08 10:10:14 +02004525 ret = get_keyword(*context, in, &kw, &word, &word_len);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004526 LY_CHECK_GOTO(ret, cleanup);
4527
Radek Krejcid6b76452019-09-03 17:03:03 +02004528 if (kw == LY_STMT_SUBMODULE) {
David Sedlák1b623122019-08-05 15:27:49 +02004529 LOGERR((*context)->ctx, LY_EDENIED, "Input data contains submodule which cannot be parsed directly without its main module.");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004530 ret = LY_EINVAL;
4531 goto cleanup;
Radek Krejcid6b76452019-09-03 17:03:03 +02004532 } else if (kw != LY_STMT_MODULE) {
David Sedlák1538a842019-08-08 15:38:51 +02004533 LOGVAL_PARSER((*context), LY_VCODE_MOD_SUBOMD, ly_stmt2str(kw));
Radek Krejci40544fa2019-01-11 09:38:37 +01004534 ret = LY_EVALID;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004535 goto cleanup;
4536 }
4537
4538 mod_p = calloc(1, sizeof *mod_p);
David Sedlák1b623122019-08-05 15:27:49 +02004539 LY_CHECK_ERR_GOTO(!mod_p, LOGMEM((*context)->ctx), cleanup);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004540 mod_p->mod = mod;
4541 mod_p->parsing = 1;
4542
4543 /* substatements */
Michal Vasko63f3d842020-07-08 10:10:14 +02004544 ret = parse_module(*context, in, mod_p);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004545 LY_CHECK_GOTO(ret, cleanup);
4546
4547 /* read some trailing spaces or new lines */
Michal Vasko63f3d842020-07-08 10:10:14 +02004548 while (isspace(in->current[0])) {
4549 ++in->current;
Radek Krejci0a1d0d42019-05-16 15:14:51 +02004550 }
Michal Vasko63f3d842020-07-08 10:10:14 +02004551 if (in->current[0]) {
4552 LOGVAL_PARSER(*context, LY_VCODE_TRAILING_MOD, 15, in->current, strlen(in->current) > 15 ? "..." : "");
Radek Krejci40544fa2019-01-11 09:38:37 +01004553 ret = LY_EVALID;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004554 goto cleanup;
4555 }
Radek Krejci0bcdaed2019-01-10 10:21:34 +01004556
4557 mod_p->parsing = 0;
4558 mod->parsed = mod_p;
4559
4560cleanup:
4561 if (ret) {
4562 lysp_module_free(mod_p);
Michal Vaskob36053d2020-03-26 15:49:30 +01004563 yang_parser_ctx_free(*context);
David Sedlák1b623122019-08-05 15:27:49 +02004564 *context = NULL;
Radek Krejcibbe09a92018-11-08 09:36:54 +01004565 }
4566
Michal Vasko7fbc8162018-09-17 10:35:16 +02004567 return ret;
4568}