Coverage Report

Created: 2025-08-03 06:36

/src/libyang/src/parser_stmt.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file parser_stmt.c
3
 * @author Radek Krejčí <rkrejci@cesnet.cz>
4
 * @brief Parser of the extension substatements.
5
 *
6
 * Copyright (c) 2019 CESNET, z.s.p.o.
7
 *
8
 * This source code is licensed under BSD 3-Clause License (the "License").
9
 * You may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     https://opensource.org/licenses/BSD-3-Clause
13
 */
14
15
#include <assert.h>
16
#include <ctype.h>
17
#include <errno.h>
18
#include <stdint.h>
19
#include <stdlib.h>
20
#include <string.h>
21
22
#include "common.h"
23
#include "dict.h"
24
#include "log.h"
25
#include "parser_schema.h"
26
#include "path.h"
27
#include "schema_compile.h"
28
#include "set.h"
29
#include "tree.h"
30
#include "tree_edit.h"
31
#include "tree_schema.h"
32
#include "tree_schema_internal.h"
33
34
static LY_ERR lysp_stmt_container(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
35
        struct lysp_node **siblings);
36
static LY_ERR lysp_stmt_choice(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
37
        struct lysp_node **siblings);
38
static LY_ERR lysp_stmt_case(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
39
        struct lysp_node **siblings);
40
static LY_ERR lysp_stmt_uses(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
41
        struct lysp_node **siblings);
42
static LY_ERR lysp_stmt_grouping(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
43
        struct lysp_node_grp **groupings);
44
static LY_ERR lysp_stmt_list(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
45
        struct lysp_node **siblings);
46
47
static LY_ERR
48
lysp_stmt_validate_value(struct lys_parser_ctx *ctx, enum yang_arg val_type, const char *val)
49
0
{
50
0
    uint8_t prefix = 0;
51
0
    ly_bool first = 1;
52
0
    uint32_t c;
53
0
    size_t utf8_char_len;
54
55
0
    while (*val) {
56
0
        LY_CHECK_ERR_RET(ly_getutf8(&val, &c, &utf8_char_len),
57
0
                LOGVAL_PARSER(ctx, LY_VCODE_INCHAR, (val)[-utf8_char_len]), LY_EVALID);
58
59
0
        switch (val_type) {
60
0
        case Y_IDENTIF_ARG:
61
0
            LY_CHECK_RET(lysp_check_identifierchar(ctx, c, first, NULL));
62
0
            break;
63
0
        case Y_PREF_IDENTIF_ARG:
64
0
            LY_CHECK_RET(lysp_check_identifierchar(ctx, c, first, &prefix));
65
0
            break;
66
0
        case Y_STR_ARG:
67
0
        case Y_MAYBE_STR_ARG:
68
0
            LY_CHECK_RET(lysp_check_stringchar(ctx, c));
69
0
            break;
70
0
        }
71
0
        first = 0;
72
0
    }
73
74
0
    return LY_SUCCESS;
75
0
}
76
77
/**
78
 * @brief Parse extension instance.
79
 *
80
 * @param[in] ctx parser context.
81
 * @param[in] stmt Source statement data from the parsed extension instance.
82
 * @param[in] insubstmt The statement this extension instance is a substatement of.
83
 * @param[in] insubstmt_index Index of the keyword instance this extension instance is a substatement of.
84
 * @param[in,out] exts Extension instances to add to.
85
 *
86
 * @return LY_ERR values.
87
 */
88
static LY_ERR
89
lysp_stmt_ext(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, enum ly_stmt insubstmt,
90
        LY_ARRAY_COUNT_TYPE insubstmt_index, struct lysp_ext_instance **exts)
91
0
{
92
0
    struct lysp_ext_instance *e;
93
94
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *exts, e, LY_EMEM);
95
96
    /* store name and insubstmt info */
97
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->stmt, 0, &e->name));
98
0
    e->parent_stmt = insubstmt;
99
0
    e->parent_stmt_index = insubstmt_index;
100
0
    e->parsed = NULL;
101
    /* TODO (duplicate) e->child = stmt->child; */
102
103
    /* get optional argument */
104
0
    if (stmt->arg) {
105
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &e->argument));
106
0
    }
107
108
0
    return LY_SUCCESS;
109
0
}
110
111
/**
112
 * @brief Parse a generic text field without specific constraints. Those are contact, organization,
113
 * description, etc...
114
 *
115
 * @param[in] ctx parser context.
116
 * @param[in] stmt Source statement data from the parsed extension instance.
117
 * @param[in] substmt_index Index of this substatement.
118
 * @param[in,out] value Place to store the parsed value.
119
 * @param[in] arg Type of the YANG keyword argument (of the value).
120
 * @param[in,out] exts Extension instances to add to.
121
 *
122
 * @return LY_ERR values.
123
 */
124
static LY_ERR
125
lysp_stmt_text_field(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint32_t substmt_index,
126
        const char **value, enum yang_arg arg, struct lysp_ext_instance **exts)
127
0
{
128
0
    if (*value) {
129
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
130
0
        return LY_EVALID;
131
0
    }
132
133
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
134
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, value));
135
136
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
137
0
        switch (child->kw) {
138
0
        case LY_STMT_EXTENSION_INSTANCE:
139
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, substmt_index, exts));
140
0
            break;
141
0
        default:
142
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
143
0
            return LY_EVALID;
144
0
        }
145
0
    }
146
0
    return LY_SUCCESS;
147
0
}
148
149
/**
150
 * @brief Parse a qname that can have more instances such as if-feature.
151
 *
152
 * @param[in] ctx parser context.
153
 * @param[in] stmt Source statement data from the parsed extension instance.
154
 * @param[in,out] qnames Parsed qnames to add to.
155
 * @param[in] arg Type of the expected argument.
156
 * @param[in,out] exts Extension instances to add to.
157
 *
158
 * @return LY_ERR values.
159
 */
160
static LY_ERR
161
lysp_stmt_qnames(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
162
        struct lysp_qname **qnames, enum yang_arg arg, struct lysp_ext_instance **exts)
163
0
{
164
0
    struct lysp_qname *item;
165
166
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
167
168
    /* allocate new pointer */
169
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *qnames, item, LY_EMEM);
170
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &item->str));
171
0
    item->mod = ctx->parsed_mod;
172
173
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
174
0
        switch (child->kw) {
175
0
        case LY_STMT_EXTENSION_INSTANCE:
176
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*qnames) - 1, exts));
177
0
            break;
178
0
        default:
179
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
180
0
            return LY_EVALID;
181
0
        }
182
0
    }
183
0
    return LY_SUCCESS;
184
0
}
185
186
/**
187
 * @brief Parse a generic text field that can have more instances such as base.
188
 *
189
 * @param[in] ctx parser context.
190
 * @param[in] stmt Source statement data from the parsed extension instance.
191
 * @param[in,out] texts Parsed values to add to.
192
 * @param[in] arg Type of the expected argument.
193
 * @param[in,out] exts Extension instances to add to.
194
 *
195
 * @return LY_ERR values.
196
 */
197
static LY_ERR
198
lysp_stmt_text_fields(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
199
        const char ***texts, enum yang_arg arg, struct lysp_ext_instance **exts)
200
0
{
201
0
    const char **item;
202
203
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
204
205
    /* allocate new pointer */
206
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *texts, item, LY_EMEM);
207
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, item));
208
209
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
210
0
        switch (child->kw) {
211
0
        case LY_STMT_EXTENSION_INSTANCE:
212
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*texts) - 1, exts));
213
0
            break;
214
0
        default:
215
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
216
0
            return LY_EVALID;
217
0
        }
218
0
    }
219
0
    return LY_SUCCESS;
220
0
}
221
222
/**
223
 * @brief Parse the status statement.
224
 *
225
 * @param[in] ctx parser context.
226
 * @param[in] stmt Source statement data from the parsed extension instance.
227
 * @param[in,out] flags Flags to add to.
228
 * @param[in,out] exts Extension instances to add to.
229
 *
230
 * @return LY_ERR values.
231
 */
232
static LY_ERR
233
lysp_stmt_status(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
234
0
{
235
0
    size_t arg_len;
236
237
0
    if (*flags & LYS_STATUS_MASK) {
238
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "status");
239
0
        return LY_EVALID;
240
0
    }
241
242
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
243
0
    arg_len = strlen(stmt->arg);
244
0
    if ((arg_len == ly_strlen_const("current")) && !strncmp(stmt->arg, "current", arg_len)) {
245
0
        *flags |= LYS_STATUS_CURR;
246
0
    } else if ((arg_len == ly_strlen_const("deprecated")) && !strncmp(stmt->arg, "deprecated", arg_len)) {
247
0
        *flags |= LYS_STATUS_DEPRC;
248
0
    } else if ((arg_len == ly_strlen_const("obsolete")) && !strncmp(stmt->arg, "obsolete", arg_len)) {
249
0
        *flags |= LYS_STATUS_OBSLT;
250
0
    } else {
251
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "status");
252
0
        return LY_EVALID;
253
0
    }
254
255
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
256
0
        switch (child->kw) {
257
0
        case LY_STMT_EXTENSION_INSTANCE:
258
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_STATUS, 0, exts));
259
0
            break;
260
0
        default:
261
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "status");
262
0
            return LY_EVALID;
263
0
        }
264
0
    }
265
0
    return LY_SUCCESS;
266
0
}
267
268
/**
269
 * @brief Parse the when statement.
270
 *
271
 * @param[in] ctx parser context.
272
 * @param[in] stmt Source statement data from the parsed extension instance.
273
 * @param[in,out] when_p When pointer to parse to.
274
 *
275
 * @return LY_ERR values.
276
 */
277
static LY_ERR
278
lysp_stmt_when(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_when **when_p)
279
0
{
280
0
    LY_ERR ret = LY_SUCCESS;
281
0
    struct lysp_when *when;
282
283
0
    if (*when_p) {
284
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "when");
285
0
        return LY_EVALID;
286
0
    }
287
288
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
289
290
0
    when = calloc(1, sizeof *when);
291
0
    LY_CHECK_ERR_RET(!when, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
292
0
    *when_p = when;
293
294
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &when->cond));
295
296
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
297
0
        switch (child->kw) {
298
0
        case LY_STMT_DESCRIPTION:
299
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &when->dsc, Y_STR_ARG, &when->exts));
300
0
            break;
301
0
        case LY_STMT_REFERENCE:
302
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &when->ref, Y_STR_ARG, &when->exts));
303
0
            break;
304
0
        case LY_STMT_EXTENSION_INSTANCE:
305
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_WHEN, 0, &when->exts));
306
0
            break;
307
0
        default:
308
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "when");
309
0
            return LY_EVALID;
310
0
        }
311
0
    }
312
0
    return ret;
313
0
}
314
315
/**
316
 * @brief Parse the config statement.
317
 *
318
 * @param[in] ctx parser context.
319
 * @param[in] stmt Source statement data from the parsed extension instance.
320
 * @param[in,out] flags Flags to add to.
321
 * @param[in,out] exts Extension instances to add to.
322
 *
323
 * @return LY_ERR values.
324
 */
325
static LY_ERR
326
lysp_stmt_config(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
327
0
{
328
0
    size_t arg_len;
329
330
0
    if (*flags & LYS_CONFIG_MASK) {
331
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "config");
332
0
        return LY_EVALID;
333
0
    }
334
335
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
336
0
    arg_len = strlen(stmt->arg);
337
0
    if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
338
0
        *flags |= LYS_CONFIG_W;
339
0
    } else if ((arg_len == ly_strlen_const("false")) && !strncmp(stmt->arg, "false", arg_len)) {
340
0
        *flags |= LYS_CONFIG_R;
341
0
    } else {
342
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "config");
343
0
        return LY_EVALID;
