Coverage Report

Created: 2025-11-11 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libyang/src/printer_yin.c
Line
Count
Source
1
/**
2
 * @file printer_yin.c
3
 * @author Fred Gan <ganshaolong@vip.qq.com>
4
 * @brief YIN printer
5
 *
6
 * Copyright (c) 2015 - 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
#define _GNU_SOURCE
16
17
#include <stdint.h>
18
#include <stdio.h>
19
#include <stdlib.h>
20
21
#include "common.h"
22
#include "compat.h"
23
#include "log.h"
24
#include "out.h"
25
#include "out_internal.h"
26
#include "printer_internal.h"
27
#include "tree.h"
28
#include "tree_schema.h"
29
#include "tree_schema_internal.h"
30
#include "xml.h"
31
#include "xpath.h"
32
33
/**
34
 * @brief YIN printer context.
35
 */
36
struct lys_ypr_ctx {
37
    union {
38
        struct {
39
            struct ly_out *out;              /**< output specification */
40
            uint16_t level;                  /**< current indentation level: 0 - no formatting, >= 1 indentation levels */
41
            uint32_t options;                /**< Schema output options (see @ref schemaprinterflags). */
42
            const struct lys_module *module; /**< schema to print */
43
        };
44
        struct lyspr_ctx printer_ctx;
45
    };
46
47
    /* YIN printer specific members */
48
};
49
50
static void yprp_extension_instances(struct lys_ypr_ctx *ctx, enum ly_stmt substmt, uint8_t substmt_index,
51
        struct lysp_ext_instance *ext, int8_t *flag, LY_ARRAY_COUNT_TYPE count);
52
53
static void
54
ypr_open(struct lys_ypr_ctx *ctx, const char *elem_name, const char *attr_name, const char *attr_value, int8_t flag)
55
0
{
56
0
    ly_print_(ctx->out, "%*s<%s", INDENT, elem_name);
57
58
0
    if (attr_name) {
59
0
        ly_print_(ctx->out, " %s=\"", attr_name);
60
0
        lyxml_dump_text(ctx->out, attr_value, 1);
61
0
        ly_print_(ctx->out, "\"%s", flag == -1 ? "/>\n" : flag == 1 ? ">\n" : "");
62
0
    } else if (flag) {
63
0
        ly_print_(ctx->out, flag == -1 ? "/>\n" : ">\n");
64
0
    }
65
0
}
66
67
static void
68
ypr_close(struct lys_ypr_ctx *ctx, const char *elem_name, int8_t flag)
69
0
{
70
0
    if (flag) {
71
0
        ly_print_(ctx->out, "%*s</%s>\n", INDENT, elem_name);
72
0
    } else {
73
0
        ly_print_(ctx->out, "/>\n");
74
0
    }
75
0
}
76
77
/*
78
 * par_close_flag
79
 * 0 - parent not yet closed, printing >\n, setting flag to 1
80
 * 1 or NULL - parent already closed, do nothing
81
 */
