blob: 5c345bb76adf9803b0a77d66801699b2cc96f6b5 [file] [log] [blame]
Radek Krejci335332a2019-09-05 13:03:35 +02001/**
Michal Vasko59892dd2022-05-13 11:02:30 +02002 * @file parser_common.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief libyang common parser functions.
Radek Krejci335332a2019-09-05 13:03:35 +02005 *
Michal Vasko59892dd2022-05-13 11:02:30 +02006 * Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
Radek Krejci335332a2019-09-05 13:03:35 +02007 *
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 */
14
Michal Vasko59892dd2022-05-13 11:02:30 +020015#define _GNU_SOURCE
16#define _POSIX_C_SOURCE 200809L /* strdup, strndup */
17
18#ifdef __APPLE__
19#define _DARWIN_C_SOURCE /* F_GETPATH */
20#endif
21
22#if defined (__NetBSD__) || defined (__OpenBSD__)
23/* realpath */
24#define _XOPEN_SOURCE 1
25#define _XOPEN_SOURCE_EXTENDED 1
26#endif
27
28#include "parser_internal.h"
29
Radek Krejci335332a2019-09-05 13:03:35 +020030#include <assert.h>
31#include <ctype.h>
32#include <errno.h>
Michal Vasko59892dd2022-05-13 11:02:30 +020033#include <fcntl.h>
34#include <limits.h>
Radek Krejci535ea9f2020-05-29 16:01:05 +020035#include <stdint.h>
Michal Vasko59892dd2022-05-13 11:02:30 +020036#include <stdio.h>
Radek Krejci535ea9f2020-05-29 16:01:05 +020037#include <stdlib.h>
38#include <string.h>
Michal Vasko59892dd2022-05-13 11:02:30 +020039#include <unistd.h>
Radek Krejci335332a2019-09-05 13:03:35 +020040
Radek Krejci535ea9f2020-05-29 16:01:05 +020041#include "common.h"
Michal Vasko59892dd2022-05-13 11:02:30 +020042#include "compat.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020043#include "dict.h"
Michal Vasko59892dd2022-05-13 11:02:30 +020044#include "in_internal.h"
Radek Krejci47fab892020-11-05 17:02:41 +010045#include "log.h"
Michal Vasko59892dd2022-05-13 11:02:30 +020046#include "parser_data.h"
Michal Vasko69730152020-10-09 16:30:07 +020047#include "path.h"
Radek Krejci77114102021-03-10 15:21:57 +010048#include "set.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020049#include "tree.h"
Michal Vasko59892dd2022-05-13 11:02:30 +020050#include "tree_data.h"
51#include "tree_data_internal.h"
Radek Krejci335332a2019-09-05 13:03:35 +020052#include "tree_schema.h"
53#include "tree_schema_internal.h"
54
Michal Vasko59892dd2022-05-13 11:02:30 +020055void
56lyd_ctx_free(struct lyd_ctx *lydctx)
57{
58 ly_set_erase(&lydctx->node_types, NULL);
59 ly_set_erase(&lydctx->meta_types, NULL);
60 ly_set_erase(&lydctx->node_when, NULL);
61 ly_set_erase(&lydctx->ext_val, free);
62}
63
64LY_ERR
65lyd_parser_find_operation(const struct lyd_node *parent, uint32_t int_opts, struct lyd_node **op)
66{
67 const struct lyd_node *iter;
68
69 *op = NULL;
70
71 if (!parent) {
72 /* no parent, nothing to look for */
73 return LY_SUCCESS;
74 }
75
76 /* we need to find the operation node if it already exists */
77 for (iter = parent; iter; iter = lyd_parent(iter)) {
78 if (iter->schema && (iter->schema->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))) {
79 break;
80 }
81 }
82
83 if (!iter) {
84 /* no operation found */
85 return LY_SUCCESS;
86 }
87
88 if (!(int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_ACTION | LYD_INTOPT_NOTIF | LYD_INTOPT_REPLY))) {
89 LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent %s \"%s\" node when not parsing any operation.",
90 lys_nodetype2str(iter->schema->nodetype), iter->schema->name);
91 return LY_EINVAL;
92 } else if ((iter->schema->nodetype == LYS_RPC) && !(int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY))) {
93 LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent RPC \"%s\" node when not parsing RPC nor rpc-reply.",
94 iter->schema->name);
95 return LY_EINVAL;
96 } else if ((iter->schema->nodetype == LYS_ACTION) && !(int_opts & (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY))) {
97 LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent action \"%s\" node when not parsing action nor rpc-reply.",
98 iter->schema->name);
99 return LY_EINVAL;
100 } else if ((iter->schema->nodetype == LYS_NOTIF) && !(int_opts & LYD_INTOPT_NOTIF)) {
101 LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent notification \"%s\" node when not parsing a notification.",
102 iter->schema->name);
103 return LY_EINVAL;
104 }
105
106 *op = (struct lyd_node *)iter;
107 return LY_SUCCESS;
108}
109
110LY_ERR
111lyd_parser_check_schema(struct lyd_ctx *lydctx, const struct lysc_node *snode)
112{
113 LY_ERR rc = LY_SUCCESS;
114
115 LOG_LOCSET(snode, NULL, NULL, NULL);
116
117 if (lydctx->int_opts & LYD_INTOPT_ANY) {
118 /* nothing to check, everything is allowed */
119 goto cleanup;
120 }
121
122 if ((lydctx->parse_opts & LYD_PARSE_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
123 LOGVAL(lydctx->data_ctx->ctx, LY_VCODE_UNEXPNODE, "state", snode->name);
124 rc = LY_EVALID;
125 goto cleanup;
126 }
127
128 if (snode->nodetype == LYS_RPC) {
129 if (lydctx->int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY)) {
130 if (lydctx->op_node) {
131 goto error_node_dup;
132 }
133 } else {
134 goto error_node_inval;
135 }
136 } else if (snode->nodetype == LYS_ACTION) {
137 if (lydctx->int_opts & (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY)) {
138 if (lydctx->op_node) {
139 goto error_node_dup;
140 }
141 } else {
142 goto error_node_inval;
143 }
144 } else if (snode->nodetype == LYS_NOTIF) {
145 if (lydctx->int_opts & LYD_INTOPT_NOTIF) {
146 if (lydctx->op_node) {
147 goto error_node_dup;
148 }
149 } else {
150 goto error_node_inval;
151 }
152 }
153
154 /* success */
155 goto cleanup;
156
157error_node_dup:
158 LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\", %s \"%s\" already parsed.",
159 lys_nodetype2str(snode->nodetype), snode->name, lys_nodetype2str(lydctx->op_node->schema->nodetype),
160 lydctx->op_node->schema->name);
161 rc = LY_EVALID;
162 goto cleanup;
163
164error_node_inval:
165 LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\".", lys_nodetype2str(snode->nodetype),
166 snode->name);
167 rc = LY_EVALID;
168
169cleanup:
170 LOG_LOCBACK(1, 0, 0, 0);
171 return rc;
172}
173
174LY_ERR
175lyd_parser_create_term(struct lyd_ctx *lydctx, const struct lysc_node *schema, const void *value, size_t value_len,
176 ly_bool *dynamic, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, struct lyd_node **node)
177{
178 ly_bool incomplete;
179
180 LY_CHECK_RET(lyd_create_term(schema, value, value_len, dynamic, format, prefix_data, hints, &incomplete, node));
181
182 if (incomplete && !(lydctx->parse_opts & LYD_PARSE_ONLY)) {
183 LY_CHECK_RET(ly_set_add(&lydctx->node_types, *node, 1, NULL));
184 }
185 return LY_SUCCESS;
186}
187
188LY_ERR
189lyd_parser_create_meta(struct lyd_ctx *lydctx, struct lyd_node *parent, struct lyd_meta **meta, const struct lys_module *mod,
190 const char *name, size_t name_len, const void *value, size_t value_len, ly_bool *dynamic, LY_VALUE_FORMAT format,
191 void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node)
192{
193 ly_bool incomplete;
194 struct lyd_meta *first = NULL;
195
196 if (meta && *meta) {
197 /* remember the first metadata */
198 first = *meta;
199 }
200
201 LY_CHECK_RET(lyd_create_meta(parent, meta, mod, name, name_len, value, value_len, dynamic, format, prefix_data,
202 hints, ctx_node, 0, &incomplete));
203
204 if (incomplete && !(lydctx->parse_opts & LYD_PARSE_ONLY)) {
205 LY_CHECK_RET(ly_set_add(&lydctx->meta_types, *meta, 1, NULL));
206 }
207
208 if (first) {
209 /* always return the first metadata */
210 *meta = first;
211 }
212
213 return LY_SUCCESS;
214}
215
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100216static LY_ERR lysp_stmt_container(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
217 struct lysp_node **siblings);
218static LY_ERR lysp_stmt_choice(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
219 struct lysp_node **siblings);
220static LY_ERR lysp_stmt_case(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
221 struct lysp_node **siblings);
222static LY_ERR lysp_stmt_uses(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
223 struct lysp_node **siblings);
224static LY_ERR lysp_stmt_grouping(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
225 struct lysp_node_grp **groupings);
226static LY_ERR lysp_stmt_list(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
227 struct lysp_node **siblings);
228
Radek Krejci335332a2019-09-05 13:03:35 +0200229static LY_ERR
230lysp_stmt_validate_value(struct lys_parser_ctx *ctx, enum yang_arg val_type, const char *val)
231{
Radek Krejci857189e2020-09-01 13:26:36 +0200232 uint8_t prefix = 0;
233 ly_bool first = 1;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200234 uint32_t c;
Radek Krejci335332a2019-09-05 13:03:35 +0200235 size_t utf8_char_len;
236
237 while (*val) {
238 LY_CHECK_ERR_RET(ly_getutf8(&val, &c, &utf8_char_len),
Michal Vasko69730152020-10-09 16:30:07 +0200239 LOGVAL_PARSER(ctx, LY_VCODE_INCHAR, (val)[-utf8_char_len]), LY_EVALID);
Radek Krejci335332a2019-09-05 13:03:35 +0200240
241 switch (val_type) {
242 case Y_IDENTIF_ARG:
243 LY_CHECK_RET(lysp_check_identifierchar(ctx, c, first, NULL));
244 break;
245 case Y_PREF_IDENTIF_ARG:
246 LY_CHECK_RET(lysp_check_identifierchar(ctx, c, first, &prefix));
247 break;
248 case Y_STR_ARG:
249 case Y_MAYBE_STR_ARG:
250 LY_CHECK_RET(lysp_check_stringchar(ctx, c));
251 break;
252 }
253 first = 0;
254 }
255
256 return LY_SUCCESS;
257}
258
259/**
260 * @brief Parse extension instance.
261 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100262 * @param[in] ctx parser context.
263 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejcifc596f92021-02-26 22:40:26 +0100264 * @param[in] insubstmt The statement this extension instance is a substatement of.
Radek Krejci335332a2019-09-05 13:03:35 +0200265 * @param[in] insubstmt_index Index of the keyword instance this extension instance is a substatement of.
266 * @param[in,out] exts Extension instances to add to.
267 *
268 * @return LY_ERR values.
269 */
270static LY_ERR
Radek Krejcifc596f92021-02-26 22:40:26 +0100271lysp_stmt_ext(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, enum ly_stmt insubstmt,
Radek Krejci0f969882020-08-21 16:56:47 +0200272 LY_ARRAY_COUNT_TYPE insubstmt_index, struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200273{
274 struct lysp_ext_instance *e;
275
Michal Vaskob36053d2020-03-26 15:49:30 +0100276 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *exts, e, LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +0200277
278 /* store name and insubstmt info */
Radek Krejci011e4aa2020-09-04 15:22:31 +0200279 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->stmt, 0, &e->name));
Radek Krejciab430862021-03-02 20:13:40 +0100280 e->parent_stmt = insubstmt;
281 e->parent_stmt_index = insubstmt_index;
aPiecek60d9d672021-04-27 15:49:57 +0200282 e->parsed = NULL;
Radek Krejci335332a2019-09-05 13:03:35 +0200283 /* TODO (duplicate) e->child = stmt->child; */
284
285 /* get optional argument */
286 if (stmt->arg) {
Radek Krejci011e4aa2020-09-04 15:22:31 +0200287 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &e->argument));
Radek Krejci335332a2019-09-05 13:03:35 +0200288 }
289
290 return LY_SUCCESS;
291}
292
293/**
294 * @brief Parse a generic text field without specific constraints. Those are contact, organization,
295 * description, etc...
296 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100297 * @param[in] ctx parser context.
298 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200299 * @param[in] substmt_index Index of this substatement.
300 * @param[in,out] value Place to store the parsed value.
301 * @param[in] arg Type of the YANG keyword argument (of the value).
302 * @param[in,out] exts Extension instances to add to.
303 *
304 * @return LY_ERR values.
305 */
306static LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100307lysp_stmt_text_field(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint32_t substmt_index,
Radek Krejci0f969882020-08-21 16:56:47 +0200308 const char **value, enum yang_arg arg, struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200309{
Radek Krejci335332a2019-09-05 13:03:35 +0200310 if (*value) {
Radek Krejci3972b332021-03-02 16:34:31 +0100311 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200312 return LY_EVALID;
313 }
314
315 LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
Radek Krejci011e4aa2020-09-04 15:22:31 +0200316 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, value));
Radek Krejci335332a2019-09-05 13:03:35 +0200317
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100318 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
319 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200320 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100321 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, substmt_index, exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200322 break;
323 default:
Radek Krejci3972b332021-03-02 16:34:31 +0100324 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200325 return LY_EVALID;
326 }
327 }
328 return LY_SUCCESS;
329}
330
331/**
Michal Vasko7f45cf22020-10-01 12:49:44 +0200332 * @brief Parse a qname that can have more instances such as if-feature.
333 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100334 * @param[in] ctx parser context.
335 * @param[in] stmt Source statement data from the parsed extension instance.
Michal Vasko7f45cf22020-10-01 12:49:44 +0200336 * @param[in,out] qnames Parsed qnames to add to.
337 * @param[in] arg Type of the expected argument.
338 * @param[in,out] exts Extension instances to add to.
339 *
340 * @return LY_ERR values.
341 */
342static LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100343lysp_stmt_qnames(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
Michal Vasko7f45cf22020-10-01 12:49:44 +0200344 struct lysp_qname **qnames, enum yang_arg arg, struct lysp_ext_instance **exts)
345{
346 struct lysp_qname *item;
Michal Vasko7f45cf22020-10-01 12:49:44 +0200347
348 LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
349
350 /* allocate new pointer */
351 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *qnames, item, LY_EMEM);
352 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &item->str));
Michal Vasko8a67eff2021-12-07 14:04:47 +0100353 item->mod = PARSER_CUR_PMOD(ctx);
Michal Vasko7f45cf22020-10-01 12:49:44 +0200354
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100355 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
356 switch (child->kw) {
Michal Vasko7f45cf22020-10-01 12:49:44 +0200357 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100358 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*qnames) - 1, exts));
Michal Vasko7f45cf22020-10-01 12:49:44 +0200359 break;
360 default:
Radek Krejci3972b332021-03-02 16:34:31 +0100361 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
Michal Vasko7f45cf22020-10-01 12:49:44 +0200362 return LY_EVALID;
363 }
364 }
365 return LY_SUCCESS;
366}
367
368/**
Radek Krejci335332a2019-09-05 13:03:35 +0200369 * @brief Parse a generic text field that can have more instances such as base.
370 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100371 * @param[in] ctx parser context.
372 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200373 * @param[in,out] texts Parsed values to add to.
374 * @param[in] arg Type of the expected argument.
375 * @param[in,out] exts Extension instances to add to.
376 *
377 * @return LY_ERR values.
378 */
379static LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100380lysp_stmt_text_fields(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
Radek Krejci0f969882020-08-21 16:56:47 +0200381 const char ***texts, enum yang_arg arg, struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200382{
383 const char **item;
Radek Krejci335332a2019-09-05 13:03:35 +0200384
385 LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
386
387 /* allocate new pointer */
Michal Vaskob36053d2020-03-26 15:49:30 +0100388 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *texts, item, LY_EMEM);
Radek Krejci011e4aa2020-09-04 15:22:31 +0200389 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, item));
Radek Krejci335332a2019-09-05 13:03:35 +0200390
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100391 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
392 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200393 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100394 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*texts) - 1, exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200395 break;
396 default:
Radek Krejci3972b332021-03-02 16:34:31 +0100397 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200398 return LY_EVALID;
399 }
400 }
401 return LY_SUCCESS;
402}
403
404/**
405 * @brief Parse the status statement.
406 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100407 * @param[in] ctx parser context.
408 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200409 * @param[in,out] flags Flags to add to.
410 * @param[in,out] exts Extension instances to add to.
411 *
412 * @return LY_ERR values.
413 */
414static LY_ERR
415lysp_stmt_status(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
416{
417 size_t arg_len;
Radek Krejci335332a2019-09-05 13:03:35 +0200418
419 if (*flags & LYS_STATUS_MASK) {
420 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "status");
421 return LY_EVALID;
422 }
423
424 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
425 arg_len = strlen(stmt->arg);
Radek Krejcif13b87b2020-12-01 22:02:17 +0100426 if ((arg_len == ly_strlen_const("current")) && !strncmp(stmt->arg, "current", arg_len)) {
Radek Krejci335332a2019-09-05 13:03:35 +0200427 *flags |= LYS_STATUS_CURR;
Radek Krejcif13b87b2020-12-01 22:02:17 +0100428 } else if ((arg_len == ly_strlen_const("deprecated")) && !strncmp(stmt->arg, "deprecated", arg_len)) {
Radek Krejci335332a2019-09-05 13:03:35 +0200429 *flags |= LYS_STATUS_DEPRC;
Radek Krejcif13b87b2020-12-01 22:02:17 +0100430 } else if ((arg_len == ly_strlen_const("obsolete")) && !strncmp(stmt->arg, "obsolete", arg_len)) {
Radek Krejci335332a2019-09-05 13:03:35 +0200431 *flags |= LYS_STATUS_OBSLT;
432 } else {
433 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "status");
434 return LY_EVALID;
435 }
436
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100437 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
438 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200439 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +0100440 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_STATUS, 0, exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200441 break;
442 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100443 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "status");
Radek Krejci335332a2019-09-05 13:03:35 +0200444 return LY_EVALID;
445 }
446 }
447 return LY_SUCCESS;
448}
449
450/**
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100451 * @brief Parse the when statement.
Radek Krejci335332a2019-09-05 13:03:35 +0200452 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100453 * @param[in] ctx parser context.
454 * @param[in] stmt Source statement data from the parsed extension instance.
455 * @param[in,out] when_p When pointer to parse to.
456 *
457 * @return LY_ERR values.
458 */
459static LY_ERR
460lysp_stmt_when(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_when **when_p)
461{
462 LY_ERR ret = LY_SUCCESS;
463 struct lysp_when *when;
464
465 if (*when_p) {
466 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "when");
467 return LY_EVALID;
468 }
469
470 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
471
472 when = calloc(1, sizeof *when);
473 LY_CHECK_ERR_RET(!when, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
474 *when_p = when;
475
476 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &when->cond));
477
478 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
479 switch (child->kw) {
480 case LY_STMT_DESCRIPTION:
481 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &when->dsc, Y_STR_ARG, &when->exts));
482 break;
483 case LY_STMT_REFERENCE:
484 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &when->ref, Y_STR_ARG, &when->exts));
485 break;
486 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +0100487 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_WHEN, 0, &when->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100488 break;
489 default:
490 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "when");
491 return LY_EVALID;
492 }
493 }
494 return ret;
495}
496
497/**
498 * @brief Parse the config statement.
499 *
500 * @param[in] ctx parser context.
501 * @param[in] stmt Source statement data from the parsed extension instance.
502 * @param[in,out] flags Flags to add to.
Radek Krejci335332a2019-09-05 13:03:35 +0200503 * @param[in,out] exts Extension instances to add to.
504 *
505 * @return LY_ERR values.
506 */
507static LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100508lysp_stmt_config(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200509{
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100510 size_t arg_len;
Radek Krejci335332a2019-09-05 13:03:35 +0200511
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100512 if (*flags & LYS_CONFIG_MASK) {
513 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "config");
514 return LY_EVALID;
515 }
516
517 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
518 arg_len = strlen(stmt->arg);
519 if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
520 *flags |= LYS_CONFIG_W;
521 } else if ((arg_len == ly_strlen_const("false")) && !strncmp(stmt->arg, "false", arg_len)) {
522 *flags |= LYS_CONFIG_R;
523 } else {
524 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "config");
525 return LY_EVALID;
526 }
527
528 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
529 switch (child->kw) {
530 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +0100531 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONFIG, 0, exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100532 break;
533 default:
534 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "config");
535 return LY_EVALID;
536 }
537 }
538
539 return LY_SUCCESS;
540}
541
542/**
543 * @brief Parse the mandatory statement.
544 *
545 * @param[in] ctx parser context.
546 * @param[in] stmt Source statement data from the parsed extension instance.
547 * @param[in,out] flags Flags to add to.
548 * @param[in,out] exts Extension instances to add to.
549 *
550 * @return LY_ERR values.
551 */
552static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +0200553lysp_stmt_mandatory(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags,
554 struct lysp_ext_instance **exts)
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100555{
556 size_t arg_len;
557
558 if (*flags & LYS_MAND_MASK) {
559 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "mandatory");
560 return LY_EVALID;
561 }
562
563 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
564 arg_len = strlen(stmt->arg);
565 if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
566 *flags |= LYS_MAND_TRUE;
567 } else if ((arg_len == ly_strlen_const("false")) && !strncmp(stmt->arg, "false", arg_len)) {
568 *flags |= LYS_MAND_FALSE;
569 } else {
570 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "mandatory");
571 return LY_EVALID;
572 }
573
574 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
575 switch (child->kw) {
576 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +0100577 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MANDATORY, 0, exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100578 break;
579 default:
580 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "mandatory");
581 return LY_EVALID;
582 }
583 }
584
585 return LY_SUCCESS;
586}
587
588/**
589 * @brief Parse a restriction such as range or length.
590 *
591 * @param[in] ctx parser context.
592 * @param[in] stmt Source statement data from the parsed extension instance.
593 * @param[in,out] exts Extension instances to add to.
594 *
595 * @return LY_ERR values.
596 */
597static LY_ERR
598lysp_stmt_restr(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr *restr)
599{
Radek Krejci335332a2019-09-05 13:03:35 +0200600 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
Michal Vasko7f45cf22020-10-01 12:49:44 +0200601 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &restr->arg.str));
Michal Vasko8a67eff2021-12-07 14:04:47 +0100602 restr->arg.mod = PARSER_CUR_PMOD(ctx);
Radek Krejci335332a2019-09-05 13:03:35 +0200603
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100604 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
605 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200606 case LY_STMT_DESCRIPTION:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100607 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200608 break;
609 case LY_STMT_REFERENCE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100610 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->ref, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200611 break;
612 case LY_STMT_ERROR_APP_TAG:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100613 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200614 break;
615 case LY_STMT_ERROR_MESSAGE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100616 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200617 break;
618 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +0100619 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200620 break;
621 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100622 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200623 return LY_EVALID;
624 }
625 }
626 return LY_SUCCESS;
627}
628
629/**
630 * @brief Parse a restriction that can have more instances such as must.
631 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100632 * @param[in] ctx parser context.
633 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200634 * @param[in,out] restrs Restrictions to add to.
635 *
636 * @return LY_ERR values.
637 */
638static LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100639lysp_stmt_restrs(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr **restrs)
Radek Krejci335332a2019-09-05 13:03:35 +0200640{
641 struct lysp_restr *restr;
642
Michal Vaskob36053d2020-03-26 15:49:30 +0100643 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *restrs, restr, LY_EMEM);
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100644 return lysp_stmt_restr(ctx, stmt, restr);
645}
646
647/**
648 * @brief Parse the anydata or anyxml statement.
649 *
650 * @param[in] ctx parser context.
651 * @param[in] stmt Source statement data from the parsed extension instance.
652 * @param[in,out] siblings Siblings to add to.
653 *
654 * @return LY_ERR values.
655 */
656static LY_ERR
657lysp_stmt_any(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
658{
659 struct lysp_node_anydata *any;
660
661 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
662
663 /* create new structure and insert into siblings */
664 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, any, next, LY_EMEM);
665
666 any->nodetype = stmt->kw == LY_STMT_ANYDATA ? LYS_ANYDATA : LYS_ANYXML;
667 any->parent = parent;
668
669 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &any->name));
670
671 /* parse substatements */
672 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
673 switch (child->kw) {
674 case LY_STMT_CONFIG:
675 LY_CHECK_RET(lysp_stmt_config(ctx, child, &any->flags, &any->exts));
676 break;
677 case LY_STMT_DESCRIPTION:
678 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &any->dsc, Y_STR_ARG, &any->exts));
679 break;
680 case LY_STMT_IF_FEATURE:
681 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &any->iffeatures, Y_STR_ARG, &any->exts));
682 break;
683 case LY_STMT_MANDATORY:
684 LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &any->flags, &any->exts));
685 break;
686 case LY_STMT_MUST:
687 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &any->musts));
688 break;
689 case LY_STMT_REFERENCE:
690 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &any->ref, Y_STR_ARG, &any->exts));
691 break;
692 case LY_STMT_STATUS:
693 LY_CHECK_RET(lysp_stmt_status(ctx, child, &any->flags, &any->exts));
694 break;
695 case LY_STMT_WHEN:
696 LY_CHECK_RET(lysp_stmt_when(ctx, child, &any->when));
697 break;
698 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +0100699 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &any->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100700 break;
701 default:
702 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
703 (any->nodetype & LYS_ANYDATA) == LYS_ANYDATA ? ly_stmt2str(LY_STMT_ANYDATA) : ly_stmt2str(LY_STMT_ANYXML));
704 return LY_EVALID;
705 }
706 }
707
708 return LY_SUCCESS;
Radek Krejci335332a2019-09-05 13:03:35 +0200709}
710
711/**
712 * @brief Parse the value or position statement. Substatement of type enum statement.
713 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100714 * @param[in] ctx parser context.
715 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200716 * @param[in,out] value Value to write to.
717 * @param[in,out] flags Flags to write to.
718 * @param[in,out] exts Extension instances to add to.
719 *
720 * @return LY_ERR values.
721 */
722static LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100723lysp_stmt_type_enum_value_pos(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, int64_t *value, uint16_t *flags,
Radek Krejci0f969882020-08-21 16:56:47 +0200724 struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200725{
726 size_t arg_len;
727 char *ptr = NULL;
Michal Vasko73d77ab2021-07-23 12:45:55 +0200728 long long int num = 0;
729 unsigned long long int unum = 0;
Radek Krejci335332a2019-09-05 13:03:35 +0200730
731 if (*flags & LYS_SET_VALUE) {
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100732 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200733 return LY_EVALID;
734 }
735 *flags |= LYS_SET_VALUE;
736
737 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
738
739 arg_len = strlen(stmt->arg);
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100740 if (!arg_len || (stmt->arg[0] == '+') || ((stmt->arg[0] == '0') && (arg_len > 1)) ||
741 ((stmt->kw == LY_STMT_POSITION) && !strncmp(stmt->arg, "-0", 2))) {
742 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200743 goto error;
744 }
745
746 errno = 0;
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100747 if (stmt->kw == LY_STMT_VALUE) {
Michal Vasko73d77ab2021-07-23 12:45:55 +0200748 num = strtoll(stmt->arg, &ptr, LY_BASE_DEC);
Michal Vasko69730152020-10-09 16:30:07 +0200749 if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100750 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200751 goto error;
752 }
753 } else {
Michal Vasko73d77ab2021-07-23 12:45:55 +0200754 unum = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
Radek Krejci335332a2019-09-05 13:03:35 +0200755 if (unum > UINT64_C(4294967295)) {
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100756 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200757 goto error;
758 }
759 }
760 /* we have not parsed the whole argument */
761 if ((size_t)(ptr - stmt->arg) != arg_len) {
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100762 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200763 goto error;
764 }
765 if (errno == ERANGE) {
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100766 LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200767 goto error;
768 }
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100769 if (stmt->kw == LY_STMT_VALUE) {
Radek Krejci335332a2019-09-05 13:03:35 +0200770 *value = num;
771 } else {
772 *value = unum;
773 }
774
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100775 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
776 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200777 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +0100778 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw == LY_STMT_VALUE ? LY_STMT_VALUE : LY_STMT_POSITION, 0, exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200779 break;
780 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100781 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200782 return LY_EVALID;
783 }
784 }
785 return LY_SUCCESS;
786
787error:
788 return LY_EVALID;
789}
790
791/**
792 * @brief Parse the enum or bit statement. Substatement of type statement.
793 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100794 * @param[in] ctx parser context.
795 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200796 * @param[in,out] enums Enums or bits to add to.
797 *
798 * @return LY_ERR values.
799 */
800static LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100801lysp_stmt_type_enum(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_type_enum **enums)
Radek Krejci335332a2019-09-05 13:03:35 +0200802{
803 struct lysp_type_enum *enm;
Radek Krejci335332a2019-09-05 13:03:35 +0200804
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100805 LY_CHECK_RET(lysp_stmt_validate_value(ctx, stmt->kw == LY_STMT_ENUM ? Y_STR_ARG : Y_IDENTIF_ARG, stmt->arg));
Radek Krejci335332a2019-09-05 13:03:35 +0200806
Michal Vaskob36053d2020-03-26 15:49:30 +0100807 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *enums, enm, LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +0200808
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100809 if (stmt->kw == LY_STMT_ENUM) {
Radek Krejci335332a2019-09-05 13:03:35 +0200810 LY_CHECK_RET(lysp_check_enum_name(ctx, stmt->arg, strlen(stmt->arg)));
811 } /* else nothing specific for YANG_BIT */
812
Radek Krejci011e4aa2020-09-04 15:22:31 +0200813 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &enm->name));
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100814 CHECK_UNIQUENESS(ctx, *enums, name, ly_stmt2str(stmt->kw), enm->name);
Radek Krejci335332a2019-09-05 13:03:35 +0200815
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100816 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
817 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200818 case LY_STMT_DESCRIPTION:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100819 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200820 break;
821 case LY_STMT_IF_FEATURE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100822 PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", ly_stmt2str(stmt->kw));
823 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &enm->iffeatures, Y_STR_ARG, &enm->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200824 break;
825 case LY_STMT_REFERENCE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100826 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &enm->ref, Y_STR_ARG, &enm->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200827 break;
828 case LY_STMT_STATUS:
829 LY_CHECK_RET(lysp_stmt_status(ctx, child, &enm->flags, &enm->exts));
830 break;
831 case LY_STMT_VALUE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100832 LY_CHECK_ERR_RET(stmt->kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
833 ly_stmt2str(stmt->kw)), LY_EVALID);
834 LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200835 break;
836 case LY_STMT_POSITION:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100837 LY_CHECK_ERR_RET(stmt->kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
838 ly_stmt2str(stmt->kw)), LY_EVALID);
839 LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200840 break;
841 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +0100842 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &enm->exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200843 break;
844 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100845 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
Radek Krejci335332a2019-09-05 13:03:35 +0200846 return LY_EVALID;
847 }
848 }
849 return LY_SUCCESS;
850}
851
852/**
853 * @brief Parse the fraction-digits statement. Substatement of type statement.
854 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100855 * @param[in] ctx parser context.
856 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200857 * @param[in,out] fracdig Value to write to.
858 * @param[in,out] exts Extension instances to add to.
859 *
860 * @return LY_ERR values.
861 */
862static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +0200863lysp_stmt_type_fracdigits(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *fracdig,
864 struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200865{
866 char *ptr;
867 size_t arg_len;
Michal Vasko73d77ab2021-07-23 12:45:55 +0200868 unsigned long long int num;
Radek Krejci335332a2019-09-05 13:03:35 +0200869
870 if (*fracdig) {
871 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "fraction-digits");
872 return LY_EVALID;
873 }
874
875 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
876 arg_len = strlen(stmt->arg);
877 if (!arg_len || (stmt->arg[0] == '0') || !isdigit(stmt->arg[0])) {
878 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "fraction-digits");
879 return LY_EVALID;
880 }
881
882 errno = 0;
Michal Vasko73d77ab2021-07-23 12:45:55 +0200883 num = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
Radek Krejci335332a2019-09-05 13:03:35 +0200884 /* we have not parsed the whole argument */
885 if ((size_t)(ptr - stmt->arg) != arg_len) {
886 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "fraction-digits");
887 return LY_EVALID;
888 }
Radek Krejcif13b87b2020-12-01 22:02:17 +0100889 if ((errno == ERANGE) || (num > LY_TYPE_DEC64_FD_MAX)) {
Radek Krejci335332a2019-09-05 13:03:35 +0200890 LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "fraction-digits");
891 return LY_EVALID;
892 }
893 *fracdig = num;
894
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100895 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
896 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200897 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +0100898 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_FRACTION_DIGITS, 0, exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200899 break;
900 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100901 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "fraction-digits");
Radek Krejci335332a2019-09-05 13:03:35 +0200902 return LY_EVALID;
903 }
904 }
905 return LY_SUCCESS;
906}
907
908/**
909 * @brief Parse the require-instance statement. Substatement of type statement.
910 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100911 * @param[in] ctx parser context.
912 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200913 * @param[in,out] reqinst Value to write to.
914 * @param[in,out] flags Flags to write to.
915 * @param[in,out] exts Extension instances to add to.
916 *
917 * @return LY_ERR values.
918 */
919static LY_ERR
920lysp_stmt_type_reqinstance(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *reqinst, uint16_t *flags,
Radek Krejci0f969882020-08-21 16:56:47 +0200921 struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200922{
923 size_t arg_len;
Radek Krejci335332a2019-09-05 13:03:35 +0200924
925 if (*flags & LYS_SET_REQINST) {
926 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "require-instance");
927 return LY_EVALID;
928 }
929 *flags |= LYS_SET_REQINST;
930
931 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
932 arg_len = strlen(stmt->arg);
Radek Krejcif13b87b2020-12-01 22:02:17 +0100933 if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
Radek Krejci335332a2019-09-05 13:03:35 +0200934 *reqinst = 1;
Radek Krejcif13b87b2020-12-01 22:02:17 +0100935 } else if ((arg_len != ly_strlen_const("false")) || strncmp(stmt->arg, "false", arg_len)) {
Radek Krejci335332a2019-09-05 13:03:35 +0200936 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "require-instance");
937 return LY_EVALID;
938 }
939
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100940 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
941 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200942 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +0100943 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REQUIRE_INSTANCE, 0, exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200944 break;
945 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100946 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "require-instance");
Radek Krejci335332a2019-09-05 13:03:35 +0200947 return LY_EVALID;
948 }
949 }
950 return LY_SUCCESS;
951}
952
953/**
954 * @brief Parse the modifier statement. Substatement of type pattern statement.
955 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100956 * @param[in] ctx parser context.
957 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +0200958 * @param[in,out] pat Value to write to.
959 * @param[in,out] exts Extension instances to add to.
960 *
961 * @return LY_ERR values.
962 */
963static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +0200964lysp_stmt_type_pattern_modifier(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, const char **pat,
965 struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +0200966{
967 size_t arg_len;
968 char *buf;
Radek Krejci335332a2019-09-05 13:03:35 +0200969
Radek Krejcif13b87b2020-12-01 22:02:17 +0100970 if ((*pat)[0] == LYSP_RESTR_PATTERN_NACK) {
Radek Krejci335332a2019-09-05 13:03:35 +0200971 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "modifier");
972 return LY_EVALID;
973 }
974
975 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
976 arg_len = strlen(stmt->arg);
Radek Krejcif13b87b2020-12-01 22:02:17 +0100977 if ((arg_len != ly_strlen_const("invert-match")) || strncmp(stmt->arg, "invert-match", arg_len)) {
Radek Krejci335332a2019-09-05 13:03:35 +0200978 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "modifier");
979 return LY_EVALID;
980 }
981
982 /* replace the value in the dictionary */
983 buf = malloc(strlen(*pat) + 1);
Michal Vaskob36053d2020-03-26 15:49:30 +0100984 LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +0200985 strcpy(buf, *pat);
Michal Vaskob36053d2020-03-26 15:49:30 +0100986 lydict_remove(PARSER_CTX(ctx), *pat);
Radek Krejci335332a2019-09-05 13:03:35 +0200987
Radek Krejcif13b87b2020-12-01 22:02:17 +0100988 assert(buf[0] == LYSP_RESTR_PATTERN_ACK);
989 buf[0] = LYSP_RESTR_PATTERN_NACK;
Radek Krejci011e4aa2020-09-04 15:22:31 +0200990 LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, pat));
Radek Krejci335332a2019-09-05 13:03:35 +0200991
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100992 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
993 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +0200994 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +0100995 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MODIFIER, 0, exts));
Radek Krejci335332a2019-09-05 13:03:35 +0200996 break;
997 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +0100998 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "modifier");
Radek Krejci335332a2019-09-05 13:03:35 +0200999 return LY_EVALID;
1000 }
1001 }
1002 return LY_SUCCESS;
1003}
1004
1005/**
1006 * @brief Parse the pattern statement. Substatement of type statement.
1007 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001008 * @param[in] ctx parser context.
1009 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +02001010 * @param[in,out] patterns Restrictions to add to.
1011 *
1012 * @return LY_ERR values.
1013 */
1014static LY_ERR
1015lysp_stmt_type_pattern(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr **patterns)
1016{
1017 char *buf;
1018 size_t arg_len;
Radek Krejci335332a2019-09-05 13:03:35 +02001019 struct lysp_restr *restr;
1020
1021 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
Michal Vaskob36053d2020-03-26 15:49:30 +01001022 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *patterns, restr, LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +02001023 arg_len = strlen(stmt->arg);
1024
1025 /* add special meaning first byte */
1026 buf = malloc(arg_len + 2);
Michal Vaskob36053d2020-03-26 15:49:30 +01001027 LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +02001028 memmove(buf + 1, stmt->arg, arg_len);
Radek Krejcif13b87b2020-12-01 22:02:17 +01001029 buf[0] = LYSP_RESTR_PATTERN_ACK; /* pattern's default regular-match flag */
Radek Krejci335332a2019-09-05 13:03:35 +02001030 buf[arg_len + 1] = '\0'; /* terminating NULL byte */
Michal Vasko7f45cf22020-10-01 12:49:44 +02001031 LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, &restr->arg.str));
Michal Vasko8a67eff2021-12-07 14:04:47 +01001032 restr->arg.mod = PARSER_CUR_PMOD(ctx);
Radek Krejci335332a2019-09-05 13:03:35 +02001033
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001034 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1035 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +02001036 case LY_STMT_DESCRIPTION:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001037 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001038 break;
1039 case LY_STMT_REFERENCE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001040 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->ref, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001041 break;
1042 case LY_STMT_ERROR_APP_TAG:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001043 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001044 break;
1045 case LY_STMT_ERROR_MESSAGE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001046 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001047 break;
1048 case LY_STMT_MODIFIER:
1049 PARSER_CHECK_STMTVER2_RET(ctx, "modifier", "pattern");
Michal Vasko7f45cf22020-10-01 12:49:44 +02001050 LY_CHECK_RET(lysp_stmt_type_pattern_modifier(ctx, child, &restr->arg.str, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001051 break;
1052 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001053 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_PATTERN, 0, &restr->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001054 break;
1055 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001056 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "pattern");
Radek Krejci335332a2019-09-05 13:03:35 +02001057 return LY_EVALID;
1058 }
1059 }
1060 return LY_SUCCESS;
1061}
1062
1063/**
1064 * @brief Parse the type statement.
1065 *
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001066 * @param[in] ctx parser context.
1067 * @param[in] stmt Source statement data from the parsed extension instance.
Radek Krejci335332a2019-09-05 13:03:35 +02001068 * @param[in,out] type Type to wrote to.
1069 *
1070 * @return LY_ERR values.
1071 */
1072static LY_ERR
1073lysp_stmt_type(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_type *type)
1074{
1075 struct lysp_type *nest_type;
Radek Krejcib1247842020-07-02 16:22:38 +02001076 const char *str_path = NULL;
Michal Vasko004d3152020-06-11 19:59:22 +02001077 LY_ERR ret;
Radek Krejci335332a2019-09-05 13:03:35 +02001078
1079 if (type->name) {
1080 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "type");
1081 return LY_EVALID;
1082 }
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001083
1084 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
Radek Krejci011e4aa2020-09-04 15:22:31 +02001085 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &type->name));
Michal Vasko8a67eff2021-12-07 14:04:47 +01001086 type->pmod = PARSER_CUR_PMOD(ctx);
Radek Krejci335332a2019-09-05 13:03:35 +02001087
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001088 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1089 switch (child->kw) {
Radek Krejci335332a2019-09-05 13:03:35 +02001090 case LY_STMT_BASE:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001091 LY_CHECK_RET(lysp_stmt_text_fields(ctx, child, &type->bases, Y_PREF_IDENTIF_ARG, &type->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001092 type->flags |= LYS_SET_BASE;
1093 break;
1094 case LY_STMT_BIT:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001095 LY_CHECK_RET(lysp_stmt_type_enum(ctx, child, &type->bits));
Radek Krejci335332a2019-09-05 13:03:35 +02001096 type->flags |= LYS_SET_BIT;
1097 break;
1098 case LY_STMT_ENUM:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001099 LY_CHECK_RET(lysp_stmt_type_enum(ctx, child, &type->enums));
Radek Krejci335332a2019-09-05 13:03:35 +02001100 type->flags |= LYS_SET_ENUM;
1101 break;
1102 case LY_STMT_FRACTION_DIGITS:
1103 LY_CHECK_RET(lysp_stmt_type_fracdigits(ctx, child, &type->fraction_digits, &type->exts));
1104 type->flags |= LYS_SET_FRDIGITS;
1105 break;
1106 case LY_STMT_LENGTH:
1107 if (type->length) {
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001108 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(child->kw));
Radek Krejci335332a2019-09-05 13:03:35 +02001109 return LY_EVALID;
1110 }
1111 type->length = calloc(1, sizeof *type->length);
Michal Vaskob36053d2020-03-26 15:49:30 +01001112 LY_CHECK_ERR_RET(!type->length, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +02001113
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001114 LY_CHECK_RET(lysp_stmt_restr(ctx, child, type->length));
Radek Krejci335332a2019-09-05 13:03:35 +02001115 type->flags |= LYS_SET_LENGTH;
1116 break;
1117 case LY_STMT_PATH:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001118 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &str_path, Y_STR_ARG, &type->exts));
Michal Vaskoed725d72021-06-23 12:03:45 +02001119 ret = ly_path_parse(PARSER_CTX(ctx), NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
Michal Vasko69730152020-10-09 16:30:07 +02001120 LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
Michal Vasko004d3152020-06-11 19:59:22 +02001121 lydict_remove(PARSER_CTX(ctx), str_path);
1122 LY_CHECK_RET(ret);
Radek Krejci335332a2019-09-05 13:03:35 +02001123 type->flags |= LYS_SET_PATH;
1124 break;
1125 case LY_STMT_PATTERN:
1126 LY_CHECK_RET(lysp_stmt_type_pattern(ctx, child, &type->patterns));
1127 type->flags |= LYS_SET_PATTERN;
1128 break;
1129 case LY_STMT_RANGE:
1130 if (type->range) {
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001131 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(child->kw));
Radek Krejci335332a2019-09-05 13:03:35 +02001132 return LY_EVALID;
1133 }
1134 type->range = calloc(1, sizeof *type->range);
Michal Vaskob36053d2020-03-26 15:49:30 +01001135 LY_CHECK_ERR_RET(!type->range, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +02001136
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001137 LY_CHECK_RET(lysp_stmt_restr(ctx, child, type->range));
Radek Krejci335332a2019-09-05 13:03:35 +02001138 type->flags |= LYS_SET_RANGE;
1139 break;
1140 case LY_STMT_REQUIRE_INSTANCE:
1141 LY_CHECK_RET(lysp_stmt_type_reqinstance(ctx, child, &type->require_instance, &type->flags, &type->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001142 /* LYS_SET_REQINST checked and set inside lysp_stmt_type_reqinstance() */
Radek Krejci335332a2019-09-05 13:03:35 +02001143 break;
1144 case LY_STMT_TYPE:
Michal Vaskob36053d2020-03-26 15:49:30 +01001145 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), type->types, nest_type, LY_EMEM);
Radek Krejci335332a2019-09-05 13:03:35 +02001146 LY_CHECK_RET(lysp_stmt_type(ctx, child, nest_type));
1147 type->flags |= LYS_SET_TYPE;
1148 break;
1149 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001150 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPE, 0, &type->exts));
Radek Krejci335332a2019-09-05 13:03:35 +02001151 break;
1152 default:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001153 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "type");
Radek Krejci335332a2019-09-05 13:03:35 +02001154 return LY_EVALID;
1155 }
1156 }
1157 return LY_SUCCESS;
1158}
1159
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001160/**
1161 * @brief Parse the leaf statement.
1162 *
1163 * @param[in] ctx parser context.
1164 * @param[in] stmt Source statement data from the parsed extension instance.
1165 * @param[in] parent Parent node to connect to (not into).
1166 * @param[in,out] siblings Siblings to add to.
1167 *
1168 * @return LY_ERR values.
1169 */
1170static LY_ERR
1171lysp_stmt_leaf(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
1172{
1173 struct lysp_node_leaf *leaf;
1174
1175 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1176
1177 /* create new leaf structure */
1178 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, leaf, next, LY_EMEM);
1179 leaf->nodetype = LYS_LEAF;
1180 leaf->parent = parent;
1181
1182 /* get name */
1183 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &leaf->name));
1184
1185 /* parse substatements */
1186 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1187 switch (child->kw) {
1188 case LY_STMT_CONFIG:
1189 LY_CHECK_RET(lysp_stmt_config(ctx, child, &leaf->flags, &leaf->exts));
1190 break;
1191 case LY_STMT_DEFAULT:
1192 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->dflt.str, Y_STR_ARG, &leaf->exts));
Michal Vasko8a67eff2021-12-07 14:04:47 +01001193 leaf->dflt.mod = PARSER_CUR_PMOD(ctx);
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001194 break;
1195 case LY_STMT_DESCRIPTION:
1196 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->dsc, Y_STR_ARG, &leaf->exts));
1197 break;
1198 case LY_STMT_IF_FEATURE:
1199 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &leaf->iffeatures, Y_STR_ARG, &leaf->exts));
1200 break;
1201 case LY_STMT_MANDATORY:
1202 LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &leaf->flags, &leaf->exts));
1203 break;
1204 case LY_STMT_MUST:
1205 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &leaf->musts));
1206 break;
1207 case LY_STMT_REFERENCE:
1208 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->ref, Y_STR_ARG, &leaf->exts));
1209 break;
1210 case LY_STMT_STATUS:
1211 LY_CHECK_RET(lysp_stmt_status(ctx, child, &leaf->flags, &leaf->exts));
1212 break;
1213 case LY_STMT_TYPE:
1214 LY_CHECK_RET(lysp_stmt_type(ctx, child, &leaf->type));
1215 break;
1216 case LY_STMT_UNITS:
1217 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->units, Y_STR_ARG, &leaf->exts));
1218 break;
1219 case LY_STMT_WHEN:
1220 LY_CHECK_RET(lysp_stmt_when(ctx, child, &leaf->when));
1221 break;
1222 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001223 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF, 0, &leaf->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001224 break;
1225 default:
1226 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "leaf");
1227 return LY_EVALID;
1228 }
1229 }
1230
1231 /* mandatory substatements */
1232 if (!leaf->type.name) {
1233 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf");
1234 return LY_EVALID;
1235 }
1236
1237 return LY_SUCCESS;
1238}
1239
1240/**
1241 * @brief Parse the max-elements statement.
1242 *
1243 * @param[in] ctx parser context.
1244 * @param[in] stmt Source statement data from the parsed extension instance.
1245 * @param[in,out] max Value to write to.
1246 * @param[in,out] flags Flags to write to.
1247 * @param[in,out] exts Extension instances to add to.
1248 *
1249 * @return LY_ERR values.
1250 */
1251static LY_ERR
1252lysp_stmt_maxelements(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
1253 uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
1254{
1255 size_t arg_len;
1256 char *ptr;
Michal Vasko73d77ab2021-07-23 12:45:55 +02001257 unsigned long long int num;
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001258
1259 if (*flags & LYS_SET_MAX) {
1260 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "max-elements");
1261 return LY_EVALID;
1262 }
1263 *flags |= LYS_SET_MAX;
1264
1265 /* get value */
1266 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1267 arg_len = strlen(stmt->arg);
1268
1269 if (!arg_len || (stmt->arg[0] == '0') || ((stmt->arg[0] != 'u') && !isdigit(stmt->arg[0]))) {
1270 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "max-elements");
1271 return LY_EVALID;
1272 }
1273
1274 if ((arg_len != ly_strlen_const("unbounded")) || strncmp(stmt->arg, "unbounded", arg_len)) {
1275 errno = 0;
Michal Vasko73d77ab2021-07-23 12:45:55 +02001276 num = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001277 /* we have not parsed the whole argument */
1278 if ((size_t)(ptr - stmt->arg) != arg_len) {
1279 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "max-elements");
1280 return LY_EVALID;
1281 }
1282 if ((errno == ERANGE) || (num > UINT32_MAX)) {
1283 LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "max-elements");
1284 return LY_EVALID;
1285 }
1286
1287 *max = num;
1288 } else {
1289 /* unbounded */
1290 *max = 0;
1291 }
1292
1293 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1294 switch (child->kw) {
1295 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +01001296 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MAX_ELEMENTS, 0, exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001297 break;
1298 default:
1299 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "max-elements");
1300 return LY_EVALID;
1301 }
1302 }
1303
1304 return LY_SUCCESS;
1305}
1306
1307/**
1308 * @brief Parse the min-elements statement.
1309 *
1310 * @param[in] ctx parser context.
1311 * @param[in] stmt Source statement data from the parsed extension instance.
1312 * @param[in,out] min Value to write to.
1313 * @param[in,out] flags Flags to write to.
1314 * @param[in,out] exts Extension instances to add to.
1315 *
1316 * @return LY_ERR values.
1317 */
1318static LY_ERR
1319lysp_stmt_minelements(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
1320 uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts)
1321{
1322 size_t arg_len;
1323 char *ptr;
Michal Vasko73d77ab2021-07-23 12:45:55 +02001324 unsigned long long int num;
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001325
1326 if (*flags & LYS_SET_MIN) {
1327 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "min-elements");
1328 return LY_EVALID;
1329 }
1330 *flags |= LYS_SET_MIN;
1331
1332 /* get value */
1333 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1334 arg_len = strlen(stmt->arg);
1335
1336 if (!arg_len || !isdigit(stmt->arg[0]) || ((stmt->arg[0] == '0') && (arg_len > 1))) {
1337 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "min-elements");
1338 return LY_EVALID;
1339 }
1340
1341 errno = 0;
Michal Vasko73d77ab2021-07-23 12:45:55 +02001342 num = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001343 /* we have not parsed the whole argument */
1344 if ((size_t)(ptr - stmt->arg) != arg_len) {
1345 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "min-elements");
1346 return LY_EVALID;
1347 }
1348 if ((errno == ERANGE) || (num > UINT32_MAX)) {
1349 LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "min-elements");
1350 return LY_EVALID;
1351 }
1352 *min = num;
1353
1354 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1355 switch (child->kw) {
1356 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +01001357 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MIN_ELEMENTS, 0, exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001358 break;
1359 default:
1360 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "min-elements");
1361 return LY_EVALID;
1362 }
1363 }
1364
1365 return LY_SUCCESS;
1366}
1367
1368/**
1369 * @brief Parse the ordered-by statement.
1370 *
1371 * @param[in] ctx parser context.
1372 * @param[in] stmt Source statement data from the parsed extension instance.
1373 * @param[in,out] flags Flags to write to.
1374 * @param[in,out] exts Extension instances to add to.
1375 *
1376 * @return LY_ERR values.
1377 */
1378static LY_ERR
1379lysp_stmt_orderedby(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
1380{
1381 size_t arg_len;
1382
1383 if (*flags & LYS_ORDBY_MASK) {
1384 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "ordered-by");
1385 return LY_EVALID;
1386 }
1387
1388 /* get value */
1389 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1390 arg_len = strlen(stmt->arg);
1391 if ((arg_len == ly_strlen_const("system")) && !strncmp(stmt->arg, "system", arg_len)) {
1392 *flags |= LYS_MAND_TRUE;
1393 } else if ((arg_len == ly_strlen_const("user")) && !strncmp(stmt->arg, "user", arg_len)) {
1394 *flags |= LYS_MAND_FALSE;
1395 } else {
1396 LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "ordered-by");
1397 return LY_EVALID;
1398 }
1399
1400 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1401 switch (child->kw) {
1402 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejcifc596f92021-02-26 22:40:26 +01001403 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_ORDERED_BY, 0, exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001404 break;
1405 default:
1406 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "ordered-by");
1407 return LY_EVALID;
1408 }
1409 }
1410
1411 return LY_SUCCESS;
1412}
1413
1414/**
1415 * @brief Parse the leaf-list statement.
1416 *
1417 * @param[in] ctx parser context.
1418 * @param[in] stmt Source statement data from the parsed extension instance.
1419 * @param[in] parent Parent node to connect to (not into).
1420 * @param[in,out] siblings Siblings to add to.
1421 *
1422 * @return LY_ERR values.
1423 */
1424static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02001425lysp_stmt_leaflist(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1426 struct lysp_node **siblings)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001427{
1428 struct lysp_node_leaflist *llist;
1429
1430 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1431
1432 /* create new leaf-list structure */
1433 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, llist, next, LY_EMEM);
1434 llist->nodetype = LYS_LEAFLIST;
1435 llist->parent = parent;
1436
1437 /* get name */
1438 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &llist->name));
1439
1440 /* parse substatements */
1441 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1442 switch (child->kw) {
1443 case LY_STMT_CONFIG:
1444 LY_CHECK_RET(lysp_stmt_config(ctx, child, &llist->flags, &llist->exts));
1445 break;
1446 case LY_STMT_DEFAULT:
1447 PARSER_CHECK_STMTVER2_RET(ctx, "default", "leaf-list");
1448 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &llist->dflts, Y_STR_ARG, &llist->exts));
1449 break;
1450 case LY_STMT_DESCRIPTION:
1451 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->dsc, Y_STR_ARG, &llist->exts));
1452 break;
1453 case LY_STMT_IF_FEATURE:
1454 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &llist->iffeatures, Y_STR_ARG, &llist->exts));
1455 break;
1456 case LY_STMT_MAX_ELEMENTS:
1457 LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &llist->max, &llist->flags, &llist->exts));
1458 break;
1459 case LY_STMT_MIN_ELEMENTS:
1460 LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &llist->min, &llist->flags, &llist->exts));
1461 break;
1462 case LY_STMT_MUST:
1463 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &llist->musts));
1464 break;
1465 case LY_STMT_ORDERED_BY:
1466 LY_CHECK_RET(lysp_stmt_orderedby(ctx, child, &llist->flags, &llist->exts));
1467 break;
1468 case LY_STMT_REFERENCE:
1469 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->ref, Y_STR_ARG, &llist->exts));
1470 break;
1471 case LY_STMT_STATUS:
1472 LY_CHECK_RET(lysp_stmt_status(ctx, child, &llist->flags, &llist->exts));
1473 break;
1474 case LY_STMT_TYPE:
1475 LY_CHECK_RET(lysp_stmt_type(ctx, child, &llist->type));
1476 break;
1477 case LY_STMT_UNITS:
1478 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->units, Y_STR_ARG, &llist->exts));
1479 break;
1480 case LY_STMT_WHEN:
1481 LY_CHECK_RET(lysp_stmt_when(ctx, child, &llist->when));
1482 break;
1483 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001484 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF_LIST, 0, &llist->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001485 break;
1486 default:
1487 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "llist");
1488 return LY_EVALID;
1489 }
1490 }
1491
1492 /* mandatory substatements */
1493 if (!llist->type.name) {
1494 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf-list");
1495 return LY_EVALID;
1496 }
1497
1498 return LY_SUCCESS;
1499}
1500
1501/**
1502 * @brief Parse the refine statement.
1503 *
1504 * @param[in] ctx parser context.
1505 * @param[in] stmt Source statement data from the parsed extension instance.
1506 * @param[in,out] refines Refines to add to.
1507 *
1508 * @return LY_ERR values.
1509 */
1510static LY_ERR
1511lysp_stmt_refine(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_refine **refines)
1512{
1513 struct lysp_refine *rf;
1514
1515 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1516
1517 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *refines, rf, LY_EMEM);
1518
1519 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &rf->nodeid));
1520
1521 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1522 switch (child->kw) {
1523 case LY_STMT_CONFIG:
1524 LY_CHECK_RET(lysp_stmt_config(ctx, child, &rf->flags, &rf->exts));
1525 break;
1526 case LY_STMT_DEFAULT:
1527 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &rf->dflts, Y_STR_ARG, &rf->exts));
1528 break;
1529 case LY_STMT_DESCRIPTION:
1530 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->dsc, Y_STR_ARG, &rf->exts));
1531 break;
1532 case LY_STMT_IF_FEATURE:
1533 PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "refine");
1534 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &rf->iffeatures, Y_STR_ARG, &rf->exts));
1535 break;
1536 case LY_STMT_MAX_ELEMENTS:
1537 LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &rf->max, &rf->flags, &rf->exts));
1538 break;
1539 case LY_STMT_MIN_ELEMENTS:
1540 LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &rf->min, &rf->flags, &rf->exts));
1541 break;
1542 case LY_STMT_MUST:
1543 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &rf->musts));
1544 break;
1545 case LY_STMT_MANDATORY:
1546 LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &rf->flags, &rf->exts));
1547 break;
1548 case LY_STMT_REFERENCE:
1549 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->ref, Y_STR_ARG, &rf->exts));
1550 break;
1551 case LY_STMT_PRESENCE:
1552 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->presence, Y_STR_ARG, &rf->exts));
1553 break;
1554 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001555 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REFINE, 0, &rf->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001556 break;
1557 default:
1558 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "refine");
1559 return LY_EVALID;
1560 }
1561 }
1562
1563 return LY_SUCCESS;
1564}
1565
1566/**
1567 * @brief Parse the typedef statement.
1568 *
1569 * @param[in] ctx parser context.
1570 * @param[in] stmt Source statement data from the parsed extension instance.
1571 * @param[in] parent Parent node to connect to (not into).
1572 * @param[in,out] typedefs Typedefs to add to.
1573 *
1574 * @return LY_ERR values.
1575 */
1576static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02001577lysp_stmt_typedef(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1578 struct lysp_tpdf **typedefs)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001579{
1580 struct lysp_tpdf *tpdf;
1581
1582 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1583
1584 LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *typedefs, tpdf, LY_EMEM);
1585
1586 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &tpdf->name));
1587
1588 /* parse substatements */
1589 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1590 switch (child->kw) {
1591 case LY_STMT_DEFAULT:
1592 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->dflt.str, Y_STR_ARG, &tpdf->exts));
Michal Vasko8a67eff2021-12-07 14:04:47 +01001593 tpdf->dflt.mod = PARSER_CUR_PMOD(ctx);
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001594 break;
1595 case LY_STMT_DESCRIPTION:
1596 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->dsc, Y_STR_ARG, &tpdf->exts));
1597 break;
1598 case LY_STMT_REFERENCE:
1599 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->ref, Y_STR_ARG, &tpdf->exts));
1600 break;
1601 case LY_STMT_STATUS:
1602 LY_CHECK_RET(lysp_stmt_status(ctx, child, &tpdf->flags, &tpdf->exts));
1603 break;
1604 case LY_STMT_TYPE:
1605 LY_CHECK_RET(lysp_stmt_type(ctx, child, &tpdf->type));
1606 break;
1607 case LY_STMT_UNITS:
1608 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->units, Y_STR_ARG, &tpdf->exts));
1609 break;
1610 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001611 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPEDEF, 0, &tpdf->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001612 break;
1613 default:
1614 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "typedef");
1615 return LY_EVALID;
1616 }
1617 }
1618
1619 /* mandatory substatements */
1620 if (!tpdf->type.name) {
1621 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "typedef");
1622 return LY_EVALID;
1623 }
1624
1625 /* store data for collision check */
1626 if (parent && !(parent->nodetype & (LYS_GROUPING | LYS_RPC | LYS_ACTION | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF))) {
1627 LY_CHECK_RET(ly_set_add(&ctx->tpdfs_nodes, parent, 0, NULL));
1628 }
1629
1630 return LY_SUCCESS;
1631}
1632
1633/**
1634 * @brief Parse the input or output statement.
1635 *
1636 * @param[in] ctx parser context.
1637 * @param[in] stmt Source statement data from the parsed extension instance.
1638 * @param[in] parent Parent node to connect to (not into).
1639 * @param[in,out] inout_p Input/output pointer to write to.
1640 *
1641 * @return LY_ERR values.
1642 */
1643static LY_ERR
1644lysp_stmt_inout(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1645 struct lysp_node_action_inout *inout_p)
1646{
1647 if (inout_p->nodetype) {
1648 LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
1649 return LY_EVALID;
1650 }
1651
1652 /* initiate structure */
1653 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->kw == LY_STMT_INPUT ? "input" : "output", 0, &inout_p->name));
1654 inout_p->nodetype = stmt->kw == LY_STMT_INPUT ? LYS_INPUT : LYS_OUTPUT;
1655 inout_p->parent = parent;
1656
1657 /* parse substatements */
1658 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1659 switch (child->kw) {
1660 case LY_STMT_ANYDATA:
1661 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", ly_stmt2str(stmt->kw));
1662 /* fall through */
1663 case LY_STMT_ANYXML:
1664 LY_CHECK_RET(lysp_stmt_any(ctx, child, &inout_p->node, &inout_p->child));
1665 break;
1666 case LY_STMT_CHOICE:
1667 LY_CHECK_RET(lysp_stmt_choice(ctx, child, &inout_p->node, &inout_p->child));
1668 break;
1669 case LY_STMT_CONTAINER:
1670 LY_CHECK_RET(lysp_stmt_container(ctx, child, &inout_p->node, &inout_p->child));
1671 break;
1672 case LY_STMT_LEAF:
1673 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &inout_p->node, &inout_p->child));
1674 break;
1675 case LY_STMT_LEAF_LIST:
1676 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &inout_p->node, &inout_p->child));
1677 break;
1678 case LY_STMT_LIST:
1679 LY_CHECK_RET(lysp_stmt_list(ctx, child, &inout_p->node, &inout_p->child));
1680 break;
1681 case LY_STMT_USES:
1682 LY_CHECK_RET(lysp_stmt_uses(ctx, child, &inout_p->node, &inout_p->child));
1683 break;
1684 case LY_STMT_TYPEDEF:
1685 LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &inout_p->node, &inout_p->typedefs));
1686 break;
1687 case LY_STMT_MUST:
1688 PARSER_CHECK_STMTVER2_RET(ctx, "must", ly_stmt2str(stmt->kw));
1689 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &inout_p->musts));
1690 break;
1691 case LY_STMT_GROUPING:
1692 LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &inout_p->node, &inout_p->groupings));
1693 break;
1694 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001695 LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &inout_p->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001696 break;
1697 default:
1698 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
1699 return LY_EVALID;
1700 }
1701 }
1702
1703 if (!inout_p->child) {
1704 LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(stmt->kw));
1705 return LY_EVALID;
1706 }
1707
1708 return LY_SUCCESS;
1709}
1710
1711/**
1712 * @brief Parse the action statement.
1713 *
1714 * @param[in] ctx parser context.
1715 * @param[in] stmt Source statement data from the parsed extension instance.
1716 * @param[in] parent Parent node to connect to (not into).
1717 * @param[in,out] actions Actions to add to.
1718 *
1719 * @return LY_ERR values.
1720 */
1721static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02001722lysp_stmt_action(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1723 struct lysp_node_action **actions)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001724{
1725 struct lysp_node_action *act;
1726
1727 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1728
1729 LY_LIST_NEW_RET(PARSER_CTX(ctx), actions, act, next, LY_EMEM);
1730
1731 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &act->name));
1732 act->nodetype = parent ? LYS_ACTION : LYS_RPC;
1733 act->parent = parent;
1734
1735 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1736 switch (child->kw) {
1737 case LY_STMT_DESCRIPTION:
1738 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &act->dsc, Y_STR_ARG, &act->exts));
1739 break;
1740 case LY_STMT_IF_FEATURE:
1741 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &act->iffeatures, Y_STR_ARG, &act->exts));
1742 break;
1743 case LY_STMT_REFERENCE:
1744 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &act->ref, Y_STR_ARG, &act->exts));
1745 break;
1746 case LY_STMT_STATUS:
1747 LY_CHECK_RET(lysp_stmt_status(ctx, child, &act->flags, &act->exts));
1748 break;
1749
1750 case LY_STMT_INPUT:
1751 LY_CHECK_RET(lysp_stmt_inout(ctx, child, &act->node, &act->input));
1752 break;
1753 case LY_STMT_OUTPUT:
1754 LY_CHECK_RET(lysp_stmt_inout(ctx, child, &act->node, &act->output));
1755 break;
1756
1757 case LY_STMT_TYPEDEF:
1758 LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &act->node, &act->typedefs));
1759 break;
1760 case LY_STMT_GROUPING:
1761 LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &act->node, &act->groupings));
1762 break;
1763 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001764 LY_CHECK_RET(lysp_stmt_ext(ctx, child, parent ? LY_STMT_ACTION : LY_STMT_RPC, 0, &act->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001765 break;
1766 default:
1767 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), parent ? "action" : "rpc");
1768 return LY_EVALID;
1769 }
1770 }
1771
1772 /* always initialize inout, they are technically present (needed for later deviations/refines) */
1773 if (!act->input.nodetype) {
1774 act->input.nodetype = LYS_INPUT;
1775 act->input.parent = &act->node;
1776 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), "input", 0, &act->input.name));
1777 }
1778 if (!act->output.nodetype) {
1779 act->output.nodetype = LYS_OUTPUT;
1780 act->output.parent = &act->node;
1781 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), "output", 0, &act->output.name));
1782 }
1783
1784 return LY_SUCCESS;
1785}
1786
1787/**
1788 * @brief Parse the notification statement.
1789 *
1790 * @param[in] ctx parser context.
1791 * @param[in] stmt Source statement data from the parsed extension instance.
1792 * @param[in] parent Parent node to connect to (not into).
1793 * @param[in,out] notifs Notifications to add to.
1794 *
1795 * @return LY_ERR values.
1796 */
1797static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02001798lysp_stmt_notif(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1799 struct lysp_node_notif **notifs)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001800{
1801 struct lysp_node_notif *notif;
1802
1803 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1804
1805 LY_LIST_NEW_RET(PARSER_CTX(ctx), notifs, notif, next, LY_EMEM);
1806
1807 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &notif->name));
1808 notif->nodetype = LYS_NOTIF;
1809 notif->parent = parent;
1810
1811 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1812 switch (child->kw) {
1813 case LY_STMT_DESCRIPTION:
1814 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &notif->dsc, Y_STR_ARG, &notif->exts));
1815 break;
1816 case LY_STMT_IF_FEATURE:
1817 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &notif->iffeatures, Y_STR_ARG, &notif->exts));
1818 break;
1819 case LY_STMT_REFERENCE:
1820 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &notif->ref, Y_STR_ARG, &notif->exts));
1821 break;
1822 case LY_STMT_STATUS:
1823 LY_CHECK_RET(lysp_stmt_status(ctx, child, &notif->flags, &notif->exts));
1824 break;
1825
1826 case LY_STMT_ANYDATA:
1827 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "notification");
1828 /* fall through */
1829 case LY_STMT_ANYXML:
1830 LY_CHECK_RET(lysp_stmt_any(ctx, child, &notif->node, &notif->child));
1831 break;
1832 case LY_STMT_CHOICE:
1833 LY_CHECK_RET(lysp_stmt_case(ctx, child, &notif->node, &notif->child));
1834 break;
1835 case LY_STMT_CONTAINER:
1836 LY_CHECK_RET(lysp_stmt_container(ctx, child, &notif->node, &notif->child));
1837 break;
1838 case LY_STMT_LEAF:
1839 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &notif->node, &notif->child));
1840 break;
1841 case LY_STMT_LEAF_LIST:
1842 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &notif->node, &notif->child));
1843 break;
1844 case LY_STMT_LIST:
1845 LY_CHECK_RET(lysp_stmt_list(ctx, child, &notif->node, &notif->child));
1846 break;
1847 case LY_STMT_USES:
1848 LY_CHECK_RET(lysp_stmt_uses(ctx, child, &notif->node, &notif->child));
1849 break;
1850
1851 case LY_STMT_MUST:
1852 PARSER_CHECK_STMTVER2_RET(ctx, "must", "notification");
1853 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &notif->musts));
1854 break;
1855 case LY_STMT_TYPEDEF:
1856 LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &notif->node, &notif->typedefs));
1857 break;
1858 case LY_STMT_GROUPING:
1859 LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &notif->node, &notif->groupings));
1860 break;
1861 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001862 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_NOTIFICATION, 0, &notif->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001863 break;
1864 default:
1865 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "notification");
1866 return LY_EVALID;
1867 }
1868 }
1869
1870 return LY_SUCCESS;
1871}
1872
1873/**
1874 * @brief Parse the grouping statement.
1875 *
1876 * @param[in] ctx parser context.
1877 * @param[in] stmt Source statement data from the parsed extension instance.
1878 * @param[in] parent Parent node to connect to (not into).
1879 * @param[in,out] groupings Groupings to add to.
1880 *
1881 * @return LY_ERR values.
1882 */
1883static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02001884lysp_stmt_grouping(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1885 struct lysp_node_grp **groupings)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001886{
1887 struct lysp_node_grp *grp;
1888
1889 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1890
1891 LY_LIST_NEW_RET(PARSER_CTX(ctx), groupings, grp, next, LY_EMEM);
1892
1893 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &grp->name));
1894 grp->nodetype = LYS_GROUPING;
1895 grp->parent = parent;
1896
1897 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1898 switch (child->kw) {
1899 case LY_STMT_DESCRIPTION:
1900 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &grp->dsc, Y_STR_ARG, &grp->exts));
1901 break;
1902 case LY_STMT_REFERENCE:
1903 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &grp->ref, Y_STR_ARG, &grp->exts));
1904 break;
1905 case LY_STMT_STATUS:
1906 LY_CHECK_RET(lysp_stmt_status(ctx, child, &grp->flags, &grp->exts));
1907 break;
1908
1909 case LY_STMT_ANYDATA:
1910 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "grouping");
1911 /* fall through */
1912 case LY_STMT_ANYXML:
1913 LY_CHECK_RET(lysp_stmt_any(ctx, child, &grp->node, &grp->child));
1914 break;
1915 case LY_STMT_CHOICE:
1916 LY_CHECK_RET(lysp_stmt_choice(ctx, child, &grp->node, &grp->child));
1917 break;
1918 case LY_STMT_CONTAINER:
1919 LY_CHECK_RET(lysp_stmt_container(ctx, child, &grp->node, &grp->child));
1920 break;
1921 case LY_STMT_LEAF:
1922 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &grp->node, &grp->child));
1923 break;
1924 case LY_STMT_LEAF_LIST:
1925 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &grp->node, &grp->child));
1926 break;
1927 case LY_STMT_LIST:
1928 LY_CHECK_RET(lysp_stmt_list(ctx, child, &grp->node, &grp->child));
1929 break;
1930 case LY_STMT_USES:
1931 LY_CHECK_RET(lysp_stmt_uses(ctx, child, &grp->node, &grp->child));
1932 break;
1933
1934 case LY_STMT_TYPEDEF:
1935 LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &grp->node, &grp->typedefs));
1936 break;
1937 case LY_STMT_ACTION:
1938 PARSER_CHECK_STMTVER2_RET(ctx, "action", "grouping");
1939 LY_CHECK_RET(lysp_stmt_action(ctx, child, &grp->node, &grp->actions));
1940 break;
1941 case LY_STMT_GROUPING:
1942 LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &grp->node, &grp->groupings));
1943 break;
1944 case LY_STMT_NOTIFICATION:
1945 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "grouping");
1946 LY_CHECK_RET(lysp_stmt_notif(ctx, child, &grp->node, &grp->notifs));
1947 break;
1948 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01001949 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_GROUPING, 0, &grp->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001950 break;
1951 default:
1952 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "grouping");
1953 return LY_EVALID;
1954 }
1955 }
1956
1957 return LY_SUCCESS;
1958}
1959
1960/**
1961 * @brief Parse the augment statement.
1962 *
1963 * @param[in] ctx parser context.
1964 * @param[in] stmt Source statement data from the parsed extension instance.
1965 * @param[in] parent Parent node to connect to (not into).
1966 * @param[in,out] augments Augments to add to.
1967 *
1968 * @return LY_ERR values.
1969 */
1970static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02001971lysp_stmt_augment(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1972 struct lysp_node_augment **augments)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01001973{
1974 struct lysp_node_augment *aug;
1975
1976 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1977
1978 LY_LIST_NEW_RET(PARSER_CTX(ctx), augments, aug, next, LY_EMEM);
1979
1980 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &aug->nodeid));
1981 aug->nodetype = LYS_AUGMENT;
1982 aug->parent = parent;
1983
1984 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1985 switch (child->kw) {
1986 case LY_STMT_DESCRIPTION:
1987 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
1988 break;
1989 case LY_STMT_IF_FEATURE:
1990 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &aug->iffeatures, Y_STR_ARG, &aug->exts));
1991 break;
1992 case LY_STMT_REFERENCE:
1993 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &aug->ref, Y_STR_ARG, &aug->exts));
1994 break;
1995 case LY_STMT_STATUS:
1996 LY_CHECK_RET(lysp_stmt_status(ctx, child, &aug->flags, &aug->exts));
1997 break;
1998 case LY_STMT_WHEN:
1999 LY_CHECK_RET(lysp_stmt_when(ctx, child, &aug->when));
2000 break;
2001
2002 case LY_STMT_ANYDATA:
2003 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "augment");
2004 /* fall through */
2005 case LY_STMT_ANYXML:
2006 LY_CHECK_RET(lysp_stmt_any(ctx, child, &aug->node, &aug->child));
2007 break;
2008 case LY_STMT_CASE:
2009 LY_CHECK_RET(lysp_stmt_case(ctx, child, &aug->node, &aug->child));
2010 break;
2011 case LY_STMT_CHOICE:
2012 LY_CHECK_RET(lysp_stmt_choice(ctx, child, &aug->node, &aug->child));
2013 break;
2014 case LY_STMT_CONTAINER:
2015 LY_CHECK_RET(lysp_stmt_container(ctx, child, &aug->node, &aug->child));
2016 break;
2017 case LY_STMT_LEAF:
2018 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &aug->node, &aug->child));
2019 break;
2020 case LY_STMT_LEAF_LIST:
2021 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &aug->node, &aug->child));
2022 break;
2023 case LY_STMT_LIST:
2024 LY_CHECK_RET(lysp_stmt_list(ctx, child, &aug->node, &aug->child));
2025 break;
2026 case LY_STMT_USES:
2027 LY_CHECK_RET(lysp_stmt_uses(ctx, child, &aug->node, &aug->child));
2028 break;
2029
2030 case LY_STMT_ACTION:
2031 PARSER_CHECK_STMTVER2_RET(ctx, "action", "augment");
2032 LY_CHECK_RET(lysp_stmt_action(ctx, child, &aug->node, &aug->actions));
2033 break;
2034 case LY_STMT_NOTIFICATION:
2035 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "augment");
2036 LY_CHECK_RET(lysp_stmt_notif(ctx, child, &aug->node, &aug->notifs));
2037 break;
2038 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01002039 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_AUGMENT, 0, &aug->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002040 break;
2041 default:
2042 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "augment");
2043 return LY_EVALID;
2044 }
2045 }
2046
2047 return LY_SUCCESS;
2048}
2049
2050/**
2051 * @brief Parse the uses statement.
2052 *
2053 * @param[in] ctx parser context.
2054 * @param[in] stmt Source statement data from the parsed extension instance.
2055 * @param[in] parent Parent node to connect to (not into).
2056 * @param[in,out] siblings Siblings to add to.
2057 *
2058 * @return LY_ERR values.
2059 */
2060static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02002061lysp_stmt_uses(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2062 struct lysp_node **siblings)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002063{
2064 struct lysp_node_uses *uses;
2065
2066 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
2067
2068 /* create uses structure */
2069 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, uses, next, LY_EMEM);
2070
2071 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &uses->name));
2072 uses->nodetype = LYS_USES;
2073 uses->parent = parent;
2074
2075 /* parse substatements */
2076 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2077 switch (child->kw) {
2078 case LY_STMT_DESCRIPTION:
2079 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
2080 break;
2081 case LY_STMT_IF_FEATURE:
2082 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &uses->iffeatures, Y_STR_ARG, &uses->exts));
2083 break;
2084 case LY_STMT_REFERENCE:
2085 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &uses->ref, Y_STR_ARG, &uses->exts));
2086 break;
2087 case LY_STMT_STATUS:
2088 LY_CHECK_RET(lysp_stmt_status(ctx, child, &uses->flags, &uses->exts));
2089 break;
2090 case LY_STMT_WHEN:
2091 LY_CHECK_RET(lysp_stmt_when(ctx, child, &uses->when));
2092 break;
2093
2094 case LY_STMT_REFINE:
2095 LY_CHECK_RET(lysp_stmt_refine(ctx, child, &uses->refines));
2096 break;
2097 case LY_STMT_AUGMENT:
2098 LY_CHECK_RET(lysp_stmt_augment(ctx, child, &uses->node, &uses->augments));
2099 break;
2100 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01002101 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_USES, 0, &uses->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002102 break;
2103 default:
2104 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "uses");
2105 return LY_EVALID;
2106 }
2107 }
2108
2109 return LY_SUCCESS;
2110}
2111
2112/**
2113 * @brief Parse the case statement.
2114 *
2115 * @param[in] ctx parser context.
2116 * @param[in] stmt Source statement data from the parsed extension instance.
2117 * @param[in] parent Parent node to connect to (not into).
2118 * @param[in,out] siblings Siblings to add to.
2119 *
2120 * @return LY_ERR values.
2121 */
2122static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02002123lysp_stmt_case(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2124 struct lysp_node **siblings)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002125{
2126 struct lysp_node_case *cas;
2127
2128 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2129
2130 /* create new case structure */
2131 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, cas, next, LY_EMEM);
2132
2133 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &cas->name));
2134 cas->nodetype = LYS_CASE;
2135 cas->parent = parent;
2136
2137 /* parse substatements */
2138 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2139 switch (child->kw) {
2140 case LY_STMT_DESCRIPTION:
2141 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
2142 break;
2143 case LY_STMT_IF_FEATURE:
2144 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &cas->iffeatures, Y_STR_ARG, &cas->exts));
2145 break;
2146 case LY_STMT_REFERENCE:
2147 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cas->ref, Y_STR_ARG, &cas->exts));
2148 break;
2149 case LY_STMT_STATUS:
2150 LY_CHECK_RET(lysp_stmt_status(ctx, child, &cas->flags, &cas->exts));
2151 break;
2152 case LY_STMT_WHEN:
2153 LY_CHECK_RET(lysp_stmt_when(ctx, child, &cas->when));
2154 break;
2155
2156 case LY_STMT_ANYDATA:
2157 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "case");
2158 /* fall through */
2159 case LY_STMT_ANYXML:
2160 LY_CHECK_RET(lysp_stmt_any(ctx, child, &cas->node, &cas->child));
2161 break;
2162 case LY_STMT_CHOICE:
2163 LY_CHECK_RET(lysp_stmt_choice(ctx, child, &cas->node, &cas->child));
2164 break;
2165 case LY_STMT_CONTAINER:
2166 LY_CHECK_RET(lysp_stmt_container(ctx, child, &cas->node, &cas->child));
2167 break;
2168 case LY_STMT_LEAF:
2169 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &cas->node, &cas->child));
2170 break;
2171 case LY_STMT_LEAF_LIST:
2172 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &cas->node, &cas->child));
2173 break;
2174 case LY_STMT_LIST:
2175 LY_CHECK_RET(lysp_stmt_list(ctx, child, &cas->node, &cas->child));
2176 break;
2177 case LY_STMT_USES:
2178 LY_CHECK_RET(lysp_stmt_uses(ctx, child, &cas->node, &cas->child));
2179 break;
2180 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01002181 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CASE, 0, &cas->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002182 break;
2183 default:
2184 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "case");
2185 return LY_EVALID;
2186 }
2187 }
2188 return LY_SUCCESS;
2189}
2190
2191/**
2192 * @brief Parse the choice statement.
2193 *
2194 * @param[in] ctx parser context.
2195 * @param[in] stmt Source statement data from the parsed extension instance.
2196 * @param[in] parent Parent node to connect to (not into).
2197 * @param[in,out] siblings Siblings to add to.
2198 *
2199 * @return LY_ERR values.
2200 */
2201static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02002202lysp_stmt_choice(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2203 struct lysp_node **siblings)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002204{
2205 struct lysp_node_choice *choice;
2206
2207 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2208
2209 /* create new choice structure */
2210 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, choice, next, LY_EMEM);
2211
2212 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &choice->name));
2213 choice->nodetype = LYS_CHOICE;
2214 choice->parent = parent;
2215
2216 /* parse substatements */
2217 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2218 switch (child->kw) {
2219 case LY_STMT_CONFIG:
2220 LY_CHECK_RET(lysp_stmt_config(ctx, child, &choice->flags, &choice->exts));
2221 break;
2222 case LY_STMT_DESCRIPTION:
2223 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->dsc, Y_STR_ARG, &choice->exts));
2224 break;
2225 case LY_STMT_IF_FEATURE:
2226 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &choice->iffeatures, Y_STR_ARG, &choice->exts));
2227 break;
2228 case LY_STMT_MANDATORY:
2229 LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &choice->flags, &choice->exts));
2230 break;
2231 case LY_STMT_REFERENCE:
2232 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->ref, Y_STR_ARG, &choice->exts));
2233 break;
2234 case LY_STMT_STATUS:
2235 LY_CHECK_RET(lysp_stmt_status(ctx, child, &choice->flags, &choice->exts));
2236 break;
2237 case LY_STMT_WHEN:
2238 LY_CHECK_RET(lysp_stmt_when(ctx, child, &choice->when));
2239 break;
2240 case LY_STMT_DEFAULT:
2241 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->dflt.str, Y_PREF_IDENTIF_ARG, &choice->exts));
Michal Vasko8a67eff2021-12-07 14:04:47 +01002242 choice->dflt.mod = PARSER_CUR_PMOD(ctx);
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002243 break;
2244 case LY_STMT_ANYDATA:
2245 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "choice");
2246 /* fall through */
2247 case LY_STMT_ANYXML:
2248 LY_CHECK_RET(lysp_stmt_any(ctx, child, &choice->node, &choice->child));
2249 break;
2250 case LY_STMT_CASE:
2251 LY_CHECK_RET(lysp_stmt_case(ctx, child, &choice->node, &choice->child));
2252 break;
2253 case LY_STMT_CHOICE:
2254 PARSER_CHECK_STMTVER2_RET(ctx, "choice", "choice");
2255 LY_CHECK_RET(lysp_stmt_choice(ctx, child, &choice->node, &choice->child));
2256 break;
2257 case LY_STMT_CONTAINER:
2258 LY_CHECK_RET(lysp_stmt_container(ctx, child, &choice->node, &choice->child));
2259 break;
2260 case LY_STMT_LEAF:
2261 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &choice->node, &choice->child));
2262 break;
2263 case LY_STMT_LEAF_LIST:
2264 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &choice->node, &choice->child));
2265 break;
2266 case LY_STMT_LIST:
2267 LY_CHECK_RET(lysp_stmt_list(ctx, child, &choice->node, &choice->child));
2268 break;
2269 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01002270 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CHOICE, 0, &choice->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002271 break;
2272 default:
2273 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "choice");
2274 return LY_EVALID;
2275 }
2276 }
2277 return LY_SUCCESS;
2278}
2279
2280/**
2281 * @brief Parse the container statement.
2282 *
2283 * @param[in] ctx parser context.
2284 * @param[in] stmt Source statement data from the parsed extension instance.
2285 * @param[in] parent Parent node to connect to (not into).
2286 * @param[in,out] siblings Siblings to add to.
2287 *
2288 * @return LY_ERR values.
2289 */
2290static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02002291lysp_stmt_container(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2292 struct lysp_node **siblings)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002293{
2294 struct lysp_node_container *cont;
2295
2296 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2297
2298 /* create new container structure */
2299 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, cont, next, LY_EMEM);
2300
2301 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &cont->name));
2302 cont->nodetype = LYS_CONTAINER;
2303 cont->parent = parent;
2304
2305 /* parse substatements */
2306 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2307 switch (child->kw) {
2308 case LY_STMT_CONFIG:
2309 LY_CHECK_RET(lysp_stmt_config(ctx, child, &cont->flags, &cont->exts));
2310 break;
2311 case LY_STMT_DESCRIPTION:
2312 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->dsc, Y_STR_ARG, &cont->exts));
2313 break;
2314 case LY_STMT_IF_FEATURE:
2315 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &cont->iffeatures, Y_STR_ARG, &cont->exts));
2316 break;
2317 case LY_STMT_REFERENCE:
2318 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->ref, Y_STR_ARG, &cont->exts));
2319 break;
2320 case LY_STMT_STATUS:
2321 LY_CHECK_RET(lysp_stmt_status(ctx, child, &cont->flags, &cont->exts));
2322 break;
2323 case LY_STMT_WHEN:
2324 LY_CHECK_RET(lysp_stmt_when(ctx, child, &cont->when));
2325 break;
2326 case LY_STMT_PRESENCE:
2327 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->presence, Y_STR_ARG, &cont->exts));
2328 break;
2329 case LY_STMT_ANYDATA:
2330 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "container");
2331 /* fall through */
2332 case LY_STMT_ANYXML:
2333 LY_CHECK_RET(lysp_stmt_any(ctx, child, &cont->node, &cont->child));
2334 break;
2335 case LY_STMT_CHOICE:
2336 LY_CHECK_RET(lysp_stmt_choice(ctx, child, &cont->node, &cont->child));
2337 break;
2338 case LY_STMT_CONTAINER:
2339 LY_CHECK_RET(lysp_stmt_container(ctx, child, &cont->node, &cont->child));
2340 break;
2341 case LY_STMT_LEAF:
2342 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &cont->node, &cont->child));
2343 break;
2344 case LY_STMT_LEAF_LIST:
2345 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &cont->node, &cont->child));
2346 break;
2347 case LY_STMT_LIST:
2348 LY_CHECK_RET(lysp_stmt_list(ctx, child, &cont->node, &cont->child));
2349 break;
2350 case LY_STMT_USES:
2351 LY_CHECK_RET(lysp_stmt_uses(ctx, child, &cont->node, &cont->child));
2352 break;
2353
2354 case LY_STMT_TYPEDEF:
2355 LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &cont->node, &cont->typedefs));
2356 break;
2357 case LY_STMT_MUST:
2358 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &cont->musts));
2359 break;
2360 case LY_STMT_ACTION:
2361 PARSER_CHECK_STMTVER2_RET(ctx, "action", "container");
2362 LY_CHECK_RET(lysp_stmt_action(ctx, child, &cont->node, &cont->actions));
2363 break;
2364 case LY_STMT_GROUPING:
2365 LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &cont->node, &cont->groupings));
2366 break;
2367 case LY_STMT_NOTIFICATION:
2368 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "container");
2369 LY_CHECK_RET(lysp_stmt_notif(ctx, child, &cont->node, &cont->notifs));
2370 break;
2371 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01002372 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONTAINER, 0, &cont->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002373 break;
2374 default:
2375 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "container");
2376 return LY_EVALID;
2377 }
2378 }
2379
2380 return LY_SUCCESS;
2381}
2382
2383/**
2384 * @brief Parse the list statement.
2385 *
2386 * @param[in] ctx parser context.
2387 * @param[in] stmt Source statement data from the parsed extension instance.
2388 * @param[in] parent Parent node to connect to (not into).
2389 * @param[in,out] siblings Siblings to add to.
2390 *
2391 * @return LY_ERR values.
2392 */
2393static LY_ERR
Michal Vasko59892dd2022-05-13 11:02:30 +02002394lysp_stmt_list(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2395 struct lysp_node **siblings)
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002396{
2397 struct lysp_node_list *list;
2398
2399 LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2400
2401 /* create new list structure */
2402 LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, list, next, LY_EMEM);
2403
2404 LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &list->name));
2405 list->nodetype = LYS_LIST;
2406 list->parent = parent;
2407
2408 /* parse substatements */
2409 for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2410 switch (child->kw) {
2411 case LY_STMT_CONFIG:
2412 LY_CHECK_RET(lysp_stmt_config(ctx, child, &list->flags, &list->exts));
2413 break;
2414 case LY_STMT_DESCRIPTION:
2415 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->dsc, Y_STR_ARG, &list->exts));
2416 break;
2417 case LY_STMT_IF_FEATURE:
2418 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &list->iffeatures, Y_STR_ARG, &list->exts));
2419 break;
2420 case LY_STMT_REFERENCE:
2421 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->ref, Y_STR_ARG, &list->exts));
2422 break;
2423 case LY_STMT_STATUS:
2424 LY_CHECK_RET(lysp_stmt_status(ctx, child, &list->flags, &list->exts));
2425 break;
2426 case LY_STMT_WHEN:
2427 LY_CHECK_RET(lysp_stmt_when(ctx, child, &list->when));
2428 break;
2429 case LY_STMT_KEY:
2430 LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->key, Y_STR_ARG, &list->exts));
2431 break;
2432 case LY_STMT_MAX_ELEMENTS:
2433 LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &list->max, &list->flags, &list->exts));
2434 break;
2435 case LY_STMT_MIN_ELEMENTS:
2436 LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &list->min, &list->flags, &list->exts));
2437 break;
2438 case LY_STMT_ORDERED_BY:
2439 LY_CHECK_RET(lysp_stmt_orderedby(ctx, child, &list->flags, &list->exts));
2440 break;
2441 case LY_STMT_UNIQUE:
2442 LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &list->uniques, Y_STR_ARG, &list->exts));
2443 break;
2444
2445 case LY_STMT_ANYDATA:
2446 PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "list");
2447 /* fall through */
2448 case LY_STMT_ANYXML:
2449 LY_CHECK_RET(lysp_stmt_any(ctx, child, &list->node, &list->child));
2450 break;
2451 case LY_STMT_CHOICE:
2452 LY_CHECK_RET(lysp_stmt_choice(ctx, child, &list->node, &list->child));
2453 break;
2454 case LY_STMT_CONTAINER:
2455 LY_CHECK_RET(lysp_stmt_container(ctx, child, &list->node, &list->child));
2456 break;
2457 case LY_STMT_LEAF:
2458 LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &list->node, &list->child));
2459 break;
2460 case LY_STMT_LEAF_LIST:
2461 LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &list->node, &list->child));
2462 break;
2463 case LY_STMT_LIST:
2464 LY_CHECK_RET(lysp_stmt_list(ctx, child, &list->node, &list->child));
2465 break;
2466 case LY_STMT_USES:
2467 LY_CHECK_RET(lysp_stmt_uses(ctx, child, &list->node, &list->child));
2468 break;
2469
2470 case LY_STMT_TYPEDEF:
2471 LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &list->node, &list->typedefs));
2472 break;
2473 case LY_STMT_MUST:
2474 LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &list->musts));
2475 break;
2476 case LY_STMT_ACTION:
2477 PARSER_CHECK_STMTVER2_RET(ctx, "action", "list");
2478 LY_CHECK_RET(lysp_stmt_action(ctx, child, &list->node, &list->actions));
2479 break;
2480 case LY_STMT_GROUPING:
2481 LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &list->node, &list->groupings));
2482 break;
2483 case LY_STMT_NOTIFICATION:
2484 PARSER_CHECK_STMTVER2_RET(ctx, "notification", "list");
2485 LY_CHECK_RET(lysp_stmt_notif(ctx, child, &list->node, &list->notifs));
2486 break;
2487 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01002488 LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LIST, 0, &list->exts));
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002489 break;
2490 default:
2491 LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "list");
2492 return LY_EVALID;
2493 }
2494 }
2495
2496 return LY_SUCCESS;
2497}
2498
Radek Krejci335332a2019-09-05 13:03:35 +02002499LY_ERR
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002500lysp_stmt_parse(struct lysc_ctx *ctx, const struct lysp_stmt *stmt, void **result, struct lysp_ext_instance **exts)
Radek Krejci335332a2019-09-05 13:03:35 +02002501{
Radek Krejciad5963b2019-09-06 16:03:05 +02002502 LY_ERR ret = LY_SUCCESS;
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002503 uint16_t flags;
2504 struct lys_parser_ctx pctx = {0};
Michal Vasko8a67eff2021-12-07 14:04:47 +01002505 struct ly_set pmods = {0};
2506 void *objs;
Radek Krejci335332a2019-09-05 13:03:35 +02002507
Michal Vasko8a67eff2021-12-07 14:04:47 +01002508 /* local context */
Michal Vaskob36053d2020-03-26 15:49:30 +01002509 pctx.format = LYS_IN_YANG;
Michal Vasko8a67eff2021-12-07 14:04:47 +01002510 pctx.parsed_mods = &pmods;
2511 objs = &ctx->pmod;
2512 pmods.objs = objs;
2513 pmods.count = 1;
Radek Krejci2efc45b2020-12-22 16:25:44 +01002514
Radek Krejciddace2c2021-01-08 11:30:56 +01002515 LOG_LOCSET(NULL, NULL, ctx->path, NULL);
Radek Krejci335332a2019-09-05 13:03:35 +02002516
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002517 switch (stmt->kw) {
2518 case LY_STMT_ACTION:
2519 case LY_STMT_RPC:
2520 ret = lysp_stmt_action(&pctx, stmt, NULL, (struct lysp_node_action **)result);
2521 break;
2522 case LY_STMT_ANYDATA:
2523 case LY_STMT_ANYXML:
2524 ret = lysp_stmt_any(&pctx, stmt, NULL, (struct lysp_node **)result);
2525 break;
2526 case LY_STMT_AUGMENT:
2527 ret = lysp_stmt_augment(&pctx, stmt, NULL, (struct lysp_node_augment **)result);
2528 break;
2529 case LY_STMT_BASE:
2530 ret = lysp_stmt_text_fields(&pctx, stmt, (const char ***)result, Y_PREF_IDENTIF_ARG, exts);
2531 break;
2532 case LY_STMT_BIT:
2533 case LY_STMT_ENUM:
2534 ret = lysp_stmt_type_enum(&pctx, stmt, (struct lysp_type_enum **)result);
2535 break;
2536 case LY_STMT_CASE:
2537 ret = lysp_stmt_case(&pctx, stmt, NULL, (struct lysp_node **)result);
2538 break;
2539 case LY_STMT_CHOICE:
2540 ret = lysp_stmt_choice(&pctx, stmt, NULL, (struct lysp_node **)result);
2541 break;
2542 case LY_STMT_CONFIG:
Michal Vasko39ed7a22022-02-21 08:34:18 +01002543 assert(*result);
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002544 ret = lysp_stmt_config(&pctx, stmt, *(uint16_t **)result, exts);
2545 break;
2546 case LY_STMT_CONTACT:
2547 case LY_STMT_DESCRIPTION:
2548 case LY_STMT_ERROR_APP_TAG:
2549 case LY_STMT_ERROR_MESSAGE:
2550 case LY_STMT_KEY:
2551 case LY_STMT_NAMESPACE:
2552 case LY_STMT_ORGANIZATION:
2553 case LY_STMT_PRESENCE:
2554 case LY_STMT_REFERENCE:
2555 case LY_STMT_UNITS:
2556 ret = lysp_stmt_text_field(&pctx, stmt, 0, (const char **)result, Y_STR_ARG, exts);
2557 break;
2558 case LY_STMT_CONTAINER:
2559 ret = lysp_stmt_container(&pctx, stmt, NULL, (struct lysp_node **)result);
2560 break;
2561 case LY_STMT_DEFAULT:
2562 case LY_STMT_IF_FEATURE:
2563 case LY_STMT_UNIQUE:
2564 ret = lysp_stmt_qnames(&pctx, stmt, (struct lysp_qname **)result, Y_STR_ARG, exts);
2565 break;
2566 case LY_STMT_EXTENSION_INSTANCE:
Radek Krejci39b7fc22021-02-26 23:29:18 +01002567 ret = lysp_stmt_ext(&pctx, stmt, LY_STMT_EXTENSION_INSTANCE, 0, exts);
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002568 break;
2569 case LY_STMT_FRACTION_DIGITS:
2570 ret = lysp_stmt_type_fracdigits(&pctx, stmt, *(uint8_t **)result, exts);
2571 break;
2572 case LY_STMT_GROUPING:
2573 ret = lysp_stmt_grouping(&pctx, stmt, NULL, (struct lysp_node_grp **)result);
2574 break;
2575 case LY_STMT_INPUT:
2576 case LY_STMT_OUTPUT: {
2577 struct lysp_node_action_inout *inout;
2578
2579 *result = inout = calloc(1, sizeof *inout);
2580 LY_CHECK_ERR_RET(!inout, LOGMEM(ctx->ctx), LY_EMEM);
2581 ret = lysp_stmt_inout(&pctx, stmt, NULL, inout);
2582 break;
2583 }
2584 case LY_STMT_LEAF:
2585 ret = lysp_stmt_leaf(&pctx, stmt, NULL, (struct lysp_node **)result);
2586 break;
2587 case LY_STMT_LEAF_LIST:
2588 ret = lysp_stmt_leaflist(&pctx, stmt, NULL, (struct lysp_node **)result);
2589 break;
2590 case LY_STMT_LENGTH:
2591 case LY_STMT_MUST:
2592 case LY_STMT_RANGE:
2593 ret = lysp_stmt_restrs(&pctx, stmt, (struct lysp_restr **)result);
2594 break;
2595 case LY_STMT_LIST:
2596 ret = lysp_stmt_list(&pctx, stmt, NULL, (struct lysp_node **)result);
2597 break;
2598 case LY_STMT_MANDATORY:
2599 ret = lysp_stmt_mandatory(&pctx, stmt, *(uint16_t **)result, exts);
2600 break;
2601 case LY_STMT_MAX_ELEMENTS:
2602 flags = 0;
2603 ret = lysp_stmt_maxelements(&pctx, stmt, *(uint32_t **)result, &flags, exts);
2604 break;
2605 case LY_STMT_MIN_ELEMENTS:
2606 flags = 0;
2607 ret = lysp_stmt_minelements(&pctx, stmt, *(uint32_t **)result, &flags, exts);
2608 break;
2609 case LY_STMT_MODIFIER:
2610 ret = lysp_stmt_type_pattern_modifier(&pctx, stmt, (const char **)result, exts);
2611 break;
2612 case LY_STMT_NOTIFICATION:
2613 ret = lysp_stmt_notif(&pctx, stmt, NULL, (struct lysp_node_notif **)result);
2614 break;
2615 case LY_STMT_ORDERED_BY:
2616 ret = lysp_stmt_orderedby(&pctx, stmt, *(uint16_t **)result, exts);
2617 break;
2618 case LY_STMT_PATH: {
2619 const char *str_path = NULL;
2620
2621 LY_CHECK_RET(lysp_stmt_text_field(&pctx, stmt, 0, &str_path, Y_STR_ARG, exts));
Michal Vaskoed725d72021-06-23 12:03:45 +02002622 ret = ly_path_parse(ctx->ctx, NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002623 LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, (struct lyxp_expr **)result);
2624 lydict_remove(ctx->ctx, str_path);
2625 break;
2626 }
2627 case LY_STMT_PATTERN:
2628 ret = lysp_stmt_type_pattern(&pctx, stmt, (struct lysp_restr **)result);
2629 break;
2630 case LY_STMT_POSITION:
2631 case LY_STMT_VALUE:
2632 flags = 0;
2633 ret = lysp_stmt_type_enum_value_pos(&pctx, stmt, *(int64_t **)result, &flags, exts);
2634 break;
2635 case LY_STMT_PREFIX:
2636 ret = lysp_stmt_text_field(&pctx, stmt, 0, (const char **)result, Y_IDENTIF_ARG, exts);
2637 break;
2638 case LY_STMT_REFINE:
2639 ret = lysp_stmt_refine(&pctx, stmt, (struct lysp_refine **)result);
2640 break;
2641 case LY_STMT_REQUIRE_INSTANCE:
2642 flags = 0;
2643 ret = lysp_stmt_type_reqinstance(&pctx, stmt, *(uint8_t **)result, &flags, exts);
2644 break;
Michal Vasko69730152020-10-09 16:30:07 +02002645 case LY_STMT_STATUS:
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002646 ret = lysp_stmt_status(&pctx, stmt, *(uint16_t **)result, exts);
Radek Krejciad5963b2019-09-06 16:03:05 +02002647 break;
Radek Krejci335332a2019-09-05 13:03:35 +02002648 case LY_STMT_TYPE: {
2649 struct lysp_type *type;
Radek Krejci335332a2019-09-05 13:03:35 +02002650
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002651 *result = type = calloc(1, sizeof *type);
2652 LY_CHECK_ERR_RET(!type, LOGMEM(ctx->ctx), LY_EMEM);
2653 ret = lysp_stmt_type(&pctx, stmt, type);
Radek Krejci335332a2019-09-05 13:03:35 +02002654 break;
Radek Krejci0f969882020-08-21 16:56:47 +02002655 }
Radek Krejci76c8c4e2021-02-17 10:16:48 +01002656 case LY_STMT_TYPEDEF:
2657 ret = lysp_stmt_typedef(&pctx, stmt, NULL, (struct lysp_tpdf **)result);
2658 break;
2659 case LY_STMT_USES:
2660 ret = lysp_stmt_uses(&pctx, stmt, NULL, (struct lysp_node **)result);
2661 break;
2662 case LY_STMT_WHEN:
2663 ret = lysp_stmt_when(&pctx, stmt, (struct lysp_when **)result);
2664 break;
Radek Krejci335332a2019-09-05 13:03:35 +02002665 default:
2666 LOGINT(ctx->ctx);
2667 return LY_EINT;
2668 }
2669
Radek Krejciddace2c2021-01-08 11:30:56 +01002670 LOG_LOCBACK(0, 0, 1, 0);
Radek Krejciad5963b2019-09-06 16:03:05 +02002671 return ret;
Radek Krejci335332a2019-09-05 13:03:35 +02002672}
Michal Vasko59892dd2022-05-13 11:02:30 +02002673
2674void
2675lys_parser_fill_filepath(struct ly_ctx *ctx, struct ly_in *in, const char **filepath)
2676{
2677 char path[PATH_MAX];
2678
2679#ifndef __APPLE__
2680 char proc_path[32];
2681 int len;
2682#endif
2683
2684 LY_CHECK_ARG_RET(NULL, ctx, in, filepath, );
2685 if (*filepath) {
2686 /* filepath already set */
2687 return;
2688 }
2689
2690 switch (in->type) {
2691 case LY_IN_FILEPATH:
2692 if (realpath(in->method.fpath.filepath, path) != NULL) {
2693 lydict_insert(ctx, path, 0, filepath);
2694 } else {
2695 lydict_insert(ctx, in->method.fpath.filepath, 0, filepath);
2696 }
2697
2698 break;
2699 case LY_IN_FD:
2700#ifdef __APPLE__
2701 if (fcntl(in->method.fd, F_GETPATH, path) != -1) {
2702 lydict_insert(ctx, path, 0, filepath);
2703 }
2704#elif defined _WIN32
2705 HANDLE h = _get_osfhandle(in->method.fd);
2706 FILE_NAME_INFO info;
2707 if (GetFileInformationByHandleEx(h, FileNameInfo, &info, sizeof info)) {
2708 char *buf = calloc(info.FileNameLength + 1 /* trailing NULL */, MB_CUR_MAX);
2709 len = wcstombs(buf, info.FileName, info.FileNameLength * MB_CUR_MAX);
2710 lydict_insert(ctx, buf, len, filepath);
2711 }
2712#else
2713 /* get URI if there is /proc */
2714 sprintf(proc_path, "/proc/self/fd/%d", in->method.fd);
2715 if ((len = readlink(proc_path, path, PATH_MAX - 1)) > 0) {
2716 lydict_insert(ctx, path, len, filepath);
2717 }
2718#endif
2719 break;
2720 case LY_IN_MEMORY:
2721 case LY_IN_FILE:
2722 /* nothing to do */
2723 break;
2724 default:
2725 LOGINT(ctx);
2726 break;
2727 }
2728}