344
0
    }
345
346
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
347
0
        switch (child->kw) {
348
0
        case LY_STMT_EXTENSION_INSTANCE:
349
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONFIG, 0, exts));
350
0
            break;
351
0
        default:
352
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "config");
353
0
            return LY_EVALID;
354
0
        }
355
0
    }
356
357
0
    return LY_SUCCESS;
358
0
}
359
360
/**
361
 * @brief Parse the mandatory statement.
362
 *
363
 * @param[in] ctx parser context.
364
 * @param[in] stmt Source statement data from the parsed extension instance.
365
 * @param[in,out] flags Flags to add to.
366
 * @param[in,out] exts Extension instances to add to.
367
 *
368
 * @return LY_ERR values.
369
 */
370
static LY_ERR
371
lysp_stmt_mandatory(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
372
0
{
373
0
    size_t arg_len;
374
375
0
    if (*flags & LYS_MAND_MASK) {
376
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "mandatory");
377
0
        return LY_EVALID;
378
0
    }
379
380
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
381
0
    arg_len = strlen(stmt->arg);
382
0
    if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
383
0
        *flags |= LYS_MAND_TRUE;
384
0
    } else if ((arg_len == ly_strlen_const("false")) && !strncmp(stmt->arg, "false", arg_len)) {
385
0
        *flags |= LYS_MAND_FALSE;
386
0
    } else {
387
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "mandatory");
388
0
        return LY_EVALID;
389
0
    }
390
391
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
392
0
        switch (child->kw) {
393
0
        case LY_STMT_EXTENSION_INSTANCE:
394
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MANDATORY, 0, exts));
395
0
            break;
396
0
        default:
397
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "mandatory");
398
0
            return LY_EVALID;
399
0
        }
400
0
    }
401
402
0
    return LY_SUCCESS;
403
0
}
404
405
/**
406
 * @brief Parse a restriction such as range or length.
407
 *
408
 * @param[in] ctx parser context.
409
 * @param[in] stmt Source statement data from the parsed extension instance.
410
 * @param[in,out] exts Extension instances to add to.
411
 *
412
 * @return LY_ERR values.
413
 */
414
static LY_ERR
415
lysp_stmt_restr(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr *restr)
416
0
{
417
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
418
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &restr->arg.str));
419
0
    restr->arg.mod = ctx->parsed_mod;
420
421
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
422
0
        switch (child->kw) {
423
0
        case LY_STMT_DESCRIPTION:
424
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
425
0
            break;
426
0
        case LY_STMT_REFERENCE:
427
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->ref, Y_STR_ARG, &restr->exts));
428
0
            break;
429
0
        case LY_STMT_ERROR_APP_TAG:
430
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
431
0
            break;
432
0
        case LY_STMT_ERROR_MESSAGE:
433
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
434
0
            break;
435
0
        case LY_STMT_EXTENSION_INSTANCE:
436
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &restr->exts));
437
0
            break;
438
0
        default:
439
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
440
0
            return LY_EVALID;
441
0
        }
442
0
    }
443
0
    return LY_SUCCESS;
444
0
}
445
446
/**
447
 * @brief Parse a restriction that can have more instances such as must.
448
 *
449
 * @param[in] ctx parser context.
450
 * @param[in] stmt Source statement data from the parsed extension instance.
451
 * @param[in,out] restrs Restrictions to add to.
452
 *
453
 * @return LY_ERR values.
454
 */
455
static LY_ERR
456
lysp_stmt_restrs(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr **restrs)
457
0
{
458
0
    struct lysp_restr *restr;
459
460
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *restrs, restr, LY_EMEM);
461
0
    return lysp_stmt_restr(ctx, stmt, restr);
462
0
}
463
464
/**
465
 * @brief Parse the anydata or anyxml statement.
466
 *
467
 * @param[in] ctx parser context.
468
 * @param[in] stmt Source statement data from the parsed extension instance.
469
 * @param[in,out] siblings Siblings to add to.
470
 *
471
 * @return LY_ERR values.
472
 */
473
static LY_ERR
474
lysp_stmt_any(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
475
0
{
476
0
    struct lysp_node_anydata *any;
477
478
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
479
480
    /* create new structure and insert into siblings */
481
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, any, next, LY_EMEM);
482
483
0
    any->nodetype = stmt->kw == LY_STMT_ANYDATA ? LYS_ANYDATA : LYS_ANYXML;
484
0
    any->parent = parent;
485
486
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &any->name));
487
488
    /* parse substatements */
489
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
490
0
        switch (child->kw) {
491
0
        case LY_STMT_CONFIG:
492
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &any->flags, &any->exts));
493
0
            break;
494
0
        case LY_STMT_DESCRIPTION:
495
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &any->dsc, Y_STR_ARG, &any->exts));
496
0
            break;
497
0
        case LY_STMT_IF_FEATURE:
498
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &any->iffeatures, Y_STR_ARG, &any->exts));
499
0
            break;
500
0
        case LY_STMT_MANDATORY:
501
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &any->flags, &any->exts));
502
0
            break;
503
0
        case LY_STMT_MUST:
504
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &any->musts));
505
0
            break;
506
0
        case LY_STMT_REFERENCE:
507
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &any->ref, Y_STR_ARG, &any->exts));
508
0
            break;
509
0
        case LY_STMT_STATUS:
510
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &any->flags, &any->exts));
511
0
            break;
512
0
        case LY_STMT_WHEN:
513
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &any->when));
514
0
            break;
515
0
        case LY_STMT_EXTENSION_INSTANCE:
516
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &any->exts));
517
0
            break;
518
0
        default:
519
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
520
0
                    (any->nodetype & LYS_ANYDATA) == LYS_ANYDATA ? ly_stmt2str(LY_STMT_ANYDATA) : ly_stmt2str(LY_STMT_ANYXML));
521
0
            return LY_EVALID;
522
0
        }
523
0
    }
524
525
0
    return LY_SUCCESS;
526
0
}
527
528
/**
529
 * @brief Parse the value or position statement. Substatement of type enum statement.
530
 *
531
 * @param[in] ctx parser context.
532
 * @param[in] stmt Source statement data from the parsed extension instance.
533
 * @param[in,out] value Value to write to.
534
 * @param[in,out] flags Flags to write to.
535
 * @param[in,out] exts Extension instances to add to.
536
 *
537
 * @return LY_ERR values.
538
 */
539
static LY_ERR
540
lysp_stmt_type_enum_value_pos(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, int64_t *value, uint16_t *flags,
541
        struct lysp_ext_instance **exts)
542
0
{
543
0
    size_t arg_len;
544
0
    char *ptr = NULL;
545
0
    long int num = 0;
546
0
    unsigned long int unum = 0;
547
548
0
    if (*flags & LYS_SET_VALUE) {
549
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
550
0
        return LY_EVALID;
551
0
    }
552
0
    *flags |= LYS_SET_VALUE;
553
554
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
555
556
0
    arg_len = strlen(stmt->arg);
557
0
    if (!arg_len || (stmt->arg[0] == '+') || ((stmt->arg[0] == '0') && (arg_len > 1)) ||
558
0
            ((stmt->kw == LY_STMT_POSITION) && !strncmp(stmt->arg, "-0", 2))) {
559
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
560
0
        goto error;
561
0
    }
562
563
0
    errno = 0;
564
0
    if (stmt->kw == LY_STMT_VALUE) {
565
0
        num = strtol(stmt->arg, &ptr, LY_BASE_DEC);
566
0
        if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
567
0
            LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
568
0
            goto error;
569
0
        }
570
0
    } else {
571
0
        unum = strtoul(stmt->arg, &ptr, LY_BASE_DEC);
572
0
        if (unum > UINT64_C(4294967295)) {
573
0
            LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
574
0
            goto error;
575
0
        }
576
0
    }
577
    /* we have not parsed the whole argument */
578
0
    if ((size_t)(ptr - stmt->arg) != arg_len) {
579
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
580
0
        goto error;
581
0
    }
582
0
    if (errno == ERANGE) {
583
0
        LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, ly_stmt2str(stmt->kw));
584
0
        goto error;
585
0
    }
586
0
    if (stmt->kw == LY_STMT_VALUE) {
587
0
        *value = num;
588
0
    } else {
589
0
        *value = unum;
590
0
    }
591
592
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
593
0
        switch (child->kw) {
594
0
        case LY_STMT_EXTENSION_INSTANCE:
595
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw == LY_STMT_VALUE ? LY_STMT_VALUE : LY_STMT_POSITION, 0, exts));
596
0
            break;
597
0
        default:
598
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
599
0
            return LY_EVALID;
600
0
        }
601
0
    }
602
0
    return LY_SUCCESS;
603
604
0
error:
605
0
    return LY_EVALID;
606
0
}
607
608
/**
609
 * @brief Parse the enum or bit statement. Substatement of type statement.
610
 *
611
 * @param[in] ctx parser context.
612
 * @param[in] stmt Source statement data from the parsed extension instance.
613
 * @param[in,out] enums Enums or bits to add to.
614
 *
615
 * @return LY_ERR values.
616
 */
617
static LY_ERR
618
lysp_stmt_type_enum(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_type_enum **enums)
619
0
{
620
0
    struct lysp_type_enum *enm;
621
622
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, stmt->kw == LY_STMT_ENUM ? Y_STR_ARG : Y_IDENTIF_ARG, stmt->arg));
623
624
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *enums, enm, LY_EMEM);
625
626
0
    if (stmt->kw == LY_STMT_ENUM) {
627
0
        LY_CHECK_RET(lysp_check_enum_name(ctx, stmt->arg, strlen(stmt->arg)));
628
0
    } /* else nothing specific for YANG_BIT */
629
630
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &enm->name));
631
0
    CHECK_UNIQUENESS(ctx, *enums, name, ly_stmt2str(stmt->kw), enm->name);
632
633
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
634
0
        switch (child->kw) {
635
0
        case LY_STMT_DESCRIPTION:
636
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
637
0
            break;
638
0
        case LY_STMT_IF_FEATURE:
639
0
            PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", ly_stmt2str(stmt->kw));
640
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &enm->iffeatures, Y_STR_ARG, &enm->exts));
641
0
            break;
642
0
        case LY_STMT_REFERENCE:
643
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &enm->ref, Y_STR_ARG, &enm->exts));
644
0
            break;
645
0
        case LY_STMT_STATUS:
646
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &enm->flags, &enm->exts));
647
0
            break;
648
0
        case LY_STMT_VALUE:
649
0
            LY_CHECK_ERR_RET(stmt->kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
650
0
                    ly_stmt2str(stmt->kw)), LY_EVALID);
651
0
            LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
652
0
            break;
653
0
        case LY_STMT_POSITION:
654
0
            LY_CHECK_ERR_RET(stmt->kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw),
655
0
                    ly_stmt2str(stmt->kw)), LY_EVALID);
656
0
            LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
657
0
            break;
658
0
        case LY_STMT_EXTENSION_INSTANCE:
659
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &enm->exts));
660
0
            break;
661
0
        default:
662
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
663
0
            return LY_EVALID;
664
0
        }
665
0
    }
666
0
    return LY_SUCCESS;
667
0
}
668
669
/**
670
 * @brief Parse the fraction-digits statement. Substatement of type statement.
671
 *
672
 * @param[in] ctx parser context.
673
 * @param[in] stmt Source statement data from the parsed extension instance.
674
 * @param[in,out] fracdig Value to write to.
675
 * @param[in,out] exts Extension instances to add to.
676
 *
677
 * @return LY_ERR values.
678
 */