82
static void
83
ypr_close_parent(struct lys_ypr_ctx *ctx, int8_t *par_close_flag)
84
0
{
85
0
    if (par_close_flag && !(*par_close_flag)) {
86
0
        (*par_close_flag) = 1;
87
0
        ly_print_(ctx->out, ">\n");
88
0
    }
89
0
}
90
91
static void
92
ypr_yin_arg(struct lys_ypr_ctx *ctx, const char *arg, const char *text)
93
0
{
94
0
    ly_print_(ctx->out, "%*s<%s>", INDENT, arg);
95
0
    lyxml_dump_text(ctx->out, text, 0);
96
0
    ly_print_(ctx->out, "</%s>\n", arg);
97
0
}
98
99
static void
100
ypr_substmt(struct lys_ypr_ctx *ctx, enum ly_stmt substmt, uint8_t substmt_index, const char *text, void *ext)
101
0
{
102
0
    LY_ARRAY_COUNT_TYPE u;
103
0
    int8_t extflag = 0;
104
105
0
    if (!text) {
106
        /* nothing to print */
107
0
        return;
108
0
    }
109
110
0
    if (stmt_attr_info[substmt].flags & STMT_FLAG_YIN) {
111
0
        extflag = 1;
112
0
        ypr_open(ctx, stmt_attr_info[substmt].name, NULL, NULL, extflag);
113
0
    } else {
114
0
        ypr_open(ctx, stmt_attr_info[substmt].name, stmt_attr_info[substmt].arg, text, extflag);
115
0
    }
116
117
0
    LEVEL++;
118
0
    LY_ARRAY_FOR(ext, u) {
119
0
        if ((((struct lysp_ext_instance *)ext)[u].parent_stmt != substmt) || (((struct lysp_ext_instance *)ext)[u].parent_stmt_index != substmt_index)) {
120
0
            continue;
121
0
        }
122
0
        yprp_extension_instances(ctx, substmt, substmt_index, &((struct lysp_ext_instance *)ext)[u], &extflag, 1);
123
0
    }
124
125
    /* argument as yin-element */
126
0
    if (stmt_attr_info[substmt].flags & STMT_FLAG_YIN) {
127
0
        ypr_yin_arg(ctx, stmt_attr_info[substmt].arg, text);
128
0
    }
129
130
0
    LEVEL--;
131
0
    ypr_close(ctx, stmt_attr_info[substmt].name, extflag);
132
0
}
133
134
static void
135
ypr_unsigned(struct lys_ypr_ctx *ctx, enum ly_stmt substmt, uint8_t substmt_index, void *exts, unsigned long int attr_value)
136
0
{
137
0
    char *str;
138
139
0
    if (asprintf(&str, "%lu", attr_value) == -1) {
140
0
        LOGMEM(ctx->module->ctx);
141
0
        return;
142
0
    }
143
0
    ypr_substmt(ctx, substmt, substmt_index, str, exts);
144
0
    free(str);
145
0
}
146
147
static void
148
ypr_signed(struct lys_ypr_ctx *ctx, enum ly_stmt substmt, uint8_t substmt_index, void *exts, signed long int attr_value)
149
0
{
150
0
    char *str;
151
152
0
    if (asprintf(&str, "%ld", attr_value) == -1) {
153
0
        LOGMEM(ctx->module->ctx);
154
0
        return;
155
0
    }
156
0
    ypr_substmt(ctx, substmt, substmt_index, str, exts);
157
0
    free(str);
158
0
}
159
160
static void
161
yprp_revision(struct lys_ypr_ctx *ctx, const struct lysp_revision *rev)
162
0
{
163
0
    if (rev->dsc || rev->ref || rev->exts) {
164
0
        ypr_open(ctx, "revision", "date", rev->date, 1);
165
0
        LEVEL++;
166
0
        yprp_extension_instances(ctx, LY_STMT_REVISION, 0, rev->exts, NULL, 0);
167
0
        ypr_substmt(ctx, LY_STMT_DESCRIPTION, 0, rev->dsc, rev->exts);
168
0
        ypr_substmt(ctx, LY_STMT_REFERENCE, 0, rev->ref, rev->exts);
169
0
        LEVEL--;
170
0
        ypr_close(ctx, "revision", 1);
171
0
    } else {
172
0
        ypr_open(ctx, "revision", "date", rev->date, -1);
173
0
    }
174
0
}
175
176
static void
177
ypr_mandatory(struct lys_ypr_ctx *ctx, uint16_t flags, void *exts, int8_t *flag)
178
0
{
179
0
    if (flags & LYS_MAND_MASK) {
180
0
        ypr_close_parent(ctx, flag);
181
0
        ypr_substmt(ctx, LY_STMT_MANDATORY, 0, (flags & LYS_MAND_TRUE) ? "true" : "false", exts);
182
0
    }
183
0
}
184
185
static void
186
ypr_config(struct lys_ypr_ctx *ctx, uint16_t flags, void *exts, int8_t *flag)
187
0
{
188
0
    if (flags & LYS_CONFIG_MASK) {
189
0
        ypr_close_parent(ctx, flag);
190
0
        ypr_substmt(ctx, LY_STMT_CONFIG, 0, (flags & LYS_CONFIG_W) ? "true" : "false", exts);
191
0
    }
192
0
}
193
194
static void
195
ypr_status(struct lys_ypr_ctx *ctx, uint16_t flags, void *exts, int8_t *flag)
196
0
{
197
0
    const char *status = NULL;
198
199
0
    if (flags & LYS_STATUS_CURR) {
200
0
        ypr_close_parent(ctx, flag);
201
0
        status = "current";
202
0
    } else if (flags & LYS_STATUS_DEPRC) {
203
0
        ypr_close_parent(ctx, flag);
204
0
        status = "deprecated";
205
0
    } else if (flags & LYS_STATUS_OBSLT) {
206
0
        ypr_close_parent(ctx, flag);
207
0
        status = "obsolete";
208
0
    }
209
210
0
    ypr_substmt(ctx, LY_STMT_STATUS, 0, status, exts);
211
0
}
212
213
static void
214
ypr_description(struct lys_ypr_ctx *ctx, const char *dsc, void *exts, int8_t *flag)
215
0
{
216
0
    if (dsc) {
217
0
        ypr_close_parent(ctx, flag);
218
0
        ypr_substmt(ctx, LY_STMT_DESCRIPTION, 0, dsc, exts);
219
0
    }
220
0
}
221
222
static void
223
ypr_reference(struct lys_ypr_ctx *ctx, const char *ref, void *exts, int8_t *flag)
224
0
{
225
0
    if (ref) {
226
0
        ypr_close_parent(ctx, flag);
227
0
        ypr_substmt(ctx, LY_STMT_REFERENCE, 0, ref, exts);
228
0
    }
229
0
}
230
231
static void
232
yprp_iffeatures(struct lys_ypr_ctx *ctx, struct lysp_qname *iffs, struct lysp_ext_instance *exts, int8_t *flag)
233
0
{
234
0
    LY_ARRAY_COUNT_TYPE u, v;
235
0
    int8_t extflag;
236
237
0
    LY_ARRAY_FOR(iffs, u) {
238
0
        ypr_close_parent(ctx, flag);
239
0
        extflag = 0;
240
241
0
        ly_print_(ctx->out, "%*s<if-feature name=\"%s",  INDENT, iffs[u].str);
242
243
        /* extensions */
244
0
        LEVEL++;
245
0
        LY_ARRAY_FOR(exts, v) {
246
0
            yprp_extension_instances(ctx, LY_STMT_IF_FEATURE, u, &exts[v], &extflag, 1);
247
0
        }
248
0
        LEVEL--;
249
0
        ly_print_(ctx->out, "\"/>\n");
250
0
    }
251
0
}
252
253
static void
254
yprp_extension(struct lys_ypr_ctx *ctx, const struct lysp_ext *ext)
255
0
{
256
0
    int8_t flag = 0, flag2 = 0;
257
0
    LY_ARRAY_COUNT_TYPE u;
258
259
0
    ypr_open(ctx, "extension", "name", ext->name, flag);
260
0
    LEVEL++;
261
262
0
    if (ext->exts) {
263
0
        ypr_close_parent(ctx, &flag);
264
0
        yprp_extension_instances(ctx, LY_STMT_EXTENSION, 0, ext->exts, &flag, 0);
265
0
    }
266
267
0
    if (ext->argname) {
268
0
        ypr_close_parent(ctx, &flag);
269
0
        ypr_open(ctx, "argument", "name", ext->argname, flag2);
270
271
0
        LEVEL++;
272
0
        if (ext->exts) {
273
0
            u = -1;
274
0
            while ((u = lysp_ext_instance_iter(ext->exts, u + 1, LY_STMT_ARGUMENT)) != LY_ARRAY_COUNT(ext->exts)) {
275
0
                ypr_close_parent(ctx, &flag2);
276
0
                yprp_extension_instances(ctx, LY_STMT_ARGUMENT, 0, &ext->exts[u], &flag2, 1);
277
0
            }
278
0
        }
279
0
        if ((ext->flags & LYS_YINELEM_MASK) ||
280
0
                (ext->exts && (lysp_ext_instance_iter(ext->exts, 0, LY_STMT_YIN_ELEMENT) != LY_ARRAY_COUNT(ext->exts)))) {
281
0
            ypr_close_parent(ctx, &flag2);
282
0
            ypr_substmt(ctx, LY_STMT_YIN_ELEMENT, 0, (ext->flags & LYS_YINELEM_TRUE) ? "true" : "false", ext->exts);
283
0
        }
284
0
        LEVEL--;
285
0
        ypr_close(ctx, "argument", flag2);
286
0
    }
287
288
0
    ypr_status(ctx, ext->flags, ext->exts, &flag);
289
0
    ypr_description(ctx, ext->dsc, ext->exts, &flag);
290
0
    ypr_reference(ctx, ext->ref, ext->exts, &flag);
291
292
0
    LEVEL--;
293
0
    ypr_close(ctx, "extension", flag);
294
0
}
295
296
static void
297
yprp_feature(struct lys_ypr_ctx *ctx, const struct lysp_feature *feat)
298
0
{
299
0
    int8_t flag = 0;
300
301
0
    ypr_open(ctx, "feature", "name", feat->name, flag);
302
0
    LEVEL++;
303
0
    yprp_extension_instances(ctx, LY_STMT_FEATURE, 0, feat->exts, &flag, 0);
304
0
    yprp_iffeatures(ctx, feat->iffeatures, feat->exts, &flag);
305
0
    ypr_status(ctx, feat->flags, feat->exts, &flag);
306
0
    ypr_description(ctx, feat->dsc, feat->exts, &flag);
307
0
    ypr_reference(ctx, feat->ref, feat->exts, &flag);
308
0
    LEVEL--;
309
0
    ypr_close(ctx, "feature", flag);
310
0
}
311
312
static void
313
yprp_identity(struct lys_ypr_ctx *ctx, const struct lysp_ident *ident)
314
0
{
315
0
    int8_t flag = 0;
316
0
    LY_ARRAY_COUNT_TYPE u;
317
318
0
    ypr_open(ctx, "identity", "name", ident->name, flag);
319
0
    LEVEL++;
320
321
0
    yprp_extension_instances(ctx, LY_STMT_IDENTITY, 0, ident->exts, &flag, 0);
322
0
    yprp_iffeatures(ctx, ident->iffeatures, ident->exts, &flag);
323
324
0
    LY_ARRAY_FOR(ident->bases, u) {
325
0
        ypr_close_parent(ctx, &flag);
326
0
        ypr_substmt(ctx, LY_STMT_BASE, u, ident->bases[u], ident->exts);
327
0
    }
328
329
0
    ypr_status(ctx, ident->flags, ident->exts, &flag);
330
0
    ypr_description(ctx, ident->dsc, ident->exts, &flag);
331
0
    ypr_reference(ctx, ident->ref, ident->exts, &flag);
332
333
0
    LEVEL--;
334
0
    ypr_close(ctx, "identity", flag);
335
0
}
336
337
static void
338
yprp_restr(struct lys_ypr_ctx *ctx, const struct lysp_restr *restr, enum ly_stmt stmt, const char *attr, int8_t *flag)
339
0
{
340
0
    (void)flag;
341
0
    int8_t inner_flag = 0;
342
343
0
    if (!restr) {
344
0
        return;
345
0
    }
346
347
0
    ly_print_(ctx->out, "%*s<%s %s=\"", INDENT, ly_stmt2str(stmt), attr);
348
0
    lyxml_dump_text(ctx->out,
349
0
            (restr->arg.str[0] != LYSP_RESTR_PATTERN_NACK && restr->arg.str[0] != LYSP_RESTR_PATTERN_ACK) ?
350
0
            restr->arg.str : &restr->arg.str[1], 1);
351
0
    ly_print_(ctx->out, "\"");
352
353
0
    LEVEL++;
354
0
    yprp_extension_instances(ctx, stmt, 0, restr->exts, &inner_flag, 0);
355
0
    if (restr->arg.str[0] == LYSP_RESTR_PATTERN_NACK) {
356
0
        ypr_close_parent(ctx, &inner_flag);
357
        /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
358
0
        ypr_substmt(ctx, LY_STMT_MODIFIER, 0, "invert-match", restr->exts);
359
0
    }
360
0
    if (restr->emsg) {
361
0
        ypr_close_parent(ctx, &inner_flag);
362
0
        ypr_substmt(ctx, LY_STMT_ERROR_MESSAGE, 0, restr->emsg, restr->exts);
363
0
    }
364
0
    if (restr->eapptag) {
365
0
        ypr_close_parent(ctx, &inner_flag);
366
0
        ypr_substmt(ctx, LY_STMT_ERROR_APP_TAG, 0, restr->eapptag, restr->exts);
367
0
    }
368
0
    ypr_description(ctx, restr->dsc, restr->exts, &inner_flag);
369
0
    ypr_reference(ctx, restr->ref, restr->exts, &inner_flag);
370
371
0
    LEVEL--;
372
0
    ypr_close(ctx, ly_stmt2str(stmt), inner_flag);
373
0
}
374
375
static void
376
yprp_when(struct lys_ypr_ctx *ctx, struct lysp_when *when, int8_t *flag)
377
0
{
378
0
    int8_t inner_flag = 0;
379
380
0
    (void)flag;
381
382
0
    if (!when) {
383
0
        return;
384
0
    }
385
386
0
    ly_print_(ctx->out, "%*s<when condition=\"", INDENT);
387
0
    lyxml_dump_text(ctx->out, when->cond, 1);
388
0
    ly_print_(ctx->out, "\"");
389
390
0
    LEVEL++;
391
0
    yprp_extension_instances(ctx, LY_STMT_WHEN, 0, when->exts, &inner_flag, 0);
392
0
    ypr_description(ctx, when->dsc, when->exts, &inner_flag);
393
0
    ypr_reference(ctx, when->ref, when->exts, &inner_flag);
394
0
    LEVEL--;
395
0
    ypr_close(ctx, "when", inner_flag);
396
0
}
397
398
static void
399
yprp_enum(struct lys_ypr_ctx *ctx, const struct lysp_type_enum *items, LY_DATA_TYPE type, int8_t *flag)
400
0
{
401
0
    LY_ARRAY_COUNT_TYPE u;
402
0
    int8_t inner_flag;
403
404
0
    (void)flag;
405
406
0
    LY_ARRAY_FOR(items, u) {
407
0
        if (type == LY_TYPE_BITS) {
408
0
            ly_print_(ctx->out, "%*s<bit name=\"", INDENT);
409
0
            lyxml_dump_text(ctx->out, items[u].name, 1);
410
0
            ly_print_(ctx->out, "\"");
411
0
        } else { /* LY_TYPE_ENUM */
412
0
            ly_print_(ctx->out, "%*s<enum name=\"", INDENT);
413
0
            lyxml_dump_text(ctx->out, items[u].name, 1);
414
0
            ly_print_(ctx->out, "\"");
415
0
        }
416
0
        inner_flag = 0;
417
0
        LEVEL++;
418
0
        yprp_extension_instances(ctx, LY_STMT_ENUM, 0, items[u].exts, &inner_flag, 0);
419
0
        yprp_iffeatures(ctx, items[u].iffeatures, items[u].exts, &inner_flag);
420
0
        if (items[u].flags & LYS_SET_VALUE) {
421
0
            if (type == LY_TYPE_BITS) {
422
0
                ypr_close_parent(ctx, &inner_flag);
423
0
                ypr_unsigned(ctx, LY_STMT_POSITION, 0, items[u].exts, items[u].value);
424
0
            } else { /* LY_TYPE_ENUM */
425
0
                ypr_close_parent(ctx, &inner_flag);
426
0
                ypr_signed(ctx, LY_STMT_VALUE, 0, items[u].exts, items[u].value);
427
0
            }
428
0
        }
429
0
        ypr_status(ctx, items[u].flags, items[u].exts, &inner_flag);
430
0
        ypr_description(ctx, items[u].dsc, items[u].exts, &inner_flag);
431
0
        ypr_reference(ctx, items[u].ref, items[u].exts, &inner_flag);
432
0
        LEVEL--;
433
0
        ypr_close(ctx, type == LY_TYPE_BITS ? "bit" : "enum", inner_flag);
434
0
    }
435
0
}
436
437
static void
438
yprp_type(struct lys_ypr_ctx *ctx, const struct lysp_type *type)
439
0
{
440
0
    LY_ARRAY_COUNT_TYPE u;
441
0
    int8_t flag = 0;
442
443
0
    if (!ctx || !type) {
444
0
        return;
445
0
    }
446
447
0
    ypr_open(ctx, "type", "name", type->name, flag);
448
0
    LEVEL++;
449
450
0
    yprp_extension_instances(ctx, LY_STMT_TYPE, 0, type->exts, &flag, 0);
451
452
0
    if (type->range || type->length || type->patterns || type->bits || type->enums) {
453
0
        ypr_close_parent(ctx, &flag);
454
0
    }
455
0
    yprp_restr(ctx, type->range, LY_STMT_RANGE, "value", &flag);
456
0
    yprp_restr(ctx, type->length, LY_STMT_LENGTH, "value", &flag);
457
0
    LY_ARRAY_FOR(type->patterns, u) {
458
0
        yprp_restr(ctx, &type->patterns[u], LY_STMT_PATTERN, "value", &flag);
459
0
    }
460
0
    yprp_enum(ctx, type->bits, LY_TYPE_BITS, &flag);
461
0
    yprp_enum(ctx, type->enums, LY_TYPE_ENUM, &flag);
462
463
0
    if (type->path) {
464
0
        ypr_close_parent(ctx, &flag);
465
0
        ypr_substmt(ctx, LY_STMT_PATH, 0, type->path->expr, type->exts);
466
0
    }
467
0
    if (type->flags & LYS_SET_REQINST) {
468
0
        ypr_close_parent(ctx, &flag);
469
0
        ypr_substmt(ctx, LY_STMT_REQUIRE_INSTANCE, 0, type->require_instance ? "true" : "false", type->exts);
470
0
    }
471
0
    if (type->flags & LYS_SET_FRDIGITS) {
472
0
        ypr_close_parent(ctx, &flag);
473
0
        ypr_unsigned(ctx, LY_STMT_FRACTION_DIGITS, 0, type->exts, type->fraction_digits);
474
0
    }
475
0
    LY_ARRAY_FOR(type->bases, u) {
476
0
        ypr_close_parent(ctx, &flag);
477
0
        ypr_substmt(ctx, LY_STMT_BASE, u, type->bases[u], type->exts);
478
0
    }
479
0
    LY_ARRAY_FOR(type->types, u) {
480
0
        ypr_close_parent(ctx, &flag);
481
0
        yprp_type(ctx, &type->types[u]);
482
0
    }
483
484
0
    LEVEL--;
485
0
    ypr_close(ctx, "type", flag);
486
0
}
487
488
static void
489
yprp_typedef(struct lys_ypr_ctx *ctx, const struct lysp_tpdf *tpdf)
490
0
{
491
0
    ypr_open(ctx, "typedef", "name", tpdf->name, 1);
492
0
    LEVEL++;
493
494
0
    yprp_extension_instances(ctx, LY_STMT_TYPEDEF, 0, tpdf->exts, NULL, 0);
495
496
0
    yprp_type(ctx, &tpdf->type);
497
498
0
    if (tpdf->units) {
499
0
        ypr_substmt(ctx, LY_STMT_UNITS, 0, tpdf->units, tpdf->exts);
500
0
    }
501
0
    if (tpdf->dflt.str) {
502
0
        ypr_substmt(ctx, LY_STMT_DEFAULT, 0, tpdf->dflt.str, tpdf->exts);
503
0
    }
504
505
0
    ypr_status(ctx, tpdf->flags, tpdf->exts, NULL);
506
0
    ypr_description(ctx, tpdf->dsc, tpdf->exts, NULL);
507
0
    ypr_reference(ctx, tpdf->ref, tpdf->exts, NULL);
508
509
0
    LEVEL--;
510
0
    ypr_close(ctx, "typedef", 1);
511
0
}
512
513
static void yprp_node(struct lys_ypr_ctx *ctx, const struct lysp_node *node);
514
static void yprp_action(struct lys_ypr_ctx *ctx, const struct lysp_node_action *action);
515
static void yprp_notification(struct lys_ypr_ctx *ctx, const struct lysp_node_notif *notif);
516
517
static void
518
yprp_grouping(struct lys_ypr_ctx *ctx, const struct lysp_node_grp *grp)
519
0
{
520
0
    LY_ARRAY_COUNT_TYPE u;
521
0
    int8_t flag = 0;
522
0
    struct lysp_node *data;
523
0
    struct lysp_node_action *action;
524
0
    struct lysp_node_notif *notif;
525
0
    struct lysp_node_grp *subgrp;
526
527
0
    ypr_open(ctx, "grouping", "name", grp->name, flag);
528
0
    LEVEL++;
529
530
0
    yprp_extension_instances(ctx, LY_STMT_GROUPING, 0, grp->exts, &flag, 0);
531
0
    ypr_status(ctx, grp->flags, grp->exts, &flag);
532
0
    ypr_description(ctx, grp->dsc, grp->exts, &flag);
533
0
    ypr_reference(ctx, grp->ref, grp->exts, &flag);
534
535
0
    LY_ARRAY_FOR(grp->typedefs, u) {
536
0
        ypr_close_parent(ctx, &flag);
537
0
        yprp_typedef(ctx, &grp->typedefs[u]);
538
0
    }
539
540
0
    LY_LIST_FOR(grp->groupings, subgrp) {
541
0
        ypr_close_parent(ctx, &flag);
542
0
        yprp_grouping(ctx, subgrp);
543
0
    }
544
545
0
    LY_LIST_FOR(grp->child, data) {
546
0
        ypr_close_parent(ctx, &flag);
547
0
        yprp_node(ctx, data);
548
0
    }
549
550
0
    LY_LIST_FOR(grp->actions, action) {
551
0
        ypr_close_parent(ctx, &flag);
552
0
        yprp_action(ctx, action);
553
0
    }
554
555
0
    LY_LIST_FOR(grp->notifs, notif) {
556
0
        ypr_close_parent(ctx, &flag);
557
0
        yprp_notification(ctx, notif);
558
0
    }
559
560
0
    LEVEL--;
561
0
    ypr_close(ctx, "grouping", flag);
562
0
}
563
564
static void
565
yprp_inout(struct lys_ypr_ctx *ctx, const struct lysp_node_action_inout *inout, int8_t *flag)
566
0
{
567
0
    LY_ARRAY_COUNT_TYPE u;
568
0
    struct lysp_node *data;
569
0
    struct lysp_node_grp *grp;
570
571
0
    if (!inout->child) {
572
        /* input/output is empty */
573
0
        return;
574
0
    }
575
0
    ypr_close_parent(ctx, flag);
576
577
0
    ypr_open(ctx, inout->name, NULL, NULL, *flag);
578
0
    LEVEL++;
579
580
0
    yprp_extension_instances(ctx, lys_nodetype2stmt(inout->nodetype), 0, inout->exts, NULL, 0);
581
0
    LY_ARRAY_FOR(inout->musts, u) {
582
0
        yprp_restr(ctx, &inout->musts[u], LY_STMT_MUST, "condition", NULL);
583
0
    }
584
0
    LY_ARRAY_FOR(inout->typedefs, u) {
585
0
        yprp_typedef(ctx, &inout->typedefs[u]);
586
0
    }
587
0
    LY_LIST_FOR(inout->groupings, grp) {
588
0
        yprp_grouping(ctx, grp);
589
0
    }
590
591
0
    LY_LIST_FOR(inout->child, data) {
592
0
        yprp_node(ctx, data);
593
0
    }
594
595
0
    LEVEL--;
596
0
    ypr_close(ctx, inout->name, 1);
597
0
}
598
599
static void
600
yprp_notification(struct lys_ypr_ctx *ctx, const struct lysp_node_notif *notif)
601
0
{
602
0
    LY_ARRAY_COUNT_TYPE u;
603
0
    int8_t flag = 0;
604
0
    struct lysp_node *data;
605
0
    struct lysp_node_grp *grp;
606
607
0
    ypr_open(ctx, "notification", "name", notif->name, flag);
608
609
0
    LEVEL++;
610
0
    yprp_extension_instances(ctx, LY_STMT_NOTIFICATION, 0, notif->exts, &flag, 0);
611
0
    yprp_iffeatures(ctx, notif->iffeatures, notif->exts, &flag);
612
613
0
    LY_ARRAY_FOR(notif->musts, u) {
614
0
        ypr_close_parent(ctx, &flag);
615
0
        yprp_restr(ctx, &notif->musts[u], LY_STMT_MUST, "condition", &flag);
616
0
    }
617
0
    ypr_status(ctx, notif->flags, notif->exts, &flag);
618
0
    ypr_description(ctx, notif->dsc, notif->exts, &flag);
619
0
    ypr_reference(ctx, notif->ref, notif->exts, &flag);
620
621
0
    LY_ARRAY_FOR(notif->typedefs, u) {
622
0
        ypr_close_parent(ctx, &flag);
623
0
        yprp_typedef(ctx, &notif->typedefs[u]);
624
0
    }
625
626
0
    LY_LIST_FOR(notif->groupings, grp) {
627
0
        ypr_close_parent(ctx, &flag);
628
0
        yprp_grouping(ctx, grp);
629
0
    }
630
631
0
    LY_LIST_FOR(notif->child, data) {
632
0
        ypr_close_parent(ctx, &flag);
633
0
        yprp_node(ctx, data);
634
0
    }
635
636
0
    LEVEL--;
637
0
    ypr_close(ctx, "notification", flag);
638
0
}
639
640
static void
641
yprp_action(struct lys_ypr_ctx *ctx, const struct lysp_node_action *action)
642
0
{
643
0
    LY_ARRAY_COUNT_TYPE u;
644
0
    int8_t flag = 0;
645
0
    struct lysp_node_grp *grp;
646
647
0
    ypr_open(ctx, action->parent ? "action" : "rpc", "name", action->name, flag);
648
649
0
    LEVEL++;
650
0
    yprp_extension_instances(ctx, lys_nodetype2stmt(action->nodetype), 0, action->exts, &flag, 0);
651
0
    yprp_iffeatures(ctx, action->iffeatures, action->exts, &flag);
652
0
    ypr_status(ctx, action->flags, action->exts, &flag);
653
0
    ypr_description(ctx, action->dsc, action->exts, &flag);
654
0
    ypr_reference(ctx, action->ref, action->exts, &flag);
655
656
0
    LY_ARRAY_FOR(action->typedefs, u) {
657
0
        ypr_close_parent(ctx, &flag);
658
0
        yprp_typedef(ctx, &action->typedefs[u]);
659
0
    }
660
661
0
    LY_LIST_FOR(action->groupings, grp) {
662
0
        ypr_close_parent(ctx, &flag);
663
0
        yprp_grouping(ctx, grp);
664
0
    }
665
666
0
    yprp_inout(ctx, &action->input, &flag);
667
0
    yprp_inout(ctx, &action->output, &flag);
668
669
0
    LEVEL--;
670
0
    ypr_close(ctx, action->parent ? "action" : "rpc", flag);
671
0
}
672
673
static void
674
yprp_node_common1(struct lys_ypr_ctx *ctx, const struct lysp_node *node, int8_t *flag)
675
0
{
676
0
    ypr_open(ctx, lys_nodetype2str(node->nodetype), "name", node->name, *flag);
677
0
    LEVEL++;
678
679
0
    yprp_extension_instances(ctx, lys_nodetype2stmt(node->nodetype), 0, node->exts, flag, 0);
680
0
    yprp_when(ctx, lysp_node_when(node), flag);
681
0
    yprp_iffeatures(ctx, node->iffeatures, node->exts, flag);
682
0
}
683
684
static void
685
yprp_node_common2(struct lys_ypr_ctx *ctx, const struct lysp_node *node, int8_t *flag)
686
0
{
687
0
    ypr_config(ctx, node->flags, node->exts, flag);
688
0
    if (node->nodetype & (LYS_CHOICE | LYS_LEAF | LYS_ANYDATA)) {
689
0
        ypr_mandatory(ctx, node->flags, node->exts, flag);
690
0
    }
691
0
    ypr_status(ctx, node->flags, node->exts, flag);
692
0
    ypr_description(ctx, node->dsc, node->exts, flag);
693
0
    ypr_reference(ctx, node->ref, node->exts, flag);
694
0
}
695
696
static void
697
yprp_container(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
698
0
{
699
0
    LY_ARRAY_COUNT_TYPE u;
700
0
    int8_t flag = 0;
701
0
    struct lysp_node *child;
702
0
    struct lysp_node_action *action;
703
0
    struct lysp_node_notif *notif;
704
0
    struct lysp_node_grp *grp;
705
0
    struct lysp_node_container *cont = (struct lysp_node_container *)node;
706
707
0
    yprp_node_common1(ctx, node, &flag);
708
709
0
    LY_ARRAY_FOR(cont->musts, u) {
710
0
        ypr_close_parent(ctx, &flag);
711
0
        yprp_restr(ctx, &cont->musts[u], LY_STMT_MUST, "condition", &flag);
712
0
    }
713
0
    if (cont->presence) {
714
0
        ypr_close_parent(ctx, &flag);
715
0
        ypr_substmt(ctx, LY_STMT_PRESENCE, 0, cont->presence, cont->exts);
716
0
    }
717
718
0
    yprp_node_common2(ctx, node, &flag);
719
720
0
    LY_ARRAY_FOR(cont->typedefs, u) {
721
0
        ypr_close_parent(ctx, &flag);
722
0
        yprp_typedef(ctx, &cont->typedefs[u]);
723
0
    }
724
725
0
    LY_LIST_FOR(cont->groupings, grp) {
726
0
        ypr_close_parent(ctx, &flag);
727
0
        yprp_grouping(ctx, grp);
728
0
    }
729
730
0
    LY_LIST_FOR(cont->child, child) {
731
0
        ypr_close_parent(ctx, &flag);
732
0
        yprp_node(ctx, child);
733
0
    }
734
735
0
    LY_LIST_FOR(cont->actions, action) {
736
0
        ypr_close_parent(ctx, &flag);
737
0
        yprp_action(ctx, action);
738
0
    }
739
740
0
    LY_LIST_FOR(cont->notifs, notif) {
741
0
        ypr_close_parent(ctx, &flag);
742
0
        yprp_notification(ctx, notif);
743
0
    }
744
745
0
    LEVEL--;
746
0
    ypr_close(ctx, "container", flag);
747
0
}
748
749
static void
750
yprp_case(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
751
0
{
752
0
    int8_t flag = 0;
753
0
    struct lysp_node *child;
754
0
    struct lysp_node_case *cas = (struct lysp_node_case *)node;
755
756
0
    yprp_node_common1(ctx, node, &flag);
757
0
    yprp_node_common2(ctx, node, &flag);
758
759
0
    LY_LIST_FOR(cas->child, child) {
760
0
        ypr_close_parent(ctx, &flag);
761
0
        yprp_node(ctx, child);
762
0
    }
763
764
0
    LEVEL--;
765
0
    ypr_close(ctx, "case", flag);
766
0
}
767
768
static void
769
yprp_choice(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
770
0
{
771
0
    int8_t flag = 0;
772
0
    struct lysp_node *child;
773
0
    struct lysp_node_choice *choice = (struct lysp_node_choice *)node;
774
775
0
    yprp_node_common1(ctx, node, &flag);
776
777
0
    if (choice->dflt.str) {
778
0
        ypr_close_parent(ctx, &flag);
779
0
        ypr_substmt(ctx, LY_STMT_DEFAULT, 0, choice->dflt.str, choice->exts);
780
0
    }
781
782
0
    yprp_node_common2(ctx, node, &flag);
783
784
0
    LY_LIST_FOR(choice->child, child) {
785
0
        ypr_close_parent(ctx, &flag);
786
0
        yprp_node(ctx, child);
787
0
    }
788
789
0
    LEVEL--;
790
0
    ypr_close(ctx, "choice", flag);
791
0
}
792
793
static void
794
yprp_leaf(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
795
0
{
796
0
    LY_ARRAY_COUNT_TYPE u;
797
0
    struct lysp_node_leaf *leaf = (struct lysp_node_leaf *)node;
798
799
0
    int8_t flag = 1;
800
801
0
    yprp_node_common1(ctx, node, &flag);
802
803
0
    yprp_type(ctx, &leaf->type);
804
0
    ypr_substmt(ctx, LY_STMT_UNITS, 0, leaf->units, leaf->exts);
805
0
    LY_ARRAY_FOR(leaf->musts, u) {
806
0
        yprp_restr(ctx, &leaf->musts[u], LY_STMT_MUST, "condition", &flag);
807
0
    }
808
0
    ypr_substmt(ctx, LY_STMT_DEFAULT, 0, leaf->dflt.str, leaf->exts);
809
810
0
    yprp_node_common2(ctx, node, &flag);
811
812
0
    LEVEL--;
813
0
    ypr_close(ctx, "leaf", flag);
814
0
}
815
816
static void
817
yprp_leaflist(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
818
0
{
819
0
    LY_ARRAY_COUNT_TYPE u;
820
0
    struct lysp_node_leaflist *llist = (struct lysp_node_leaflist *)node;
821
0
    int8_t flag = 1;
822
823
0
    yprp_node_common1(ctx, node, &flag);
824
825
0
    yprp_type(ctx, &llist->type);
826
0
    ypr_substmt(ctx, LY_STMT_UNITS, 0, llist->units, llist->exts);
827
0
    LY_ARRAY_FOR(llist->musts, u) {
828
0
        yprp_restr(ctx, &llist->musts[u], LY_STMT_MUST, "condition", NULL);
829
0
    }
830
0
    LY_ARRAY_FOR(llist->dflts, u) {
831
0
        ypr_substmt(ctx, LY_STMT_DEFAULT, u, llist->dflts[u].str, llist->exts);
832
0
    }
833
834
0
    ypr_config(ctx, node->flags, node->exts, NULL);
835
836
0
    if (llist->flags & LYS_SET_MIN) {
837
0
        ypr_unsigned(ctx, LY_STMT_MIN_ELEMENTS, 0, llist->exts, llist->min);
838
0
    }
839
0
    if (llist->flags & LYS_SET_MAX) {
840
0
        if (llist->max) {
841
0
            ypr_unsigned(ctx, LY_STMT_MAX_ELEMENTS, 0, llist->exts, llist->max);
842
0
        } else {
843
0
            ypr_substmt(ctx, LY_STMT_MAX_ELEMENTS, 0, "unbounded", llist->exts);
844
0
        }
845
0
    }
846
847
0
    if (llist->flags & LYS_ORDBY_MASK) {
848
0
        ypr_substmt(ctx, LY_STMT_ORDERED_BY, 0, (llist->flags & LYS_ORDBY_USER) ? "user" : "system", llist->exts);
849
0
    }
850
851
0
    ypr_status(ctx, node->flags, node->exts, &flag);
852
0
    ypr_description(ctx, node->dsc, node->exts, &flag);
853
0
    ypr_reference(ctx, node->ref, node->exts, &flag);
854
855
0
    LEVEL--;
856
0
    ypr_close(ctx, "leaf-list", flag);
857
0
}
858
859
static void
860
yprp_list(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
861
0
{
862
0
    LY_ARRAY_COUNT_TYPE u;
863
0
    int8_t flag = 0;
864
0
    struct lysp_node *child;
865
0
    struct lysp_node_action *action;
866
0
    struct lysp_node_notif *notif;
867
0
    struct lysp_node_grp *grp;
868
0
    struct lysp_node_list *list = (struct lysp_node_list *)node;
869
870
0
    yprp_node_common1(ctx, node, &flag);
871
872
0
    LY_ARRAY_FOR(list->musts, u) {
873
0
        ypr_close_parent(ctx, &flag);
874
0
        yprp_restr(ctx, &list->musts[u], LY_STMT_MUST, "condition", &flag);
875
0
    }
876
0
    if (list->key) {
877
0
        ypr_close_parent(ctx, &flag);
878
0
        ypr_substmt(ctx, LY_STMT_KEY, 0, list->key, list->exts);
879
0
    }
880
0
    LY_ARRAY_FOR(list->uniques, u) {
881
0
        ypr_close_parent(ctx, &flag);
882
0
        ypr_substmt(ctx, LY_STMT_UNIQUE, u, list->uniques[u].str, list->exts);
883
0
    }
884
885
0
    ypr_config(ctx, node->flags, node->exts, NULL);
886
887
0
    if (list->flags & LYS_SET_MIN) {
888
0
        ypr_unsigned(ctx, LY_STMT_MIN_ELEMENTS, 0, list->exts, list->min);
889
0
    }
890
0
    if (list->flags & LYS_SET_MAX) {
891
0
        if (list->max) {
892
0
            ypr_unsigned(ctx, LY_STMT_MAX_ELEMENTS, 0, list->exts, list->max);
893
0
        } else {
894
0
            ypr_substmt(ctx, LY_STMT_MAX_ELEMENTS, 0, "unbounded", list->exts);
895
0
        }
896
0
    }
897
898
0
    if (list->flags & LYS_ORDBY_MASK) {
899
0
        ypr_close_parent(ctx, &flag);
900
0
        ypr_substmt(ctx, LY_STMT_ORDERED_BY, 0, (list->flags & LYS_ORDBY_USER) ? "user" : "system", list->exts);
901
0
    }
902
903
0
    ypr_status(ctx, node->flags, node->exts, &flag);
904
0
    ypr_description(ctx, node->dsc, node->exts, &flag);
905
0
    ypr_reference(ctx, node->ref, node->exts, &flag);
906
907
0
    LY_ARRAY_FOR(list->typedefs, u) {
908
0
        ypr_close_parent(ctx, &flag);
909
0
        yprp_typedef(ctx, &list->typedefs[u]);
910
0
    }
911
912
0
    LY_LIST_FOR(list->groupings, grp) {
913
0
        ypr_close_parent(ctx, &flag);
914
0
        yprp_grouping(ctx, grp);
915
0
    }
916
917
0
    LY_LIST_FOR(list->child, child) {
918
0
        ypr_close_parent(ctx, &flag);
919
0
        yprp_node(ctx, child);
920
0
    }
921
922
0
    LY_LIST_FOR(list->actions, action) {
923
0
        ypr_close_parent(ctx, &flag);
924
0
        yprp_action(ctx, action);
925
0
    }
926
927
0
    LY_LIST_FOR(list->notifs, notif) {
928
0
        ypr_close_parent(ctx, &flag);
929
0
        yprp_notification(ctx, notif);
930
0
    }
931
932
0
    LEVEL--;
933
0
    ypr_close(ctx, "list", flag);
934
0
}
935
936
static void
937
yprp_refine(struct lys_ypr_ctx *ctx, struct lysp_refine *refine)
938
0
{
939
0
    LY_ARRAY_COUNT_TYPE u;
940
0
    int8_t flag = 0;
941
942
0
    ypr_open(ctx, "refine", "target-node", refine->nodeid, flag);
943
0
    LEVEL++;
944
945
0
    yprp_extension_instances(ctx, LY_STMT_REFINE, 0, refine->exts, &flag, 0);
946
0
    yprp_iffeatures(ctx, refine->iffeatures, refine->exts, &flag);
947
948
0
    LY_ARRAY_FOR(refine->musts, u) {
949
0
        ypr_close_parent(ctx, &flag);
950
0
        yprp_restr(ctx, &refine->musts[u], LY_STMT_MUST, "condition", &flag);
951
0
    }
952
953
0
    if (refine->presence) {
954
0
        ypr_close_parent(ctx, &flag);
955
0
        ypr_substmt(ctx, LY_STMT_PRESENCE, 0, refine->presence, refine->exts);
956
0
    }
957
958
0
    LY_ARRAY_FOR(refine->dflts, u) {
959
0
        ypr_close_parent(ctx, &flag);
960
0
        ypr_substmt(ctx, LY_STMT_DEFAULT, u, refine->dflts[u].str, refine->exts);
961
0
    }
962
963
0
    ypr_config(ctx, refine->flags, refine->exts, &flag);
964
0
    ypr_mandatory(ctx, refine->flags, refine->exts, &flag);
965
966
0
    if (refine->flags & LYS_SET_MIN) {
967
0
        ypr_close_parent(ctx, &flag);
968
0
        ypr_unsigned(ctx, LY_STMT_MIN_ELEMENTS, 0, refine->exts, refine->min);
969
0
    }
970
0
    if (refine->flags & LYS_SET_MAX) {
971
0
        ypr_close_parent(ctx, &flag);
972
0
        if (refine->max) {
973
0
            ypr_unsigned(ctx, LY_STMT_MAX_ELEMENTS, 0, refine->exts, refine->max);
974
0
        } else {
975
0
            ypr_substmt(ctx, LY_STMT_MAX_ELEMENTS, 0, "unbounded", refine->exts);
976
0
        }
977
0
    }
978
979
0
    ypr_description(ctx, refine->dsc, refine->exts, &flag);
980
0
    ypr_reference(ctx, refine->ref, refine->exts, &flag);
981
982
0
    LEVEL--;
983
0
    ypr_close(ctx, "refine", flag);
984
0
}
985
986
static void
987
yprp_augment(struct lys_ypr_ctx *ctx, const struct lysp_node_augment *aug)
988
0
{
989
0
    struct lysp_node *child;
990
0
    struct lysp_node_action *action;
991
0
    struct lysp_node_notif *notif;
992
993
0
    ypr_open(ctx, "augment", "target-node", aug->nodeid, 1);
994
0
    LEVEL++;
995
996
0
    yprp_extension_instances(ctx, LY_STMT_AUGMENT, 0, aug->exts, NULL, 0);
997
0
    yprp_when(ctx, aug->when, NULL);
998
0
    yprp_iffeatures(ctx, aug->iffeatures, aug->exts, NULL);
999
0
    ypr_status(ctx, aug->flags, aug->exts, NULL);
1000
0
    ypr_description(ctx, aug->dsc, aug->exts, NULL);
1001
0
    ypr_reference(ctx, aug->ref, aug->exts, NULL);
1002
1003
0
    LY_LIST_FOR(aug->child, child) {
1004
0
        yprp_node(ctx, child);
1005
0
    }
1006
1007
0
    LY_LIST_FOR(aug->actions, action) {
1008
0
        yprp_action(ctx, action);
1009
0
    }
1010
1011
0
    LY_LIST_FOR(aug->notifs, notif) {
1012
0
        yprp_notification(ctx, notif);
1013
0
    }
1014
1015
0
    LEVEL--;
1016
0
    ypr_close(ctx, "augment", 1);
1017
0
}
1018
1019
static void
1020
yprp_uses(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
1021
0
{
1022
0
    LY_ARRAY_COUNT_TYPE u;
1023
0
    int8_t flag = 0;
1024
0
    struct lysp_node_uses *uses = (struct lysp_node_uses *)node;
1025
0
    struct lysp_node_augment *aug;
1026
1027
0
    yprp_node_common1(ctx, node, &flag);
1028
0
    yprp_node_common2(ctx, node, &flag);
1029
1030
0
    LY_ARRAY_FOR(uses->refines, u) {
1031
0
        ypr_close_parent(ctx, &flag);
1032
0
        yprp_refine(ctx, &uses->refines[u]);
1033
0
    }
1034
1035
0
    LY_LIST_FOR(uses->augments, aug) {
1036
0
        ypr_close_parent(ctx, &flag);
1037
0
        yprp_augment(ctx, aug);
1038
0
    }
1039
1040
0
    LEVEL--;
1041
0
    ypr_close(ctx, "uses", flag);
1042
0
}
1043
1044
static void
1045
yprp_anydata(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
1046
0
{
1047
0
    LY_ARRAY_COUNT_TYPE u;
1048
0
    int8_t flag = 0;
1049
0
    struct lysp_node_anydata *any = (struct lysp_node_anydata *)node;
1050
1051
0
    yprp_node_common1(ctx, node, &flag);
1052
1053
0
    LY_ARRAY_FOR(any->musts, u) {
1054
0
        ypr_close_parent(ctx, &flag);
1055
0
        yprp_restr(ctx, &any->musts[u], LY_STMT_MUST, "condition", &flag);
1056
0
    }
1057
1058
0
    yprp_node_common2(ctx, node, &flag);
1059
1060
0
    LEVEL--;
1061
0
    ypr_close(ctx, lys_nodetype2str(node->nodetype), flag);
1062
0
}
1063
1064
static void
1065
yprp_node(struct lys_ypr_ctx *ctx, const struct lysp_node *node)
1066
0
{
1067
0
    switch (node->nodetype) {
1068
0
    case LYS_CONTAINER:
1069
0
        yprp_container(ctx, node);
1070
0
        break;
1071
0
    case LYS_CHOICE:
1072
0
        yprp_choice(ctx, node);
1073
0
        break;
1074
0
    case LYS_LEAF:
1075
0
        yprp_leaf(ctx, node);
1076
0
        break;
1077
0
    case LYS_LEAFLIST:
1078
0
        yprp_leaflist(ctx, node);
1079
0
        break;
1080
0
    case LYS_LIST:
1081
0
        yprp_list(ctx, node);
1082
0
        break;
1083
0
    case LYS_USES:
1084
0
        yprp_uses(ctx, node);
1085
0
        break;
1086
0
    case LYS_ANYXML:
1087
0
    case LYS_ANYDATA:
1088
0
        yprp_anydata(ctx, node);
1089
0
        break;
1090
0
    case LYS_CASE:
1091
0
        yprp_case(ctx, node);
1092
0
        break;
1093
0
    default:
1094
0
        break;
1095
0
    }
1096
0
}
1097
1098
static void
1099
yprp_deviation(struct lys_ypr_ctx *ctx, const struct lysp_deviation *deviation)
1100
0
{
1101
0
    LY_ARRAY_COUNT_TYPE u;
1102
0
    struct lysp_deviate_add *add;
1103
0
    struct lysp_deviate_rpl *rpl;
1104
0
    struct lysp_deviate_del *del;
1105
0
    struct lysp_deviate *elem;
1106
1107
0
    ypr_open(ctx, "deviation", "target-node", deviation->nodeid, 1);
1108
0
    LEVEL++;
1109
1110
0
    yprp_extension_instances(ctx, LY_STMT_DEVIATION, 0, deviation->exts, NULL, 0);
1111
0
    ypr_description(ctx, deviation->dsc, deviation->exts, NULL);
1112
0
    ypr_reference(ctx, deviation->ref, deviation->exts, NULL);
1113
1114
0
    LY_LIST_FOR(deviation->deviates, elem) {
1115
0
        ly_print_(ctx->out, "%*s<deviate value=\"", INDENT);
1116
0
        if (elem->mod == LYS_DEV_NOT_SUPPORTED) {
1117
0
            if (elem->exts) {
1118
0
                ly_print_(ctx->out, "not-supported\"/>\n");
1119
0
                LEVEL++;
1120
1121
0
                yprp_extension_instances(ctx, LY_STMT_DEVIATE, 0, elem->exts, NULL, 0);
1122
0
            } else {
1123
0
                ly_print_(ctx->out, "not-supported\"/>\n");
1124
0
                continue;
1125
0
            }
1126
0
        } else if (elem->mod == LYS_DEV_ADD) {
1127
0
            add = (struct lysp_deviate_add *)elem;
1128
0
            ly_print_(ctx->out, "add\">\n");
1129
0
            LEVEL++;
1130
1131
0
            yprp_extension_instances(ctx, LY_STMT_DEVIATE, 0, add->exts, NULL, 0);
1132
0
            ypr_substmt(ctx, LY_STMT_UNITS, 0, add->units, add->exts);
1133
0
            LY_ARRAY_FOR(add->musts, u) {
1134
0
                yprp_restr(ctx, &add->musts[u], LY_STMT_MUST, "condition", NULL);
1135
0
            }
1136
0
            LY_ARRAY_FOR(add->uniques, u) {
1137
0
                ypr_substmt(ctx, LY_STMT_UNIQUE, u, add->uniques[u].str, add->exts);
1138
0
            }
1139
0
            LY_ARRAY_FOR(add->dflts, u) {
1140
0
                ypr_substmt(ctx, LY_STMT_DEFAULT, u, add->dflts[u].str, add->exts);
1141
0
            }
1142
0
            ypr_config(ctx, add->flags, add->exts, NULL);
1143
0
            ypr_mandatory(ctx, add->flags, add->exts, NULL);
1144
0
            if (add->flags & LYS_SET_MIN) {
1145
0
                ypr_unsigned(ctx, LY_STMT_MIN_ELEMENTS, 0, add->exts, add->min);
1146
0
            }
1147
0
            if (add->flags & LYS_SET_MAX) {
1148
0
                if (add->max) {
1149
0
                    ypr_unsigned(ctx, LY_STMT_MAX_ELEMENTS, 0, add->exts, add->max);
1150
0
                } else {
1151
0
                    ypr_substmt(ctx, LY_STMT_MAX_ELEMENTS, 0, "unbounded", add->exts);
1152
0
                }
1153
0
            }
1154
0
        } else if (elem->mod == LYS_DEV_REPLACE) {
1155
0
            rpl = (struct lysp_deviate_rpl *)elem;
1156
0
            ly_print_(ctx->out, "replace\">\n");
1157
0
            LEVEL++;
1158
1159
0
            yprp_extension_instances(ctx, LY_STMT_DEVIATE, 0, rpl->exts, NULL, 0);
1160
0
            if (rpl->type) {
1161
0
                yprp_type(ctx, rpl->type);
1162
0
            }
1163
0
            ypr_substmt(ctx, LY_STMT_UNITS, 0, rpl->units, rpl->exts);
1164
0
            ypr_substmt(ctx, LY_STMT_DEFAULT, 0, rpl->dflt.str, rpl->exts);
1165
0
            ypr_config(ctx, rpl->flags, rpl->exts, NULL);
1166
0
            ypr_mandatory(ctx, rpl->flags, rpl->exts, NULL);
1167
0
            if (rpl->flags & LYS_SET_MIN) {
1168
0
                ypr_unsigned(ctx, LY_STMT_MIN_ELEMENTS, 0, rpl->exts, rpl->min);
1169
0
            }
1170
0
            if (rpl->flags & LYS_SET_MAX) {
1171
0
                if (rpl->max) {
1172
0
                    ypr_unsigned(ctx, LY_STMT_MAX_ELEMENTS, 0, rpl->exts, rpl->max);
1173
0
                } else {
1174
0
                    ypr_substmt(ctx, LY_STMT_MAX_ELEMENTS, 0, "unbounded", rpl->exts);
1175
0
                }
1176
0
            }
1177
0
        } else if (elem->mod == LYS_DEV_DELETE) {
1178
0
            del = (struct lysp_deviate_del *)elem;
1179
0
            ly_print_(ctx->out, "delete\">\n");
1180
0
            LEVEL++;
1181
1182
0
            yprp_extension_instances(ctx, LY_STMT_DEVIATE, 0, del->exts, NULL, 0);
1183
0
            ypr_substmt(ctx, LY_STMT_UNITS, 0, del->units, del->exts);
1184
0
            LY_ARRAY_FOR(del->musts, u) {
1185
0
                yprp_restr(ctx, &del->musts[u], LY_STMT_MUST, "condition", NULL);
1186
0
            }
1187
0
            LY_ARRAY_FOR(del->uniques, u) {
1188
0
                ypr_substmt(ctx, LY_STMT_UNIQUE, u, del->uniques[u].str, del->exts);
1189
0
            }
1190
0
            LY_ARRAY_FOR(del->dflts, u) {
1191
0
                ypr_substmt(ctx, LY_STMT_DEFAULT, u, del->dflts[u].str, del->exts);
1192
0
            }
1193
0
        }
1194
1195
0
        LEVEL--;
1196
0
        ypr_close(ctx, "deviate", 1);
1197
0
    }
1198
1199
0
    LEVEL--;
1200
0
    ypr_close(ctx, "deviation", 1);
1201
0
}
1202
1203
static void
1204
ypr_xmlns(struct lys_ypr_ctx *ctx, const struct lys_module *module, uint16_t indent)
1205
0
{
1206
0
    ly_print_(ctx->out, "%*sxmlns=\"%s\"", indent + INDENT, YIN_NS_URI);
1207
0
    ly_print_(ctx->out, "\n%*sxmlns:%s=\"%s\"", indent + INDENT, module->prefix, module->ns);
1208
0
}
1209
1210
static void
1211
ypr_import_xmlns(struct lys_ypr_ctx *ctx, const struct lysp_module *modp, uint16_t indent)
1212
0
{
1213
0
    LY_ARRAY_COUNT_TYPE u;
1214
1215
0
    LY_ARRAY_FOR(modp->imports, u){
1216
0
        ly_print_(ctx->out, "\n%*sxmlns:%s=\"%s\"", indent + INDENT, modp->imports[u].prefix, modp->imports[u].module->ns);
1217
0
    }
1218
0
}
1219
1220
static void
1221
yprp_stmt(struct lys_ypr_ctx *ctx, struct lysp_stmt *stmt)
1222
0
{
1223
0
    struct lysp_stmt *childstmt;
1224
0
    int8_t flag = stmt->child ? 1 : -1;
1225
1226
    /* TODO:
1227
             the extension instance substatements in extension instances (LY_STMT_EXTENSION_INSTANCE)
1228
             cannot find the compiled information, so it is needed to be done,
1229
             currently it is ignored */
1230
0
    if (stmt_attr_info[stmt->kw].name) {
1231
0
        if (stmt_attr_info[stmt->kw].flags & STMT_FLAG_YIN) {
1232
0
            ypr_open(ctx, stmt->stmt, NULL, NULL, flag);
1233
0
            ypr_yin_arg(ctx, stmt_attr_info[stmt->kw].arg, stmt->arg);
1234
0
        } else {
1235
0
            ypr_open(ctx, stmt->stmt, stmt_attr_info[stmt->kw].arg, stmt->arg, flag);
1236
0
        }
1237
0
    }
1238
1239
0
    if (stmt->child) {
1240
0
        LEVEL++;
1241
0
        LY_LIST_FOR(stmt->child, childstmt) {
1242
0
            yprp_stmt(ctx, childstmt);
1243
0
        }
1244
0
        LEVEL--;
1245
0
        ypr_close(ctx, stmt->stmt, flag);
1246
0
    }
1247
0
}
1248
1249
/**
1250
 * @param[in] count Number of extensions to print, 0 to print them all.
1251
 */
1252
static void
1253
yprp_extension_instances(struct lys_ypr_ctx *ctx, enum ly_stmt substmt, uint8_t substmt_index,
1254
        struct lysp_ext_instance *ext, int8_t *flag, LY_ARRAY_COUNT_TYPE count)
1255
0
{
1256
0
    LY_ARRAY_COUNT_TYPE u;
1257
0
    struct lysp_stmt *stmt;
1258
0
    int8_t inner_flag = 0;
1259
1260
0
    if (!count && ext) {
1261
0
        count = LY_ARRAY_COUNT(ext);
1262
0
    }
1263
0
    LY_ARRAY_FOR(ext, u) {
1264
0
        struct lysp_ext *ext_def = NULL;
1265
1266
0
        if (!count) {
1267
0
            break;
1268
0
        }
1269
1270
0
        count--;
1271
0
        if ((ext->flags & LYS_INTERNAL) || (ext->parent_stmt != substmt) || (ext->parent_stmt_index != substmt_index)) {
1272
0
            continue;
1273
0
        }
1274
1275
0
        lysp_ext_find_definition(ctx->module->ctx, &ext[u], NULL, &ext_def);
1276
0
        if (!ext_def) {
1277
0
            continue;
1278
0
        }
1279
1280
0
        ypr_close_parent(ctx, flag);
1281
0
        inner_flag = 0;
1282
1283
0
        if (ext_def->argname) {
1284
0
            lysp_ext_instance_resolve_argument(ctx->module->ctx, &ext[u], ext_def);
1285
0
        }
1286
1287
0
        ypr_open(ctx, ext[u].name, (ext_def->flags & LYS_YINELEM_TRUE) ? NULL : ext_def->argname, ext[u].argument, inner_flag);
1288
0
        LEVEL++;
1289
0
        if (ext_def->flags & LYS_YINELEM_TRUE) {
1290
0
            const char *prefix, *name, *id;
1291
0
            size_t prefix_len, name_len;
1292
1293
0
            ypr_close_parent(ctx, &inner_flag);
1294
1295
            /* we need to use the same namespace as for the extension instance element */
1296
0
            id = ext[u].name;
1297
0
            ly_parse_nodeid(&id, &prefix, &prefix_len, &name, &name_len);
1298
0
            ly_print_(ctx->out, "%*s<%.*s:%s>", INDENT, (int)prefix_len, prefix, ext_def->argname);
1299
0
            lyxml_dump_text(ctx->out, ext[u].argument, 0);
1300
0
            ly_print_(ctx->out, "</%.*s:%s>\n", (int)prefix_len, prefix, ext_def->argname);
1301
0
        }
1302
0
        LY_LIST_FOR(ext[u].child, stmt) {
1303
0
            if (stmt->flags & (LYS_YIN_ATTR | LYS_YIN_ARGUMENT)) {
1304
0
                continue;
1305
0
            }
1306
1307
0
            ypr_close_parent(ctx, &inner_flag);
1308
0
            yprp_stmt(ctx, stmt);
1309
0
        }
1310
0
        LEVEL--;
1311
0
        ypr_close(ctx, ext[u].name, inner_flag);
1312
0
    }
1313
0
}
1314
1315
static void
1316
yin_print_parsed_linkage(struct lys_ypr_ctx *ctx, const struct lysp_module *modp)
1317
0
{
1318
0
    LY_ARRAY_COUNT_TYPE u;
1319
1320
0
    LY_ARRAY_FOR(modp->imports, u) {
1321
0
        if (modp->imports[u].flags & LYS_INTERNAL) {
1322
0
            continue;
1323
0
        }
1324
1325
0
        ypr_open(ctx, "import", "module", modp->imports[u].name, 1);
1326
0
        LEVEL++;
1327
0
        yprp_extension_instances(ctx, LY_STMT_IMPORT, 0, modp->imports[u].exts, NULL, 0);
1328
0
        ypr_substmt(ctx, LY_STMT_PREFIX, 0, modp->imports[u].prefix, modp->imports[u].exts);
1329
0
        if (modp->imports[u].rev[0]) {
1330
0
            ypr_substmt(ctx, LY_STMT_REVISION_DATE, 0, modp->imports[u].rev, modp->imports[u].exts);
1331
0
        }
1332
0
        ypr_substmt(ctx, LY_STMT_DESCRIPTION, 0, modp->imports[u].dsc, modp->imports[u].exts);
1333
0
        ypr_substmt(ctx, LY_STMT_REFERENCE, 0, modp->imports[u].ref, modp->imports[u].exts);
1334
0
        LEVEL--;
1335
0
        ypr_close(ctx, "import", 1);
1336
0
    }
1337
0
    LY_ARRAY_FOR(modp->includes, u) {
1338
0
        if (modp->includes[u].injected) {
1339
            /* do not print the includes injected from submodules */
1340
0
            continue;
1341
0
        }
1342
0
        if (modp->includes[u].rev[0] || modp->includes[u].dsc || modp->includes[u].ref || modp->includes[u].exts) {
1343
0
            ypr_open(ctx, "include", "module", modp->includes[u].name, 1);
1344
0
            LEVEL++;
1345
0
            yprp_extension_instances(ctx, LY_STMT_INCLUDE, 0, modp->includes[u].exts, NULL, 0);
1346
0
            if (modp->includes[u].rev[0]) {
1347
0
                ypr_substmt(ctx, LY_STMT_REVISION_DATE, 0, modp->includes[u].rev, modp->includes[u].exts);
1348
0
            }
1349
0
            ypr_substmt(ctx, LY_STMT_DESCRIPTION, 0, modp->includes[u].dsc, modp->includes[u].exts);
1350
0
            ypr_substmt(ctx, LY_STMT_REFERENCE, 0, modp->includes[u].ref, modp->includes[u].exts);
1351
0
            LEVEL--;
1352
0
            ly_print_(ctx->out, "%*s}\n", INDENT);
1353
0
        } else {
1354
0
            ypr_open(ctx, "include", "module", modp->includes[u].name, -1);
1355
0
        }
1356
0
    }
1357
0
}
1358
1359
static void
1360
yin_print_parsed_body(struct lys_ypr_ctx *ctx, const struct lysp_module *modp)
1361
0
{
1362
0
    LY_ARRAY_COUNT_TYPE u;
1363
0
    struct lysp_node *data;
1364
0
    struct lysp_node_action *action;
1365
0
    struct lysp_node_notif *notif;
1366
0
    struct lysp_node_grp *grp;
1367
0
    struct lysp_node_augment *aug;
1368
1369
0
    LY_ARRAY_FOR(modp->extensions, u) {
1370
0
        ly_print_(ctx->out, "\n");
1371
0
        yprp_extension(ctx, &modp->extensions[u]);
1372
0
    }
1373
0
    if (modp->exts) {
1374
0
        ly_print_(ctx->out, "\n");
1375
0
        yprp_extension_instances(ctx, LY_STMT_MODULE, 0, modp->exts, NULL, 0);
1376
0
    }
1377
1378
0
    LY_ARRAY_FOR(modp->features, u) {
1379
0
        yprp_feature(ctx, &modp->features[u]);
1380
0
    }
1381
1382
0
    LY_ARRAY_FOR(modp->identities, u) {
1383
0
        yprp_identity(ctx, &modp->identities[u]);
1384
0
    }
1385
1386
0
    LY_ARRAY_FOR(modp->typedefs, u) {
1387
0
        yprp_typedef(ctx, &modp->typedefs[u]);
1388
0
    }
1389
1390
0
    LY_LIST_FOR(modp->groupings, grp) {
1391
0
        yprp_grouping(ctx, grp);
1392
0
    }
1393
1394
0
    LY_LIST_FOR(modp->data, data) {
1395
0
        yprp_node(ctx, data);
1396
0
    }
1397
1398
0
    LY_LIST_FOR(modp->augments, aug) {
1399
0
        yprp_augment(ctx, aug);
1400
0
    }
1401
1402
0
    LY_LIST_FOR(modp->rpcs, action) {
1403
0
        yprp_action(ctx, action);
1404
0
    }
1405
1406
0
    LY_LIST_FOR(modp->notifs, notif) {
1407
0
        yprp_notification(ctx, notif);
1408
0
    }
1409
1410
0
    LY_ARRAY_FOR(modp->deviations, u) {
1411
0
        yprp_deviation(ctx, &modp->deviations[u]);
1412
0
    }
1413
0
}
1414
1415
LY_ERR
1416
yin_print_parsed_module(struct ly_out *out, const struct lysp_module *modp, uint32_t options)
1417
0
{
1418
0
    LY_ARRAY_COUNT_TYPE u;
1419
0
    const struct lys_module *module = modp->mod;
1420
0
    struct lys_ypr_ctx ctx_ = {.out = out, .level = 0, .module = module, .options = options}, *ctx = &ctx_;
1421
1422
0
    ly_print_(ctx->out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1423
0
    ly_print_(ctx->out, "%*s<module name=\"%s\"\n", INDENT, module->name);
1424
0
    ypr_xmlns(ctx, module, XML_NS_INDENT);
1425
0
    ypr_import_xmlns(ctx, modp, XML_NS_INDENT);
1426
0
    ly_print_(ctx->out, ">\n");
1427
1428
0
    LEVEL++;
1429
1430
    /* module-header-stmts */
1431
0
    if (modp->version) {
1432
0
        ypr_substmt(ctx, LY_STMT_YANG_VERSION, 0, modp->version == LYS_VERSION_1_1 ? "1.1" : "1", modp->exts);
1433
0
    }
1434
0
    ypr_substmt(ctx, LY_STMT_NAMESPACE, 0, module->ns, modp->exts);
1435
0
    ypr_substmt(ctx, LY_STMT_PREFIX, 0, module->prefix, modp->exts);
1436
1437
    /* linkage-stmts (import/include) */
1438
0
    yin_print_parsed_linkage(ctx, modp);
1439
1440
    /* meta-stmts */
1441
0
    if (module->org || module->contact || module->dsc || module->ref) {
1442
0
        ly_print_(out, "\n");
1443
0
    }
1444
0
    ypr_substmt(ctx, LY_STMT_ORGANIZATION, 0, module->org, modp->exts);
1445
0
    ypr_substmt(ctx, LY_STMT_CONTACT, 0, module->contact, modp->exts);
1446
0
    ypr_substmt(ctx, LY_STMT_DESCRIPTION, 0, module->dsc, modp->exts);
1447
0
    ypr_substmt(ctx, LY_STMT_REFERENCE, 0, module->ref, modp->exts);
1448
1449
    /* revision-stmts */
1450
0
    if (modp->revs) {
1451
0
        ly_print_(out, "\n");
1452
0
    }
1453
0
    LY_ARRAY_FOR(modp->revs, u) {
1454
0
        yprp_revision(ctx, &modp->revs[u]);
1455
0
    }
1456
1457
    /* body-stmts */
1458
0
    yin_print_parsed_body(ctx, modp);
1459
1460
0
    LEVEL--;
1461
0
    ly_print_(out, "%*s</module>\n", INDENT);
1462
0
    ly_print_flush(out);
1463
1464
0
    return LY_SUCCESS;
1465
0
}
1466
1467
static void
1468
yprp_belongsto(struct lys_ypr_ctx *ctx, const struct lysp_submodule *submodp)
1469
0
{
1470
0
    ypr_open(ctx, "belongs-to", "module", submodp->mod->name, 1);
1471
0
    LEVEL++;
1472
0
    yprp_extension_instances(ctx, LY_STMT_BELONGS_TO, 0, submodp->exts, NULL, 0);
1473
0
    ypr_substmt(ctx, LY_STMT_PREFIX, 0, submodp->prefix, submodp->exts);
1474
0
    LEVEL--;
1475
0
    ypr_close(ctx, "belongs-to", 1);
1476
0
}
1477
1478
LY_ERR
1479
yin_print_parsed_submodule(struct ly_out *out, const struct lysp_submodule *submodp, uint32_t options)
1480
0
{
1481
0
    LY_ARRAY_COUNT_TYPE u;
1482
0
    struct lys_ypr_ctx ctx_ = {.out = out, .level = 0, .module = submodp->mod, .options = options}, *ctx = &ctx_;
1483
1484
0
    ly_print_(ctx->out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1485
0
    ly_print_(ctx->out, "%*s<submodule name=\"%s\"\n", INDENT, submodp->name);
1486
0
    ypr_xmlns(ctx, submodp->mod, XML_NS_INDENT);
1487
0
    ypr_import_xmlns(ctx, (struct lysp_module *)submodp, XML_NS_INDENT);
1488
0
    ly_print_(ctx->out, ">\n");
1489
1490
0
    LEVEL++;
1491
1492
    /* submodule-header-stmts */
1493
0
    if (submodp->version) {
1494
0
        ypr_substmt(ctx, LY_STMT_YANG_VERSION, 0, submodp->version == LYS_VERSION_1_1 ? "1.1" : "1", submodp->exts);
1495
0
    }
1496
0
    yprp_belongsto(ctx, submodp);
1497
1498
    /* linkage-stmts (import/include) */
1499
0
    yin_print_parsed_linkage(ctx, (struct lysp_module *)submodp);
1500
1501
    /* meta-stmts */
1502
0
    if (submodp->org || submodp->contact || submodp->dsc || submodp->ref) {
1503
0
        ly_print_(out, "\n");
1504
0
    }
1505
0
    ypr_substmt(ctx, LY_STMT_ORGANIZATION, 0, submodp->org, submodp->exts);
1506
0
    ypr_substmt(ctx, LY_STMT_CONTACT, 0, submodp->contact, submodp->exts);
1507
0
    ypr_substmt(ctx, LY_STMT_DESCRIPTION, 0, submodp->dsc, submodp->exts);
1508
0
    ypr_substmt(ctx, LY_STMT_REFERENCE, 0, submodp->ref, submodp->exts);
1509
1510
    /* revision-stmts */
1511
0
    if (submodp->revs) {
1512
0
        ly_print_(out, "\n");
1513
0
    }
1514
0
    LY_ARRAY_FOR(submodp->revs, u) {
1515
0
        yprp_revision(ctx, &submodp->revs[u]);
1516
0
    }
1517
1518
    /* body-stmts */
1519
0
    yin_print_parsed_body(ctx, (struct lysp_module *)submodp);
1520
1521
0
    LEVEL--;
1522
0
    ly_print_(out, "%*s</submodule>\n", INDENT);
1523
0
    ly_print_flush(out);
1524
1525
0
    return LY_SUCCESS;
1526
0
}