679
static LY_ERR
680
lysp_stmt_type_fracdigits(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *fracdig, struct lysp_ext_instance **exts)
681
0
{
682
0
    char *ptr;
683
0
    size_t arg_len;
684
0
    unsigned long int num;
685
686
0
    if (*fracdig) {
687
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "fraction-digits");
688
0
        return LY_EVALID;
689
0
    }
690
691
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
692
0
    arg_len = strlen(stmt->arg);
693
0
    if (!arg_len || (stmt->arg[0] == '0') || !isdigit(stmt->arg[0])) {
694
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "fraction-digits");
695
0
        return LY_EVALID;
696
0
    }
697
698
0
    errno = 0;
699
0
    num = strtoul(stmt->arg, &ptr, LY_BASE_DEC);
700
    /* we have not parsed the whole argument */
701
0
    if ((size_t)(ptr - stmt->arg) != arg_len) {
702
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "fraction-digits");
703
0
        return LY_EVALID;
704
0
    }
705
0
    if ((errno == ERANGE) || (num > LY_TYPE_DEC64_FD_MAX)) {
706
0
        LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "fraction-digits");
707
0
        return LY_EVALID;
708
0
    }
709
0
    *fracdig = num;
710
711
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
712
0
        switch (child->kw) {
713
0
        case LY_STMT_EXTENSION_INSTANCE:
714
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_FRACTION_DIGITS, 0, exts));
715
0
            break;
716
0
        default:
717
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "fraction-digits");
718
0
            return LY_EVALID;
719
0
        }
720
0
    }
721
0
    return LY_SUCCESS;
722
0
}
723
724
/**
725
 * @brief Parse the require-instance statement. Substatement of type statement.
726
 *
727
 * @param[in] ctx parser context.
728
 * @param[in] stmt Source statement data from the parsed extension instance.
729
 * @param[in,out] reqinst Value to write to.
730
 * @param[in,out] flags Flags to write to.
731
 * @param[in,out] exts Extension instances to add to.
732
 *
733
 * @return LY_ERR values.
734
 */
735
static LY_ERR
736
lysp_stmt_type_reqinstance(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *reqinst, uint16_t *flags,
737
        struct lysp_ext_instance **exts)
738
0
{
739
0
    size_t arg_len;
740
741
0
    if (*flags & LYS_SET_REQINST) {
742
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "require-instance");
743
0
        return LY_EVALID;
744
0
    }
745
0
    *flags |= LYS_SET_REQINST;
746
747
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
748
0
    arg_len = strlen(stmt->arg);
749
0
    if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
750
0
        *reqinst = 1;
751
0
    } else if ((arg_len != ly_strlen_const("false")) || strncmp(stmt->arg, "false", arg_len)) {
752
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "require-instance");
753
0
        return LY_EVALID;
754
0
    }
755
756
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
757
0
        switch (child->kw) {
758
0
        case LY_STMT_EXTENSION_INSTANCE:
759
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REQUIRE_INSTANCE, 0, exts));
760
0
            break;
761
0
        default:
762
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "require-instance");
763
0
            return LY_EVALID;
764
0
        }
765
0
    }
766
0
    return LY_SUCCESS;
767
0
}
768
769
/**
770
 * @brief Parse the modifier statement. Substatement of type pattern statement.
771
 *
772
 * @param[in] ctx parser context.
773
 * @param[in] stmt Source statement data from the parsed extension instance.
774
 * @param[in,out] pat Value to write to.
775
 * @param[in,out] exts Extension instances to add to.
776
 *
777
 * @return LY_ERR values.
778
 */
779
static LY_ERR
780
lysp_stmt_type_pattern_modifier(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, const char **pat, struct lysp_ext_instance **exts)
781
0
{
782
0
    size_t arg_len;
783
0
    char *buf;
784
785
0
    if ((*pat)[0] == LYSP_RESTR_PATTERN_NACK) {
786
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "modifier");
787
0
        return LY_EVALID;
788
0
    }
789
790
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
791
0
    arg_len = strlen(stmt->arg);
792
0
    if ((arg_len != ly_strlen_const("invert-match")) || strncmp(stmt->arg, "invert-match", arg_len)) {
793
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "modifier");
794
0
        return LY_EVALID;
795
0
    }
796
797
    /* replace the value in the dictionary */
798
0
    buf = malloc(strlen(*pat) + 1);
799
0
    LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
800
0
    strcpy(buf, *pat);
801
0
    lydict_remove(PARSER_CTX(ctx), *pat);
802
803
0
    assert(buf[0] == LYSP_RESTR_PATTERN_ACK);
804
0
    buf[0] = LYSP_RESTR_PATTERN_NACK;
805
0
    LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, pat));
806
807
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
808
0
        switch (child->kw) {
809
0
        case LY_STMT_EXTENSION_INSTANCE:
810
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MODIFIER, 0, exts));
811
0
            break;
812
0
        default:
813
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "modifier");
814
0
            return LY_EVALID;
815
0
        }
816
0
    }
817
0
    return LY_SUCCESS;
818
0
}
819
820
/**
821
 * @brief Parse the pattern statement. Substatement of type statement.
822
 *
823
 * @param[in] ctx parser context.
824
 * @param[in] stmt Source statement data from the parsed extension instance.
825
 * @param[in,out] patterns Restrictions to add to.
826
 *
827
 * @return LY_ERR values.
828
 */
829
static LY_ERR
830
lysp_stmt_type_pattern(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr **patterns)
831
0
{
832
0
    char *buf;
833
0
    size_t arg_len;
834
0
    struct lysp_restr *restr;
835
836
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
837
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *patterns, restr, LY_EMEM);
838
0
    arg_len = strlen(stmt->arg);
839
840
    /* add special meaning first byte */
841
0
    buf = malloc(arg_len + 2);
842
0
    LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
843
0
    memmove(buf + 1, stmt->arg, arg_len);
844
0
    buf[0] = LYSP_RESTR_PATTERN_ACK; /* pattern's default regular-match flag */
845
0
    buf[arg_len + 1] = '\0'; /* terminating NULL byte */
846
0
    LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, &restr->arg.str));
847
0
    restr->arg.mod = ctx->parsed_mod;
848
849
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
850
0
        switch (child->kw) {
851
0
        case LY_STMT_DESCRIPTION:
852
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
853
0
            break;
854
0
        case LY_STMT_REFERENCE:
855
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->ref, Y_STR_ARG, &restr->exts));
856
0
            break;
857
0
        case LY_STMT_ERROR_APP_TAG:
858
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
859
0
            break;
860
0
        case LY_STMT_ERROR_MESSAGE:
861
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
862
0
            break;
863
0
        case LY_STMT_MODIFIER:
864
0
            PARSER_CHECK_STMTVER2_RET(ctx, "modifier", "pattern");
865
0
            LY_CHECK_RET(lysp_stmt_type_pattern_modifier(ctx, child, &restr->arg.str, &restr->exts));
866
0
            break;
867
0
        case LY_STMT_EXTENSION_INSTANCE:
868
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_PATTERN, 0, &restr->exts));
869
0
            break;
870
0
        default:
871
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "pattern");
872
0
            return LY_EVALID;
873
0
        }
874
0
    }
875
0
    return LY_SUCCESS;
876
0
}
877
878
/**
879
 * @brief Parse the type statement.
880
 *
881
 * @param[in] ctx parser context.
882
 * @param[in] stmt Source statement data from the parsed extension instance.
883
 * @param[in,out] type Type to wrote to.
884
 *
885
 * @return LY_ERR values.
886
 */
887
static LY_ERR
888
lysp_stmt_type(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_type *type)
889
0
{
890
0
    struct lysp_type *nest_type;
891
0
    const char *str_path = NULL;
892
0
    LY_ERR ret;
893
894
0
    if (type->name) {
895
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "type");
896
0
        return LY_EVALID;
897
0
    }
898
899
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
900
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &type->name));
901
0
    type->pmod = ctx->parsed_mod;
902
903
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
904
0
        switch (child->kw) {
905
0
        case LY_STMT_BASE:
906
0
            LY_CHECK_RET(lysp_stmt_text_fields(ctx, child, &type->bases, Y_PREF_IDENTIF_ARG, &type->exts));
907
0
            type->flags |= LYS_SET_BASE;
908
0
            break;
909
0
        case LY_STMT_BIT:
910
0
            LY_CHECK_RET(lysp_stmt_type_enum(ctx, child, &type->bits));
911
0
            type->flags |= LYS_SET_BIT;
912
0
            break;
913
0
        case LY_STMT_ENUM:
914
0
            LY_CHECK_RET(lysp_stmt_type_enum(ctx, child, &type->enums));
915
0
            type->flags |= LYS_SET_ENUM;
916
0
            break;
917
0
        case LY_STMT_FRACTION_DIGITS:
918
0
            LY_CHECK_RET(lysp_stmt_type_fracdigits(ctx, child, &type->fraction_digits, &type->exts));
919
0
            type->flags |= LYS_SET_FRDIGITS;
920
0
            break;
921
0
        case LY_STMT_LENGTH:
922
0
            if (type->length) {
923
0
                LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(child->kw));
924
0
                return LY_EVALID;
925
0
            }
926
0
            type->length = calloc(1, sizeof *type->length);
927
0
            LY_CHECK_ERR_RET(!type->length, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
928
929
0
            LY_CHECK_RET(lysp_stmt_restr(ctx, child, type->length));
930
0
            type->flags |= LYS_SET_LENGTH;
931
0
            break;
932
0
        case LY_STMT_PATH:
933
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &str_path, Y_STR_ARG, &type->exts));
934
0
            ret = ly_path_parse(PARSER_CTX(ctx), NULL, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
935
0
                    LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
936
0
            lydict_remove(PARSER_CTX(ctx), str_path);
937
0
            LY_CHECK_RET(ret);
938
0
            type->flags |= LYS_SET_PATH;
939
0
            break;
940
0
        case LY_STMT_PATTERN:
941
0
            LY_CHECK_RET(lysp_stmt_type_pattern(ctx, child, &type->patterns));
942
0
            type->flags |= LYS_SET_PATTERN;
943
0
            break;
944
0
        case LY_STMT_RANGE:
945
0
            if (type->range) {
946
0
                LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(child->kw));
947
0
                return LY_EVALID;
948
0
            }
949
0
            type->range = calloc(1, sizeof *type->range);
950
0
            LY_CHECK_ERR_RET(!type->range, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
951
952
0
            LY_CHECK_RET(lysp_stmt_restr(ctx, child, type->range));
953
0
            type->flags |= LYS_SET_RANGE;
954
0
            break;
955
0
        case LY_STMT_REQUIRE_INSTANCE:
956
0
            LY_CHECK_RET(lysp_stmt_type_reqinstance(ctx, child, &type->require_instance, &type->flags, &type->exts));
957
            /* LYS_SET_REQINST checked and set inside lysp_stmt_type_reqinstance() */
958
0
            break;
959
0
        case LY_STMT_TYPE:
960
0
            LY_ARRAY_NEW_RET(PARSER_CTX(ctx), type->types, nest_type, LY_EMEM);
961
0
            LY_CHECK_RET(lysp_stmt_type(ctx, child, nest_type));
962
0
            type->flags |= LYS_SET_TYPE;
963
0
            break;
964
0
        case LY_STMT_EXTENSION_INSTANCE:
965
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPE, 0, &type->exts));
966
0
            break;
967
0
        default:
968
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "type");
969
0
            return LY_EVALID;
970
0
        }
971
0
    }
972
0
    return LY_SUCCESS;
973
0
}
974
975
/**
976
 * @brief Parse the leaf statement.
977
 *
978
 * @param[in] ctx parser context.
979
 * @param[in] stmt Source statement data from the parsed extension instance.
980
 * @param[in] parent Parent node to connect to (not into).
981
 * @param[in,out] siblings Siblings to add to.
982
 *
983
 * @return LY_ERR values.
984
 */
985
static LY_ERR
986
lysp_stmt_leaf(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
987
0
{
988
0
    struct lysp_node_leaf *leaf;
989
990
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
991
992
    /* create new leaf structure */
993
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, leaf, next, LY_EMEM);
994
0
    leaf->nodetype = LYS_LEAF;
995
0
    leaf->parent = parent;
996
997
    /* get name */
998
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &leaf->name));
999
1000
    /* parse substatements */
1001
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1002
0
        switch (child->kw) {
1003
0
        case LY_STMT_CONFIG:
1004
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &leaf->flags, &leaf->exts));
1005
0
            break;
1006
0
        case LY_STMT_DEFAULT:
1007
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->dflt.str, Y_STR_ARG, &leaf->exts));
1008
0
            leaf->dflt.mod = ctx->parsed_mod;
1009
0
            break;
1010
0
        case LY_STMT_DESCRIPTION:
1011
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->dsc, Y_STR_ARG, &leaf->exts));
1012
0
            break;
1013
0
        case LY_STMT_IF_FEATURE:
1014
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &leaf->iffeatures, Y_STR_ARG, &leaf->exts));
1015
0
            break;
1016
0
        case LY_STMT_MANDATORY:
1017
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &leaf->flags, &leaf->exts));
1018
0
            break;
1019
0
        case LY_STMT_MUST:
1020
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &leaf->musts));
1021
0
            break;
1022
0
        case LY_STMT_REFERENCE:
1023
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->ref, Y_STR_ARG, &leaf->exts));
1024
0
            break;
1025
0
        case LY_STMT_STATUS:
1026
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &leaf->flags, &leaf->exts));
1027
0
            break;
1028
0
        case LY_STMT_TYPE:
1029
0
            LY_CHECK_RET(lysp_stmt_type(ctx, child, &leaf->type));
1030
0
            break;
1031
0
        case LY_STMT_UNITS:
1032
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->units, Y_STR_ARG, &leaf->exts));
1033
0
            break;
1034
0
        case LY_STMT_WHEN:
1035
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &leaf->when));
1036
0
            break;
1037
0
        case LY_STMT_EXTENSION_INSTANCE:
1038
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF, 0, &leaf->exts));
1039
0
            break;
1040
0
        default:
1041
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "leaf");
1042
0
            return LY_EVALID;
1043
0
        }
1044
0
    }
1045
1046
    /* mandatory substatements */
1047
0
    if (!leaf->type.name) {
1048
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf");
1049
0
        return LY_EVALID;
1050
0
    }
1051
1052
0
    return LY_SUCCESS;
1053
0
}
1054
1055
/**
1056
 * @brief Parse the max-elements statement.
1057
 *
1058
 * @param[in] ctx parser context.
1059
 * @param[in] stmt Source statement data from the parsed extension instance.
1060
 * @param[in,out] max Value to write to.
1061
 * @param[in,out] flags Flags to write to.
1062
 * @param[in,out] exts Extension instances to add to.
1063
 *
1064
 * @return LY_ERR values.
1065
 */
1066
static LY_ERR
1067
lysp_stmt_maxelements(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
1068
        uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
1069
0
{
1070
0
    size_t arg_len;
1071
0
    char *ptr;
1072
0
    unsigned long int num;
1073
1074
0
    if (*flags & LYS_SET_MAX) {
1075
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "max-elements");
1076
0
        return LY_EVALID;
1077
0
    }
1078
0
    *flags |= LYS_SET_MAX;
1079
1080
    /* get value */
1081
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1082
0
    arg_len = strlen(stmt->arg);
1083
1084
0
    if (!arg_len || (stmt->arg[0] == '0') || ((stmt->arg[0] != 'u') && !isdigit(stmt->arg[0]))) {
1085
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "max-elements");
1086
0
        return LY_EVALID;
1087
0
    }
1088
1089
0
    if ((arg_len != ly_strlen_const("unbounded")) || strncmp(stmt->arg, "unbounded", arg_len)) {
1090
0
        errno = 0;
1091
0
        num = strtoul(stmt->arg, &ptr, LY_BASE_DEC);
1092
        /* we have not parsed the whole argument */
1093
0
        if ((size_t)(ptr - stmt->arg) != arg_len) {
1094
0
            LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "max-elements");
1095
0
            return LY_EVALID;
1096
0
        }
1097
0
        if ((errno == ERANGE) || (num > UINT32_MAX)) {
1098
0
            LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "max-elements");
1099
0
            return LY_EVALID;
1100
0
        }
1101
1102
0
        *max = num;
1103
0
    } else {
1104
        /* unbounded */
1105
0
        *max = 0;
1106
0
    }
1107
1108
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1109
0
        switch (child->kw) {
1110
0
        case LY_STMT_EXTENSION_INSTANCE:
1111
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MAX_ELEMENTS, 0, exts));
1112
0
            break;
1113
0
        default:
1114
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "max-elements");
1115
0
            return LY_EVALID;
1116
0
        }
1117
0
    }
1118
1119
0
    return LY_SUCCESS;
1120
0
}
1121
1122
/**
1123
 * @brief Parse the min-elements statement.
1124
 *
1125
 * @param[in] ctx parser context.
1126
 * @param[in] stmt Source statement data from the parsed extension instance.
1127
 * @param[in,out] min Value to write to.
1128
 * @param[in,out] flags Flags to write to.
1129
 * @param[in,out] exts Extension instances to add to.
1130
 *
1131
 * @return LY_ERR values.
1132
 */
1133
static LY_ERR
1134
lysp_stmt_minelements(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt,
1135
        uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts)
1136
0
{
1137
0
    size_t arg_len;
1138
0
    char *ptr;
1139
0
    unsigned long int num;
1140
1141
0
    if (*flags & LYS_SET_MIN) {
1142
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "min-elements");
1143
0
        return LY_EVALID;
1144
0
    }
1145
0
    *flags |= LYS_SET_MIN;
1146
1147
    /* get value */
1148
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1149
0
    arg_len = strlen(stmt->arg);
1150
1151
0
    if (!arg_len || !isdigit(stmt->arg[0]) || ((stmt->arg[0] == '0') && (arg_len > 1))) {
1152
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "min-elements");
1153
0
        return LY_EVALID;
1154
0
    }
1155
1156
0
    errno = 0;
1157
0
    num = strtoul(stmt->arg, &ptr, LY_BASE_DEC);
1158
    /* we have not parsed the whole argument */
1159
0
    if ((size_t)(ptr - stmt->arg) != arg_len) {
1160
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "min-elements");
1161
0
        return LY_EVALID;
1162
0
    }
1163
0
    if ((errno == ERANGE) || (num > UINT32_MAX)) {
1164
0
        LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "min-elements");
1165
0
        return LY_EVALID;
1166
0
    }
1167
0
    *min = num;
1168
1169
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1170
0
        switch (child->kw) {
1171
0
        case LY_STMT_EXTENSION_INSTANCE:
1172
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MIN_ELEMENTS, 0, exts));
1173
0
            break;
1174
0
        default:
1175
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "min-elements");
1176
0
            return LY_EVALID;
1177
0
        }
1178
0
    }
1179
1180
0
    return LY_SUCCESS;
1181
0
}
1182
1183
/**
1184
 * @brief Parse the ordered-by statement.
1185
 *
1186
 * @param[in] ctx parser context.
1187
 * @param[in] stmt Source statement data from the parsed extension instance.
1188
 * @param[in,out] flags Flags to write to.
1189
 * @param[in,out] exts Extension instances to add to.
1190
 *
1191
 * @return LY_ERR values.
1192
 */
1193
static LY_ERR
1194
lysp_stmt_orderedby(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
1195
0
{
1196
0
    size_t arg_len;
1197
1198
0
    if (*flags & LYS_ORDBY_MASK) {
1199
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "ordered-by");
1200
0
        return LY_EVALID;
1201
0
    }
1202
1203
    /* get value */
1204
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1205
0
    arg_len = strlen(stmt->arg);
1206
0
    if ((arg_len == ly_strlen_const("system")) && !strncmp(stmt->arg, "system", arg_len)) {
1207
0
        *flags |= LYS_MAND_TRUE;
1208
0
    } else if ((arg_len == ly_strlen_const("user")) && !strncmp(stmt->arg, "user", arg_len)) {
1209
0
        *flags |= LYS_MAND_FALSE;
1210
0
    } else {
1211
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "ordered-by");
1212
0
        return LY_EVALID;
1213
0
    }
1214
1215
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1216
0
        switch (child->kw) {
1217
0
        case LY_STMT_EXTENSION_INSTANCE:
1218
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_ORDERED_BY, 0, exts));
1219
0
            break;
1220
0
        default:
1221
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "ordered-by");
1222
0
            return LY_EVALID;
1223
0
        }
1224
0
    }
1225
1226
0
    return LY_SUCCESS;
1227
0
}
1228
1229
/**
1230
 * @brief Parse the leaf-list statement.
1231
 *
1232
 * @param[in] ctx parser context.
1233
 * @param[in] stmt Source statement data from the parsed extension instance.
1234
 * @param[in] parent Parent node to connect to (not into).
1235
 * @param[in,out] siblings Siblings to add to.
1236
 *
1237
 * @return LY_ERR values.
1238
 */
1239
static LY_ERR
1240
lysp_stmt_leaflist(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
1241
0
{
1242
0
    struct lysp_node_leaflist *llist;
1243
1244
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1245
1246
    /* create new leaf-list structure */
1247
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, llist, next, LY_EMEM);
1248
0
    llist->nodetype = LYS_LEAFLIST;
1249
0
    llist->parent = parent;
1250
1251
    /* get name */
1252
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &llist->name));
1253
1254
    /* parse substatements */
1255
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1256
0
        switch (child->kw) {
1257
0
        case LY_STMT_CONFIG:
1258
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &llist->flags, &llist->exts));
1259
0
            break;
1260
0
        case LY_STMT_DEFAULT:
1261
0
            PARSER_CHECK_STMTVER2_RET(ctx, "default", "leaf-list");
1262
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &llist->dflts, Y_STR_ARG, &llist->exts));
1263
0
            break;
1264
0
        case LY_STMT_DESCRIPTION:
1265
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->dsc, Y_STR_ARG, &llist->exts));
1266
0
            break;
1267
0
        case LY_STMT_IF_FEATURE:
1268
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &llist->iffeatures, Y_STR_ARG, &llist->exts));
1269
0
            break;
1270
0
        case LY_STMT_MAX_ELEMENTS:
1271
0
            LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &llist->max, &llist->flags, &llist->exts));
1272
0
            break;
1273
0
        case LY_STMT_MIN_ELEMENTS:
1274
0
            LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &llist->min, &llist->flags, &llist->exts));
1275
0
            break;
1276
0
        case LY_STMT_MUST:
1277
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &llist->musts));
1278
0
            break;
1279
0
        case LY_STMT_ORDERED_BY:
1280
0
            LY_CHECK_RET(lysp_stmt_orderedby(ctx, child, &llist->flags, &llist->exts));
1281
0
            break;
1282
0
        case LY_STMT_REFERENCE:
1283
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->ref, Y_STR_ARG, &llist->exts));
1284
0
            break;
1285
0
        case LY_STMT_STATUS:
1286
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &llist->flags, &llist->exts));
1287
0
            break;
1288
0
        case LY_STMT_TYPE:
1289
0
            LY_CHECK_RET(lysp_stmt_type(ctx, child, &llist->type));
1290
0
            break;
1291
0
        case LY_STMT_UNITS:
1292
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->units, Y_STR_ARG, &llist->exts));
1293
0
            break;
1294
0
        case LY_STMT_WHEN:
1295
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &llist->when));
1296
0
            break;
1297
0
        case LY_STMT_EXTENSION_INSTANCE:
1298
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF_LIST, 0, &llist->exts));
1299
0
            break;
1300
0
        default:
1301
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "llist");
1302
0
            return LY_EVALID;
1303
0
        }
1304
0
    }
1305
1306
    /* mandatory substatements */
1307
0
    if (!llist->type.name) {
1308
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf-list");
1309
0
        return LY_EVALID;
1310
0
    }
1311
1312
0
    return LY_SUCCESS;
1313
0
}
1314
1315
/**
1316
 * @brief Parse the refine statement.
1317
 *
1318
 * @param[in] ctx parser context.
1319
 * @param[in] stmt Source statement data from the parsed extension instance.
1320
 * @param[in,out] refines Refines to add to.
1321
 *
1322
 * @return LY_ERR values.
1323
 */
1324
static LY_ERR
1325
lysp_stmt_refine(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_refine **refines)
1326
0
{
1327
0
    struct lysp_refine *rf;
1328
1329
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1330
1331
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *refines, rf, LY_EMEM);
1332
1333
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &rf->nodeid));
1334
1335
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1336
0
        switch (child->kw) {
1337
0
        case LY_STMT_CONFIG:
1338
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &rf->flags, &rf->exts));
1339
0
            break;
1340
0
        case LY_STMT_DEFAULT:
1341
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &rf->dflts, Y_STR_ARG, &rf->exts));
1342
0
            break;
1343
0
        case LY_STMT_DESCRIPTION:
1344
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->dsc, Y_STR_ARG, &rf->exts));
1345
0
            break;
1346
0
        case LY_STMT_IF_FEATURE:
1347
0
            PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "refine");
1348
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &rf->iffeatures, Y_STR_ARG, &rf->exts));
1349
0
            break;
1350
0
        case LY_STMT_MAX_ELEMENTS:
1351
0
            LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &rf->max, &rf->flags, &rf->exts));
1352
0
            break;
1353
0
        case LY_STMT_MIN_ELEMENTS:
1354
0
            LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &rf->min, &rf->flags, &rf->exts));
1355
0
            break;
1356
0
        case LY_STMT_MUST:
1357
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &rf->musts));
1358
0
            break;
1359
0
        case LY_STMT_MANDATORY:
1360
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &rf->flags, &rf->exts));
1361
0
            break;
1362
0
        case LY_STMT_REFERENCE:
1363
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->ref, Y_STR_ARG, &rf->exts));
1364
0
            break;
1365
0
        case LY_STMT_PRESENCE:
1366
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->presence, Y_STR_ARG, &rf->exts));
1367
0
            break;
1368
0
        case LY_STMT_EXTENSION_INSTANCE:
1369
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REFINE, 0, &rf->exts));
1370
0
            break;
1371
0
        default:
1372
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "refine");
1373
0
            return LY_EVALID;
1374
0
        }
1375
0
    }
1376
1377
0
    return LY_SUCCESS;
1378
0
}
1379
1380
/**
1381
 * @brief Parse the typedef statement.
1382
 *
1383
 * @param[in] ctx parser context.
1384
 * @param[in] stmt Source statement data from the parsed extension instance.
1385
 * @param[in] parent Parent node to connect to (not into).
1386
 * @param[in,out] typedefs Typedefs to add to.
1387
 *
1388
 * @return LY_ERR values.
1389
 */
1390
static LY_ERR
1391
lysp_stmt_typedef(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_tpdf **typedefs)
1392
0
{
1393
0
    struct lysp_tpdf *tpdf;
1394
1395
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1396
1397
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *typedefs, tpdf, LY_EMEM);
1398
1399
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &tpdf->name));
1400
1401
    /* parse substatements */
1402
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1403
0
        switch (child->kw) {
1404
0
        case LY_STMT_DEFAULT:
1405
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->dflt.str, Y_STR_ARG, &tpdf->exts));
1406
0
            tpdf->dflt.mod = ctx->parsed_mod;
1407
0
            break;
1408
0
        case LY_STMT_DESCRIPTION:
1409
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->dsc, Y_STR_ARG, &tpdf->exts));
1410
0
            break;
1411
0
        case LY_STMT_REFERENCE:
1412
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->ref, Y_STR_ARG, &tpdf->exts));
1413
0
            break;
1414
0
        case LY_STMT_STATUS:
1415
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &tpdf->flags, &tpdf->exts));
1416
0
            break;
1417
0
        case LY_STMT_TYPE:
1418
0
            LY_CHECK_RET(lysp_stmt_type(ctx, child, &tpdf->type));
1419
0
            break;
1420
0
        case LY_STMT_UNITS:
1421
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->units, Y_STR_ARG, &tpdf->exts));
1422
0
            break;
1423
0
        case LY_STMT_EXTENSION_INSTANCE:
1424
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPEDEF, 0, &tpdf->exts));
1425
0
            break;
1426
0
        default:
1427
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "typedef");
1428
0
            return LY_EVALID;
1429
0
        }
1430
0
    }
1431
1432
    /* mandatory substatements */
1433
0
    if (!tpdf->type.name) {
1434
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "typedef");
1435
0
        return LY_EVALID;
1436
0
    }
1437
1438
    /* store data for collision check */
1439
0
    if (parent && !(parent->nodetype & (LYS_GROUPING | LYS_RPC | LYS_ACTION | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF))) {
1440
0
        LY_CHECK_RET(ly_set_add(&ctx->tpdfs_nodes, parent, 0, NULL));
1441
0
    }
1442
1443
0
    return LY_SUCCESS;
1444
0
}
1445
1446
/**
1447
 * @brief Parse the input or output statement.
1448
 *
1449
 * @param[in] ctx parser context.
1450
 * @param[in] stmt Source statement data from the parsed extension instance.
1451
 * @param[in] parent Parent node to connect to (not into).
1452
 * @param[in,out] inout_p Input/output pointer to write to.
1453
 *
1454
 * @return LY_ERR values.
1455
 */
1456
static LY_ERR
1457
lysp_stmt_inout(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
1458
        struct lysp_node_action_inout *inout_p)
1459
0
{
1460
0
    if (inout_p->nodetype) {
1461
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, ly_stmt2str(stmt->kw));
1462
0
        return LY_EVALID;
1463
0
    }
1464
1465
    /* initiate structure */
1466
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->kw == LY_STMT_INPUT ? "input" : "output", 0, &inout_p->name));
1467
0
    inout_p->nodetype = stmt->kw == LY_STMT_INPUT ? LYS_INPUT : LYS_OUTPUT;
1468
0
    inout_p->parent = parent;
1469
1470
    /* parse substatements */
1471
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1472
0
        switch (child->kw) {
1473
0
        case LY_STMT_ANYDATA:
1474
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", ly_stmt2str(stmt->kw));
1475
        /* fall through */
1476
0
        case LY_STMT_ANYXML:
1477
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &inout_p->node, &inout_p->child));
1478
0
            break;
1479
0
        case LY_STMT_CHOICE:
1480
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &inout_p->node, &inout_p->child));
1481
0
            break;
1482
0
        case LY_STMT_CONTAINER:
1483
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &inout_p->node, &inout_p->child));
1484
0
            break;
1485
0
        case LY_STMT_LEAF:
1486
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &inout_p->node, &inout_p->child));
1487
0
            break;
1488
0
        case LY_STMT_LEAF_LIST:
1489
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &inout_p->node, &inout_p->child));
1490
0
            break;
1491
0
        case LY_STMT_LIST:
1492
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &inout_p->node, &inout_p->child));
1493
0
            break;
1494
0
        case LY_STMT_USES:
1495
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &inout_p->node, &inout_p->child));
1496
0
            break;
1497
0
        case LY_STMT_TYPEDEF:
1498
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &inout_p->node, &inout_p->typedefs));
1499
0
            break;
1500
0
        case LY_STMT_MUST:
1501
0
            PARSER_CHECK_STMTVER2_RET(ctx, "must", ly_stmt2str(stmt->kw));
1502
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &inout_p->musts));
1503
0
            break;
1504
0
        case LY_STMT_GROUPING:
1505
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &inout_p->node, &inout_p->groupings));
1506
0
            break;
1507
0
        case LY_STMT_EXTENSION_INSTANCE:
1508
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &inout_p->exts));
1509
0
            break;
1510
0
        default:
1511
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), ly_stmt2str(stmt->kw));
1512
0
            return LY_EVALID;
1513
0
        }
1514
0
    }
1515
1516
0
    if (!inout_p->child) {
1517
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(stmt->kw));
1518
0
        return LY_EVALID;
1519
0
    }
1520
1521
0
    return LY_SUCCESS;
1522
0
}
1523
1524
/**
1525
 * @brief Parse the action statement.
1526
 *
1527
 * @param[in] ctx parser context.
1528
 * @param[in] stmt Source statement data from the parsed extension instance.
1529
 * @param[in] parent Parent node to connect to (not into).
1530
 * @param[in,out] actions Actions to add to.
1531
 *
1532
 * @return LY_ERR values.
1533
 */
1534
static LY_ERR
1535
lysp_stmt_action(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node_action **actions)
1536
0
{
1537
0
    struct lysp_node_action *act;
1538
1539
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1540
1541
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), actions, act, next, LY_EMEM);
1542
1543
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &act->name));
1544
0
    act->nodetype = parent ? LYS_ACTION : LYS_RPC;
1545
0
    act->parent = parent;
1546
1547
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1548
0
        switch (child->kw) {
1549
0
        case LY_STMT_DESCRIPTION:
1550
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &act->dsc, Y_STR_ARG, &act->exts));
1551
0
            break;
1552
0
        case LY_STMT_IF_FEATURE:
1553
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &act->iffeatures, Y_STR_ARG, &act->exts));
1554
0
            break;
1555
0
        case LY_STMT_REFERENCE:
1556
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &act->ref, Y_STR_ARG, &act->exts));
1557
0
            break;
1558
0
        case LY_STMT_STATUS:
1559
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &act->flags, &act->exts));
1560
0
            break;
1561
1562
0
        case LY_STMT_INPUT:
1563
0
            LY_CHECK_RET(lysp_stmt_inout(ctx, child, &act->node, &act->input));
1564
0
            break;
1565
0
        case LY_STMT_OUTPUT:
1566
0
            LY_CHECK_RET(lysp_stmt_inout(ctx, child, &act->node, &act->output));
1567
0
            break;
1568
1569
0
        case LY_STMT_TYPEDEF:
1570
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &act->node, &act->typedefs));
1571
0
            break;
1572
0
        case LY_STMT_GROUPING:
1573
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &act->node, &act->groupings));
1574
0
            break;
1575
0
        case LY_STMT_EXTENSION_INSTANCE:
1576
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, parent ? LY_STMT_ACTION : LY_STMT_RPC, 0, &act->exts));
1577
0
            break;
1578
0
        default:
1579
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), parent ? "action" : "rpc");
1580
0
            return LY_EVALID;
1581
0
        }
1582
0
    }
1583
1584
    /* always initialize inout, they are technically present (needed for later deviations/refines) */
1585
0
    if (!act->input.nodetype) {
1586
0
        act->input.nodetype = LYS_INPUT;
1587
0
        act->input.parent = &act->node;
1588
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), "input", 0, &act->input.name));
1589
0
    }
1590
0
    if (!act->output.nodetype) {
1591
0
        act->output.nodetype = LYS_OUTPUT;
1592
0
        act->output.parent = &act->node;
1593
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), "output", 0, &act->output.name));
1594
0
    }
1595
1596
0
    return LY_SUCCESS;
1597
0
}
1598
1599
/**
1600
 * @brief Parse the notification statement.
1601
 *
1602
 * @param[in] ctx parser context.
1603
 * @param[in] stmt Source statement data from the parsed extension instance.
1604
 * @param[in] parent Parent node to connect to (not into).
1605
 * @param[in,out] notifs Notifications to add to.
1606
 *
1607
 * @return LY_ERR values.
1608
 */
1609
static LY_ERR
1610
lysp_stmt_notif(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node_notif **notifs)
1611
0
{
1612
0
    struct lysp_node_notif *notif;
1613
1614
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1615
1616
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), notifs, notif, next, LY_EMEM);
1617
1618
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &notif->name));
1619
0
    notif->nodetype = LYS_NOTIF;
1620
0
    notif->parent = parent;
1621
1622
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1623
0
        switch (child->kw) {
1624
0
        case LY_STMT_DESCRIPTION:
1625
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &notif->dsc, Y_STR_ARG, &notif->exts));
1626
0
            break;
1627
0
        case LY_STMT_IF_FEATURE:
1628
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &notif->iffeatures, Y_STR_ARG, &notif->exts));
1629
0
            break;
1630
0
        case LY_STMT_REFERENCE:
1631
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &notif->ref, Y_STR_ARG, &notif->exts));
1632
0
            break;
1633
0
        case LY_STMT_STATUS:
1634
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &notif->flags, &notif->exts));
1635
0
            break;
1636
1637
0
        case LY_STMT_ANYDATA:
1638
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "notification");
1639
        /* fall through */
1640
0
        case LY_STMT_ANYXML:
1641
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &notif->node, &notif->child));
1642
0
            break;
1643
0
        case LY_STMT_CHOICE:
1644
0
            LY_CHECK_RET(lysp_stmt_case(ctx, child, &notif->node, &notif->child));
1645
0
            break;
1646
0
        case LY_STMT_CONTAINER:
1647
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &notif->node, &notif->child));
1648
0
            break;
1649
0
        case LY_STMT_LEAF:
1650
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &notif->node, &notif->child));
1651
0
            break;
1652
0
        case LY_STMT_LEAF_LIST:
1653
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &notif->node, &notif->child));
1654
0
            break;
1655
0
        case LY_STMT_LIST:
1656
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &notif->node, &notif->child));
1657
0
            break;
1658
0
        case LY_STMT_USES:
1659
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &notif->node, &notif->child));
1660
0
            break;
1661
1662
0
        case LY_STMT_MUST:
1663
0
            PARSER_CHECK_STMTVER2_RET(ctx, "must", "notification");
1664
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &notif->musts));
1665
0
            break;
1666
0
        case LY_STMT_TYPEDEF:
1667
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &notif->node, &notif->typedefs));
1668
0
            break;
1669
0
        case LY_STMT_GROUPING:
1670
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &notif->node, &notif->groupings));
1671
0
            break;
1672
0
        case LY_STMT_EXTENSION_INSTANCE:
1673
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_NOTIFICATION, 0, &notif->exts));
1674
0
            break;
1675
0
        default:
1676
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "notification");
1677
0
            return LY_EVALID;
1678
0
        }
1679
0
    }
1680
1681
0
    return LY_SUCCESS;
1682
0
}
1683
1684
/**
1685
 * @brief Parse the grouping statement.
1686
 *
1687
 * @param[in] ctx parser context.
1688
 * @param[in] stmt Source statement data from the parsed extension instance.
1689
 * @param[in] parent Parent node to connect to (not into).
1690
 * @param[in,out] groupings Groupings to add to.
1691
 *
1692
 * @return LY_ERR values.
1693
 */
1694
static LY_ERR
1695
lysp_stmt_grouping(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node_grp **groupings)
1696
0
{
1697
0
    struct lysp_node_grp *grp;
1698
1699
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1700
1701
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), groupings, grp, next, LY_EMEM);
1702
1703
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &grp->name));
1704
0
    grp->nodetype = LYS_GROUPING;
1705
0
    grp->parent = parent;
1706
1707
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1708
0
        switch (child->kw) {
1709
0
        case LY_STMT_DESCRIPTION:
1710
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &grp->dsc, Y_STR_ARG, &grp->exts));
1711
0
            break;
1712
0
        case LY_STMT_REFERENCE:
1713
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &grp->ref, Y_STR_ARG, &grp->exts));
1714
0
            break;
1715
0
        case LY_STMT_STATUS:
1716
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &grp->flags, &grp->exts));
1717
0
            break;
1718
1719
0
        case LY_STMT_ANYDATA:
1720
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "grouping");
1721
        /* fall through */
1722
0
        case LY_STMT_ANYXML:
1723
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &grp->node, &grp->child));
1724
0
            break;
1725
0
        case LY_STMT_CHOICE:
1726
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &grp->node, &grp->child));
1727
0
            break;
1728
0
        case LY_STMT_CONTAINER:
1729
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &grp->node, &grp->child));
1730
0
            break;
1731
0
        case LY_STMT_LEAF:
1732
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &grp->node, &grp->child));
1733
0
            break;
1734
0
        case LY_STMT_LEAF_LIST:
1735
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &grp->node, &grp->child));
1736
0
            break;
1737
0
        case LY_STMT_LIST:
1738
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &grp->node, &grp->child));
1739
0
            break;
1740
0
        case LY_STMT_USES:
1741
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &grp->node, &grp->child));
1742
0
            break;
1743
1744
0
        case LY_STMT_TYPEDEF:
1745
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &grp->node, &grp->typedefs));
1746
0
            break;
1747
0
        case LY_STMT_ACTION:
1748
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "grouping");
1749
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &grp->node, &grp->actions));
1750
0
            break;
1751
0
        case LY_STMT_GROUPING:
1752
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &grp->node, &grp->groupings));
1753
0
            break;
1754
0
        case LY_STMT_NOTIFICATION:
1755
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "grouping");
1756
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &grp->node, &grp->notifs));
1757
0
            break;
1758
0
        case LY_STMT_EXTENSION_INSTANCE:
1759
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_GROUPING, 0, &grp->exts));
1760
0
            break;
1761
0
        default:
1762
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "grouping");
1763
0
            return LY_EVALID;
1764
0
        }
1765
0
    }
1766
1767
0
    return LY_SUCCESS;
1768
0
}
1769
1770
/**
1771
 * @brief Parse the augment statement.
1772
 *
1773
 * @param[in] ctx parser context.
1774
 * @param[in] stmt Source statement data from the parsed extension instance.
1775
 * @param[in] parent Parent node to connect to (not into).
1776
 * @param[in,out] augments Augments to add to.
1777
 *
1778
 * @return LY_ERR values.
1779
 */
1780
static LY_ERR
1781
lysp_stmt_augment(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node_augment **augments)
1782
0
{
1783
0
    struct lysp_node_augment *aug;
1784
1785
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1786
1787
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), augments, aug, next, LY_EMEM);
1788
1789
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &aug->nodeid));
1790
0
    aug->nodetype = LYS_AUGMENT;
1791
0
    aug->parent = parent;
1792
1793
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1794
0
        switch (child->kw) {
1795
0
        case LY_STMT_DESCRIPTION:
1796
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
1797
0
            break;
1798
0
        case LY_STMT_IF_FEATURE:
1799
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &aug->iffeatures, Y_STR_ARG, &aug->exts));
1800
0
            break;
1801
0
        case LY_STMT_REFERENCE:
1802
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &aug->ref, Y_STR_ARG, &aug->exts));
1803
0
            break;
1804
0
        case LY_STMT_STATUS:
1805
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &aug->flags, &aug->exts));
1806
0
            break;
1807
0
        case LY_STMT_WHEN:
1808
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &aug->when));
1809
0
            break;
1810
1811
0
        case LY_STMT_ANYDATA:
1812
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "augment");
1813
        /* fall through */
1814
0
        case LY_STMT_ANYXML:
1815
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &aug->node, &aug->child));
1816
0
            break;
1817
0
        case LY_STMT_CASE:
1818
0
            LY_CHECK_RET(lysp_stmt_case(ctx, child, &aug->node, &aug->child));
1819
0
            break;
1820
0
        case LY_STMT_CHOICE:
1821
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &aug->node, &aug->child));
1822
0
            break;
1823
0
        case LY_STMT_CONTAINER:
1824
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &aug->node, &aug->child));
1825
0
            break;
1826
0
        case LY_STMT_LEAF:
1827
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &aug->node, &aug->child));
1828
0
            break;
1829
0
        case LY_STMT_LEAF_LIST:
1830
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &aug->node, &aug->child));
1831
0
            break;
1832
0
        case LY_STMT_LIST:
1833
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &aug->node, &aug->child));
1834
0
            break;
1835
0
        case LY_STMT_USES:
1836
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &aug->node, &aug->child));
1837
0
            break;
1838
1839
0
        case LY_STMT_ACTION:
1840
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "augment");
1841
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &aug->node, &aug->actions));
1842
0
            break;
1843
0
        case LY_STMT_NOTIFICATION:
1844
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "augment");
1845
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &aug->node, &aug->notifs));
1846
0
            break;
1847
0
        case LY_STMT_EXTENSION_INSTANCE:
1848
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_AUGMENT, 0, &aug->exts));
1849
0
            break;
1850
0
        default:
1851
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "augment");
1852
0
            return LY_EVALID;
1853
0
        }
1854
0
    }
1855
1856
0
    return LY_SUCCESS;
1857
0
}
1858
1859
/**
1860
 * @brief Parse the uses statement.
1861
 *
1862
 * @param[in] ctx parser context.
1863
 * @param[in] stmt Source statement data from the parsed extension instance.
1864
 * @param[in] parent Parent node to connect to (not into).
1865
 * @param[in,out] siblings Siblings to add to.
1866
 *
1867
 * @return LY_ERR values.
1868
 */
1869
static LY_ERR
1870
lysp_stmt_uses(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
1871
0
{
1872
0
    struct lysp_node_uses *uses;
1873
1874
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
1875
1876
    /* create uses structure */
1877
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, uses, next, LY_EMEM);
1878
1879
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &uses->name));
1880
0
    uses->nodetype = LYS_USES;
1881
0
    uses->parent = parent;
1882
1883
    /* parse substatements */
1884
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1885
0
        switch (child->kw) {
1886
0
        case LY_STMT_DESCRIPTION:
1887
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
1888
0
            break;
1889
0
        case LY_STMT_IF_FEATURE:
1890
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &uses->iffeatures, Y_STR_ARG, &uses->exts));
1891
0
            break;
1892
0
        case LY_STMT_REFERENCE:
1893
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &uses->ref, Y_STR_ARG, &uses->exts));
1894
0
            break;
1895
0
        case LY_STMT_STATUS:
1896
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &uses->flags, &uses->exts));
1897
0
            break;
1898
0
        case LY_STMT_WHEN:
1899
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &uses->when));
1900
0
            break;
1901
1902
0
        case LY_STMT_REFINE:
1903
0
            LY_CHECK_RET(lysp_stmt_refine(ctx, child, &uses->refines));
1904
0
            break;
1905
0
        case LY_STMT_AUGMENT:
1906
0
            LY_CHECK_RET(lysp_stmt_augment(ctx, child, &uses->node, &uses->augments));
1907
0
            break;
1908
0
        case LY_STMT_EXTENSION_INSTANCE:
1909
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_USES, 0, &uses->exts));
1910
0
            break;
1911
0
        default:
1912
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "uses");
1913
0
            return LY_EVALID;
1914
0
        }
1915
0
    }
1916
1917
0
    return LY_SUCCESS;
1918
0
}
1919
1920
/**
1921
 * @brief Parse the case statement.
1922
 *
1923
 * @param[in] ctx parser context.
1924
 * @param[in] stmt Source statement data from the parsed extension instance.
1925
 * @param[in] parent Parent node to connect to (not into).
1926
 * @param[in,out] siblings Siblings to add to.
1927
 *
1928
 * @return LY_ERR values.
1929
 */
1930
static LY_ERR
1931
lysp_stmt_case(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
1932
0
{
1933
0
    struct lysp_node_case *cas;
1934
1935
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1936
1937
    /* create new case structure */
1938
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, cas, next, LY_EMEM);
1939
1940
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &cas->name));
1941
0
    cas->nodetype = LYS_CASE;
1942
0
    cas->parent = parent;
1943
1944
    /* parse substatements */
1945
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1946
0
        switch (child->kw) {
1947
0
        case LY_STMT_DESCRIPTION:
1948
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
1949
0
            break;
1950
0
        case LY_STMT_IF_FEATURE:
1951
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &cas->iffeatures, Y_STR_ARG, &cas->exts));
1952
0
            break;
1953
0
        case LY_STMT_REFERENCE:
1954
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cas->ref, Y_STR_ARG, &cas->exts));
1955
0
            break;
1956
0
        case LY_STMT_STATUS:
1957
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &cas->flags, &cas->exts));
1958
0
            break;
1959
0
        case LY_STMT_WHEN:
1960
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &cas->when));
1961
0
            break;
1962
1963
0
        case LY_STMT_ANYDATA:
1964
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "case");
1965
        /* fall through */
1966
0
        case LY_STMT_ANYXML:
1967
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &cas->node, &cas->child));
1968
0
            break;
1969
0
        case LY_STMT_CHOICE:
1970
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &cas->node, &cas->child));
1971
0
            break;
1972
0
        case LY_STMT_CONTAINER:
1973
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &cas->node, &cas->child));
1974
0
            break;
1975
0
        case LY_STMT_LEAF:
1976
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &cas->node, &cas->child));
1977
0
            break;
1978
0
        case LY_STMT_LEAF_LIST:
1979
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &cas->node, &cas->child));
1980
0
            break;
1981
0
        case LY_STMT_LIST:
1982
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &cas->node, &cas->child));
1983
0
            break;
1984
0
        case LY_STMT_USES:
1985
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &cas->node, &cas->child));
1986
0
            break;
1987
0
        case LY_STMT_EXTENSION_INSTANCE:
1988
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CASE, 0, &cas->exts));
1989
0
            break;
1990
0
        default:
1991
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "case");
1992
0
            return LY_EVALID;
1993
0
        }
1994
0
    }
1995
0
    return LY_SUCCESS;
1996
0
}
1997
1998
/**
1999
 * @brief Parse the choice statement.
2000
 *
2001
 * @param[in] ctx parser context.
2002
 * @param[in] stmt Source statement data from the parsed extension instance.
2003
 * @param[in] parent Parent node to connect to (not into).
2004
 * @param[in,out] siblings Siblings to add to.
2005
 *
2006
 * @return LY_ERR values.
2007
 */
2008
static LY_ERR
2009
lysp_stmt_choice(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
2010
0
{
2011
0
    struct lysp_node_choice *choice;
2012
2013
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2014
2015
    /* create new choice structure */
2016
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, choice, next, LY_EMEM);
2017
2018
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &choice->name));
2019
0
    choice->nodetype = LYS_CHOICE;
2020
0
    choice->parent = parent;
2021
2022
    /* parse substatements */
2023
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2024
0
        switch (child->kw) {
2025
0
        case LY_STMT_CONFIG:
2026
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &choice->flags, &choice->exts));
2027
0
            break;
2028
0
        case LY_STMT_DESCRIPTION:
2029
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->dsc, Y_STR_ARG, &choice->exts));
2030
0
            break;
2031
0
        case LY_STMT_IF_FEATURE:
2032
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &choice->iffeatures, Y_STR_ARG, &choice->exts));
2033
0
            break;
2034
0
        case LY_STMT_MANDATORY:
2035
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &choice->flags, &choice->exts));
2036
0
            break;
2037
0
        case LY_STMT_REFERENCE:
2038
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->ref, Y_STR_ARG, &choice->exts));
2039
0
            break;
2040
0
        case LY_STMT_STATUS:
2041
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &choice->flags, &choice->exts));
2042
0
            break;
2043
0
        case LY_STMT_WHEN:
2044
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &choice->when));
2045
0
            break;
2046
0
        case LY_STMT_DEFAULT:
2047
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->dflt.str, Y_PREF_IDENTIF_ARG, &choice->exts));
2048
0
            choice->dflt.mod = ctx->parsed_mod;
2049
0
            break;
2050
0
        case LY_STMT_ANYDATA:
2051
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "choice");
2052
        /* fall through */
2053
0
        case LY_STMT_ANYXML:
2054
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &choice->node, &choice->child));
2055
0
            break;
2056
0
        case LY_STMT_CASE:
2057
0
            LY_CHECK_RET(lysp_stmt_case(ctx, child, &choice->node, &choice->child));
2058
0
            break;
2059
0
        case LY_STMT_CHOICE:
2060
0
            PARSER_CHECK_STMTVER2_RET(ctx, "choice", "choice");
2061
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &choice->node, &choice->child));
2062
0
            break;
2063
0
        case LY_STMT_CONTAINER:
2064
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &choice->node, &choice->child));
2065
0
            break;
2066
0
        case LY_STMT_LEAF:
2067
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &choice->node, &choice->child));
2068
0
            break;
2069
0
        case LY_STMT_LEAF_LIST:
2070
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &choice->node, &choice->child));
2071
0
            break;
2072
0
        case LY_STMT_LIST:
2073
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &choice->node, &choice->child));
2074
0
            break;
2075
0
        case LY_STMT_EXTENSION_INSTANCE:
2076
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CHOICE, 0, &choice->exts));
2077
0
            break;
2078
0
        default:
2079
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "choice");
2080
0
            return LY_EVALID;
2081
0
        }
2082
0
    }
2083
0
    return LY_SUCCESS;
2084
0
}
2085
2086
/**
2087
 * @brief Parse the container statement.
2088
 *
2089
 * @param[in] ctx parser context.
2090
 * @param[in] stmt Source statement data from the parsed extension instance.
2091
 * @param[in] parent Parent node to connect to (not into).
2092
 * @param[in,out] siblings Siblings to add to.
2093
 *
2094
 * @return LY_ERR values.
2095
 */
2096
static LY_ERR
2097
lysp_stmt_container(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
2098
0
{
2099
0
    struct lysp_node_container *cont;
2100
2101
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2102
2103
    /* create new container structure */
2104
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, cont, next, LY_EMEM);
2105
2106
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &cont->name));
2107
0
    cont->nodetype = LYS_CONTAINER;
2108
0
    cont->parent = parent;
2109
2110
    /* parse substatements */
2111
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2112
0
        switch (child->kw) {
2113
0
        case LY_STMT_CONFIG:
2114
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &cont->flags, &cont->exts));
2115
0
            break;
2116
0
        case LY_STMT_DESCRIPTION:
2117
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->dsc, Y_STR_ARG, &cont->exts));
2118
0
            break;
2119
0
        case LY_STMT_IF_FEATURE:
2120
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &cont->iffeatures, Y_STR_ARG, &cont->exts));
2121
0
            break;
2122
0
        case LY_STMT_REFERENCE:
2123
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->ref, Y_STR_ARG, &cont->exts));
2124
0
            break;
2125
0
        case LY_STMT_STATUS:
2126
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &cont->flags, &cont->exts));
2127
0
            break;
2128
0
        case LY_STMT_WHEN:
2129
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &cont->when));
2130
0
            break;
2131
0
        case LY_STMT_PRESENCE:
2132
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->presence, Y_STR_ARG, &cont->exts));
2133
0
            break;
2134
0
        case LY_STMT_ANYDATA:
2135
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "container");
2136
        /* fall through */
2137
0
        case LY_STMT_ANYXML:
2138
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &cont->node, &cont->child));
2139
0
            break;
2140
0
        case LY_STMT_CHOICE:
2141
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &cont->node, &cont->child));
2142
0
            break;
2143
0
        case LY_STMT_CONTAINER:
2144
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &cont->node, &cont->child));
2145
0
            break;
2146
0
        case LY_STMT_LEAF:
2147
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &cont->node, &cont->child));
2148
0
            break;
2149
0
        case LY_STMT_LEAF_LIST:
2150
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &cont->node, &cont->child));
2151
0
            break;
2152
0
        case LY_STMT_LIST:
2153
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &cont->node, &cont->child));
2154
0
            break;
2155
0
        case LY_STMT_USES:
2156
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &cont->node, &cont->child));
2157
0
            break;
2158
2159
0
        case LY_STMT_TYPEDEF:
2160
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &cont->node, &cont->typedefs));
2161
0
            break;
2162
0
        case LY_STMT_MUST:
2163
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &cont->musts));
2164
0
            break;
2165
0
        case LY_STMT_ACTION:
2166
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "container");
2167
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &cont->node, &cont->actions));
2168
0
            break;
2169
0
        case LY_STMT_GROUPING:
2170
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &cont->node, &cont->groupings));
2171
0
            break;
2172
0
        case LY_STMT_NOTIFICATION:
2173
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "container");
2174
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &cont->node, &cont->notifs));
2175
0
            break;
2176
0
        case LY_STMT_EXTENSION_INSTANCE:
2177
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONTAINER, 0, &cont->exts));
2178
0
            break;
2179
0
        default:
2180
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "container");
2181
0
            return LY_EVALID;
2182
0
        }
2183
0
    }
2184
2185
0
    return LY_SUCCESS;
2186
0
}
2187
2188
/**
2189
 * @brief Parse the list statement.
2190
 *
2191
 * @param[in] ctx parser context.
2192
 * @param[in] stmt Source statement data from the parsed extension instance.
2193
 * @param[in] parent Parent node to connect to (not into).
2194
 * @param[in,out] siblings Siblings to add to.
2195
 *
2196
 * @return LY_ERR values.
2197
 */
2198
static LY_ERR
2199
lysp_stmt_list(struct lys_parser_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
2200
0
{
2201
0
    struct lysp_node_list *list;
2202
2203
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2204
2205
    /* create new list structure */
2206
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, list, next, LY_EMEM);
2207
2208
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &list->name));
2209
0
    list->nodetype = LYS_LIST;
2210
0
    list->parent = parent;
2211
2212
    /* parse substatements */
2213
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2214
0
        switch (child->kw) {
2215
0
        case LY_STMT_CONFIG:
2216
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &list->flags, &list->exts));
2217
0
            break;
2218
0
        case LY_STMT_DESCRIPTION:
2219
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->dsc, Y_STR_ARG, &list->exts));
2220
0
            break;
2221
0
        case LY_STMT_IF_FEATURE:
2222
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &list->iffeatures, Y_STR_ARG, &list->exts));
2223
0
            break;
2224
0
        case LY_STMT_REFERENCE:
2225
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->ref, Y_STR_ARG, &list->exts));
2226
0
            break;
2227
0
        case LY_STMT_STATUS:
2228
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &list->flags, &list->exts));
2229
0
            break;
2230
0
        case LY_STMT_WHEN:
2231
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &list->when));
2232
0
            break;
2233
0
        case LY_STMT_KEY:
2234
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->key, Y_STR_ARG, &list->exts));
2235
0
            break;
2236
0
        case LY_STMT_MAX_ELEMENTS:
2237
0
            LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &list->max, &list->flags, &list->exts));
2238
0
            break;
2239
0
        case LY_STMT_MIN_ELEMENTS:
2240
0
            LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &list->min, &list->flags, &list->exts));
2241
0
            break;
2242
0
        case LY_STMT_ORDERED_BY:
2243
0
            LY_CHECK_RET(lysp_stmt_orderedby(ctx, child, &list->flags, &list->exts));
2244
0
            break;
2245
0
        case LY_STMT_UNIQUE:
2246
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &list->uniques, Y_STR_ARG, &list->exts));
2247
0
            break;
2248
2249
0
        case LY_STMT_ANYDATA:
2250
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "list");
2251
        /* fall through */
2252
0
        case LY_STMT_ANYXML:
2253
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &list->node, &list->child));
2254
0
            break;
2255
0
        case LY_STMT_CHOICE:
2256
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &list->node, &list->child));
2257
0
            break;
2258
0
        case LY_STMT_CONTAINER:
2259
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &list->node, &list->child));
2260
0
            break;
2261
0
        case LY_STMT_LEAF:
2262
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &list->node, &list->child));
2263
0
            break;
2264
0
        case LY_STMT_LEAF_LIST:
2265
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &list->node, &list->child));
2266
0
            break;
2267
0
        case LY_STMT_LIST:
2268
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &list->node, &list->child));
2269
0
            break;
2270
0
        case LY_STMT_USES:
2271
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &list->node, &list->child));
2272
0
            break;
2273
2274
0
        case LY_STMT_TYPEDEF:
2275
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &list->node, &list->typedefs));
2276
0
            break;
2277
0
        case LY_STMT_MUST:
2278
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &list->musts));
2279
0
            break;
2280
0
        case LY_STMT_ACTION:
2281
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "list");
2282
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &list->node, &list->actions));
2283
0
            break;
2284
0
        case LY_STMT_GROUPING:
2285
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &list->node, &list->groupings));
2286
0
            break;
2287
0
        case LY_STMT_NOTIFICATION:
2288
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "list");
2289
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &list->node, &list->notifs));
2290
0
            break;
2291
0
        case LY_STMT_EXTENSION_INSTANCE:
2292
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LIST, 0, &list->exts));
2293
0
            break;
2294
0
        default:
2295
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(child->kw), "list");
2296
0
            return LY_EVALID;
2297
0
        }
2298
0
    }
2299
2300
0
    return LY_SUCCESS;
2301
0
}
2302
2303
LY_ERR
2304
lysp_stmt_parse(struct lysc_ctx *ctx, const struct lysp_stmt *stmt, void **result, struct lysp_ext_instance **exts)
2305
0
{
2306
0
    LY_ERR ret = LY_SUCCESS;
2307
0
    uint16_t flags;
2308
0
    struct lys_parser_ctx pctx = {0};
2309
2310
0
    pctx.format = LYS_IN_YANG;
2311
0
    pctx.parsed_mod = ctx->pmod;
2312
2313
0
    LOG_LOCSET(NULL, NULL, ctx->path, NULL);
2314
2315
0
    switch (stmt->kw) {
2316
0
    case LY_STMT_ACTION:
2317
0
    case LY_STMT_RPC:
2318
0
        ret = lysp_stmt_action(&pctx, stmt, NULL, (struct lysp_node_action **)result);
2319
0
        break;
2320
0
    case LY_STMT_ANYDATA:
2321
0
    case LY_STMT_ANYXML:
2322
0
        ret = lysp_stmt_any(&pctx, stmt, NULL, (struct lysp_node **)result);
2323
0
        break;
2324
0
    case LY_STMT_AUGMENT:
2325
0
        ret = lysp_stmt_augment(&pctx, stmt, NULL, (struct lysp_node_augment **)result);
2326
0
        break;
2327
0
    case LY_STMT_BASE:
2328
0
        ret = lysp_stmt_text_fields(&pctx, stmt, (const char ***)result, Y_PREF_IDENTIF_ARG, exts);
2329
0
        break;
2330
0
    case LY_STMT_BIT:
2331
0
    case LY_STMT_ENUM:
2332
0
        ret = lysp_stmt_type_enum(&pctx, stmt, (struct lysp_type_enum **)result);
2333
0
        break;
2334
0
    case LY_STMT_CASE:
2335
0
        ret = lysp_stmt_case(&pctx, stmt, NULL, (struct lysp_node **)result);
2336
0
        break;
2337
0
    case LY_STMT_CHOICE:
2338
0
        ret = lysp_stmt_choice(&pctx, stmt, NULL, (struct lysp_node **)result);
2339
0
        break;
2340
0
    case LY_STMT_CONFIG:
2341
0
        ret = lysp_stmt_config(&pctx, stmt, *(uint16_t **)result, exts);
2342
0
        break;
2343
0
    case LY_STMT_CONTACT:
2344
0
    case LY_STMT_DESCRIPTION:
2345
0
    case LY_STMT_ERROR_APP_TAG:
2346
0
    case LY_STMT_ERROR_MESSAGE:
2347
0
    case LY_STMT_KEY:
2348
0
    case LY_STMT_NAMESPACE:
2349
0
    case LY_STMT_ORGANIZATION:
2350
0
    case LY_STMT_PRESENCE:
2351
0
    case LY_STMT_REFERENCE:
2352
0
    case LY_STMT_UNITS:
2353
0
        ret = lysp_stmt_text_field(&pctx, stmt, 0, (const char **)result, Y_STR_ARG, exts);
2354
0
        break;
2355
0
    case LY_STMT_CONTAINER:
2356
0
        ret = lysp_stmt_container(&pctx, stmt, NULL, (struct lysp_node **)result);
2357
0
        break;
2358
0
    case LY_STMT_DEFAULT:
2359
0
    case LY_STMT_IF_FEATURE:
2360
0
    case LY_STMT_UNIQUE:
2361
0
        ret = lysp_stmt_qnames(&pctx, stmt, (struct lysp_qname **)result, Y_STR_ARG, exts);
2362
0
        break;
2363
0
    case LY_STMT_EXTENSION_INSTANCE:
2364
0
        ret = lysp_stmt_ext(&pctx, stmt, LY_STMT_EXTENSION_INSTANCE, 0, exts);
2365
0
        break;
2366
0
    case LY_STMT_FRACTION_DIGITS:
2367
0
        ret = lysp_stmt_type_fracdigits(&pctx, stmt, *(uint8_t **)result, exts);
2368
0
        break;
2369
0
    case LY_STMT_GROUPING:
2370
0
        ret = lysp_stmt_grouping(&pctx, stmt, NULL, (struct lysp_node_grp **)result);
2371
0
        break;
2372
0
    case LY_STMT_INPUT:
2373
0
    case LY_STMT_OUTPUT: {
2374
0
        struct lysp_node_action_inout *inout;
2375
2376
0
        *result = inout = calloc(1, sizeof *inout);
2377
0
        LY_CHECK_ERR_RET(!inout, LOGMEM(ctx->ctx), LY_EMEM);
2378
0
        ret = lysp_stmt_inout(&pctx, stmt, NULL, inout);
2379
0
        break;
2380
0
    }
2381
0
    case LY_STMT_LEAF:
2382
0
        ret = lysp_stmt_leaf(&pctx, stmt, NULL, (struct lysp_node **)result);
2383
0
        break;
2384
0
    case LY_STMT_LEAF_LIST:
2385
0
        ret = lysp_stmt_leaflist(&pctx, stmt, NULL, (struct lysp_node **)result);
2386
0
        break;
2387
0
    case LY_STMT_LENGTH:
2388
0
    case LY_STMT_MUST:
2389
0
    case LY_STMT_RANGE:
2390
0
        ret = lysp_stmt_restrs(&pctx, stmt, (struct lysp_restr **)result);
2391
0
        break;
2392
0
    case LY_STMT_LIST:
2393
0
        ret = lysp_stmt_list(&pctx, stmt, NULL, (struct lysp_node **)result);
2394
0
        break;
2395
0
    case LY_STMT_MANDATORY:
2396
0
        ret = lysp_stmt_mandatory(&pctx, stmt, *(uint16_t **)result, exts);
2397
0
        break;
2398
0
    case LY_STMT_MAX_ELEMENTS:
2399
0
        flags = 0;
2400
0
        ret = lysp_stmt_maxelements(&pctx, stmt, *(uint32_t **)result, &flags, exts);
2401
0
        break;
2402
0
    case LY_STMT_MIN_ELEMENTS:
2403
0
        flags = 0;
2404
0
        ret = lysp_stmt_minelements(&pctx, stmt, *(uint32_t **)result, &flags, exts);
2405
0
        break;
2406
0
    case LY_STMT_MODIFIER:
2407
0
        ret = lysp_stmt_type_pattern_modifier(&pctx, stmt, (const char **)result, exts);
2408
0
        break;
2409
0
    case LY_STMT_NOTIFICATION:
2410
0
        ret = lysp_stmt_notif(&pctx, stmt, NULL, (struct lysp_node_notif **)result);
2411
0
        break;
2412
0
    case LY_STMT_ORDERED_BY:
2413
0
        ret = lysp_stmt_orderedby(&pctx, stmt, *(uint16_t **)result, exts);
2414
0
        break;
2415
0
    case LY_STMT_PATH: {
2416
0
        const char *str_path = NULL;
2417
2418
0
        LY_CHECK_RET(lysp_stmt_text_field(&pctx, stmt, 0, &str_path, Y_STR_ARG, exts));
2419
0
        ret = ly_path_parse(ctx->ctx, NULL, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
2420
0
                LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, (struct lyxp_expr **)result);
2421
0
        lydict_remove(ctx->ctx, str_path);
2422
0
        break;
2423
0
    }
2424
0
    case LY_STMT_PATTERN:
2425
0
        ret = lysp_stmt_type_pattern(&pctx, stmt, (struct lysp_restr **)result);
2426
0
        break;
2427
0
    case LY_STMT_POSITION:
2428
0
    case LY_STMT_VALUE:
2429
0
        flags = 0;
2430
0
        ret = lysp_stmt_type_enum_value_pos(&pctx, stmt, *(int64_t **)result, &flags, exts);
2431
0
        break;
2432
0
    case LY_STMT_PREFIX:
2433
0
        ret = lysp_stmt_text_field(&pctx, stmt, 0, (const char **)result, Y_IDENTIF_ARG, exts);
2434
0
        break;
2435
0
    case LY_STMT_REFINE:
2436
0
        ret = lysp_stmt_refine(&pctx, stmt, (struct lysp_refine **)result);
2437
0
        break;
2438
0
    case LY_STMT_REQUIRE_INSTANCE:
2439
0
        flags = 0;
2440
0
        ret = lysp_stmt_type_reqinstance(&pctx, stmt, *(uint8_t **)result, &flags, exts);
2441
0
        break;
2442
0
    case LY_STMT_STATUS:
2443
0
        ret = lysp_stmt_status(&pctx, stmt, *(uint16_t **)result, exts);
2444
0
        break;
2445
0
    case LY_STMT_TYPE: {
2446
0
        struct lysp_type *type;
2447
2448
0
        *result = type = calloc(1, sizeof *type);
2449
0
        LY_CHECK_ERR_RET(!type, LOGMEM(ctx->ctx), LY_EMEM);
2450
0
        ret = lysp_stmt_type(&pctx, stmt, type);
2451
0
        break;
2452
0
    }
2453
0
    case LY_STMT_TYPEDEF:
2454
0
        ret = lysp_stmt_typedef(&pctx, stmt, NULL, (struct lysp_tpdf **)result);
2455
0
        break;
2456
0
    case LY_STMT_USES:
2457
0
        ret = lysp_stmt_uses(&pctx, stmt, NULL, (struct lysp_node **)result);
2458
0
        break;
2459
0
    case LY_STMT_WHEN:
2460
0
        ret = lysp_stmt_when(&pctx, stmt, (struct lysp_when **)result);
2461
0
        break;
2462
0
    default:
2463
0
        LOGINT(ctx->ctx);
2464
0
        return LY_EINT;
2465
0
    }
2466
2467
0
    LOG_LOCBACK(0, 0, 1, 0);
2468
0
    return ret;
2469
0
}