blob: d82573301df55c1a9bc9ce7bbb93ac7243ad2bbd [file] [log] [blame]
FredGand944bdc2019-11-05 21:57:07 +08001/**
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
Radek Krejci535ea9f2020-05-29 16:01:05 +020015#define _GNU_SOURCE
FredGand944bdc2019-11-05 21:57:07 +080016
FredGand944bdc2019-11-05 21:57:07 +080017#include <stdint.h>
18#include <stdio.h>
19#include <stdlib.h>
FredGand944bdc2019-11-05 21:57:07 +080020
Radek Krejci535ea9f2020-05-29 16:01:05 +020021#include "common.h"
Radek Krejciaa45bda2020-07-20 07:43:38 +020022#include "compat.h"
FredGand944bdc2019-11-05 21:57:07 +080023#include "log.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020024#include "printer.h"
FredGand944bdc2019-11-05 21:57:07 +080025#include "printer_internal.h"
26#include "tree.h"
27#include "tree_schema.h"
28#include "tree_schema_internal.h"
FredGand944bdc2019-11-05 21:57:07 +080029#include "xml.h"
Michal Vasko004d3152020-06-11 19:59:22 +020030#include "xpath.h"
FredGand944bdc2019-11-05 21:57:07 +080031
32/**
33 * @brief YIN printer context.
34 */
35struct ypr_ctx {
Radek Krejci241f6b52020-05-21 18:13:49 +020036 struct ly_out *out; /**< output specification */
FredGand944bdc2019-11-05 21:57:07 +080037 unsigned int level; /**< current indentation level: 0 - no formatting, >= 1 indentation levels */
38 const struct lys_module *module; /**< schema to print */
39};
40
41#define LEVEL ctx->level /**< current level */
42#define INDENT (LEVEL)*2,"" /**< indentation parameters for printer functions */
43
44static void yprp_extension_instances(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
Michal Vaskofd69e1d2020-07-03 11:57:17 +020045 struct lysp_ext_instance *ext, int *flag, LY_ARRAY_COUNT_TYPE count);
FredGand944bdc2019-11-05 21:57:07 +080046
47static void
48ypr_open(struct ypr_ctx *ctx, const char *elem_name, const char *attr_name, const char *attr_value, int flag)
49{
Radek Krejci241f6b52020-05-21 18:13:49 +020050 ly_print(ctx->out, "%*s<%s", INDENT, elem_name);
FredGand944bdc2019-11-05 21:57:07 +080051
52 if (attr_name) {
Radek Krejci241f6b52020-05-21 18:13:49 +020053 ly_print(ctx->out, " %s=\"", attr_name);
FredGand944bdc2019-11-05 21:57:07 +080054 lyxml_dump_text(ctx->out, attr_value, 1);
Radek Krejci241f6b52020-05-21 18:13:49 +020055 ly_print(ctx->out, "\"%s", flag == -1 ? "/>\n" : flag == 1 ? ">\n" : "");
FredGand944bdc2019-11-05 21:57:07 +080056 } else if (flag) {
Radek Krejci241f6b52020-05-21 18:13:49 +020057 ly_print(ctx->out, flag == -1 ? "/>\n" : ">\n");
FredGand944bdc2019-11-05 21:57:07 +080058 }
59}
60
61static void
62ypr_close(struct ypr_ctx *ctx, const char *elem_name, int flag)
63{
64 if (flag) {
Radek Krejci241f6b52020-05-21 18:13:49 +020065 ly_print(ctx->out, "%*s</%s>\n", INDENT, elem_name);
FredGand944bdc2019-11-05 21:57:07 +080066 } else {
Radek Krejci241f6b52020-05-21 18:13:49 +020067 ly_print(ctx->out, "/>\n");
FredGand944bdc2019-11-05 21:57:07 +080068 }
69}
70
71/*
72 * par_close_flag
73 * 0 - parent not yet closed, printing >\n, setting flag to 1
74 * 1 or NULL - parent already closed, do nothing
75 */
76static void
77ypr_close_parent(struct ypr_ctx *ctx, int *par_close_flag)
78{
79 if (par_close_flag && !(*par_close_flag)) {
80 (*par_close_flag) = 1;
Radek Krejci241f6b52020-05-21 18:13:49 +020081 ly_print(ctx->out, ">\n");
FredGand944bdc2019-11-05 21:57:07 +080082 }
83}
84
85static void
86ypr_yin_arg(struct ypr_ctx *ctx, const char *arg, const char *text)
87{
Radek Krejci241f6b52020-05-21 18:13:49 +020088 ly_print(ctx->out, "%*s<%s>", INDENT, arg);
FredGand944bdc2019-11-05 21:57:07 +080089 lyxml_dump_text(ctx->out, text, 0);
Radek Krejci241f6b52020-05-21 18:13:49 +020090 ly_print(ctx->out, "</%s>\n", arg);
FredGand944bdc2019-11-05 21:57:07 +080091}
92
93
94
95static void
96ypr_substmt(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text, void *ext)
97{
Michal Vaskofd69e1d2020-07-03 11:57:17 +020098 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +080099 int extflag = 0;
100
101 if (!text) {
102 /* nothing to print */
103 return;
104 }
105
106 if (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) {
107 extflag = 1;
108 ypr_open(ctx, ext_substmt_info[substmt].name, NULL, NULL, extflag);
109 } else {
110 ypr_open(ctx, ext_substmt_info[substmt].name, ext_substmt_info[substmt].arg, text, extflag);
111 }
112
113 LEVEL++;
114 LY_ARRAY_FOR(ext, u) {
115 if (((struct lysp_ext_instance*)ext)[u].insubstmt != substmt || ((struct lysp_ext_instance*)ext)[u].insubstmt_index != substmt_index) {
116 continue;
117 }
118 yprp_extension_instances(ctx, substmt, substmt_index, &((struct lysp_ext_instance*)ext)[u], &extflag, 1);
119 }
120
121 /* argument as yin-element */
122 if (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) {
123 ypr_yin_arg(ctx, ext_substmt_info[substmt].arg, text);
124 }
125
126 LEVEL--;
127 ypr_close(ctx, ext_substmt_info[substmt].name, extflag);
128}
129
130static void
131ypr_unsigned(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, void *exts, unsigned int attr_value)
132{
133 char *str;
134 if (asprintf(&str, "%u", attr_value) == -1) {
135 LOGMEM(ctx->module->ctx);
136 ctx->out->status = LY_EMEM;
137 return;
138 }
139 ypr_substmt(ctx, substmt, substmt_index, str, exts);
140 free(str);
141}
142
143static void
144ypr_signed(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, void *exts, signed int attr_value)
145{
146 char *str;
147
148 if (asprintf(&str, "%d", attr_value) == -1) {
149 LOGMEM(ctx->module->ctx);
150 ctx->out->status = LY_EMEM;
151 return;
152 }
153 ypr_substmt(ctx, substmt, substmt_index, str, exts);
154 free(str);
155}
156
157static void
158yprp_revision(struct ypr_ctx *ctx, const struct lysp_revision *rev)
159{
160 if (rev->dsc || rev->ref || rev->exts) {
161 ypr_open(ctx, "revision", "date", rev->date, 1);
162 LEVEL++;
163 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, rev->exts, NULL, 0);
164 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, rev->dsc, rev->exts);
165 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, rev->ref, rev->exts);
166 LEVEL--;
167 ypr_close(ctx, "revision", 1);
168 } else {
169 ypr_open(ctx, "revision", "date", rev->date, -1);
170 }
171}
172
173static void
174ypr_mandatory(struct ypr_ctx *ctx, uint16_t flags, void *exts, int *flag)
175{
176 if (flags & LYS_MAND_MASK) {
177 ypr_close_parent(ctx, flag);
178 ypr_substmt(ctx, LYEXT_SUBSTMT_MANDATORY, 0, (flags & LYS_MAND_TRUE) ? "true" : "false", exts);
179 }
180}
181
182static void
183ypr_config(struct ypr_ctx *ctx, uint16_t flags, void *exts, int *flag)
184{
185 if (flags & LYS_CONFIG_MASK) {
186 ypr_close_parent(ctx, flag);
187 ypr_substmt(ctx, LYEXT_SUBSTMT_CONFIG, 0, (flags & LYS_CONFIG_W) ? "true" : "false", exts);
188 }
189}
190
191static void
192ypr_status(struct ypr_ctx *ctx, uint16_t flags, void *exts, int *flag)
193{
194 const char *status = NULL;
195
196 if (flags & LYS_STATUS_CURR) {
197 ypr_close_parent(ctx, flag);
198 status = "current";
199 } else if (flags & LYS_STATUS_DEPRC) {
200 ypr_close_parent(ctx, flag);
201 status = "deprecated";
202 } else if (flags & LYS_STATUS_OBSLT) {
203 ypr_close_parent(ctx, flag);
204 status = "obsolete";
205 }
206
207 ypr_substmt(ctx, LYEXT_SUBSTMT_STATUS, 0, status, exts);
208}
209
210static void
211ypr_description(struct ypr_ctx *ctx, const char *dsc, void *exts, int *flag)
212{
213 if (dsc) {
214 ypr_close_parent(ctx, flag);
215 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, dsc, exts);
216 }
217}
218
219static void
220ypr_reference(struct ypr_ctx *ctx, const char *ref, void *exts, int *flag)
221{
222 if (ref) {
223 ypr_close_parent(ctx, flag);
224 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, ref, exts);
225 }
226}
227
228static void
229yprp_iffeatures(struct ypr_ctx *ctx, const char **iff, struct lysp_ext_instance *exts, int *flag)
230{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200231 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800232 int extflag;
233
234 LY_ARRAY_FOR(iff, u) {
235 ypr_close_parent(ctx, flag);
236 extflag = 0;
237
Radek Krejci241f6b52020-05-21 18:13:49 +0200238 ly_print(ctx->out, "%*s<if-feature name=\"%s", INDENT, iff[u]);
FredGand944bdc2019-11-05 21:57:07 +0800239
240 /* extensions */
241 LEVEL++;
242 LY_ARRAY_FOR(exts, u) {
243 if (exts[u].insubstmt != LYEXT_SUBSTMT_IFFEATURE || exts[u].insubstmt_index != u) {
244 continue;
245 }
246 yprp_extension_instances(ctx, LYEXT_SUBSTMT_IFFEATURE, u, &exts[u], &extflag, 1);
247 }
248 LEVEL--;
Radek Krejci241f6b52020-05-21 18:13:49 +0200249 ly_print(ctx->out, "\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +0800250 }
251}
252
253static void
254yprp_extension(struct ypr_ctx *ctx, const struct lysp_ext *ext)
255{
256 int flag = 0, flag2 = 0;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200257 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800258
259 ypr_open(ctx, "extension", "name", ext->name, flag);
260 LEVEL++;
261
262 if (ext->exts) {
263 ypr_close_parent(ctx, &flag);
264 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, ext->exts, &flag, 0);
265 }
266
267 if (ext->argument) {
268 ypr_close_parent(ctx, &flag);
269 ypr_open(ctx, "argument", "name", ext->argument, flag2);
270
271 LEVEL++;
272 if (ext->exts) {
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200273 u = -1;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200274 while ((u = lysp_ext_instance_iter(ext->exts, u + 1, LYEXT_SUBSTMT_ARGUMENT)) != LY_ARRAY_COUNT(ext->exts)) {
FredGand944bdc2019-11-05 21:57:07 +0800275 ypr_close_parent(ctx, &flag2);
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200276 yprp_extension_instances(ctx, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->exts[u], &flag2, 1);
FredGand944bdc2019-11-05 21:57:07 +0800277 }
278 }
279 if ((ext->flags & LYS_YINELEM_MASK) ||
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200280 (ext->exts && lysp_ext_instance_iter(ext->exts, 0, LYEXT_SUBSTMT_YINELEM) != LY_ARRAY_COUNT(ext->exts))) {
FredGand944bdc2019-11-05 21:57:07 +0800281 ypr_close_parent(ctx, &flag2);
282 ypr_substmt(ctx, LYEXT_SUBSTMT_YINELEM, 0, (ext->flags & LYS_YINELEM_TRUE) ? "true" : "false", ext->exts);
283 }
284 LEVEL--;
285 ypr_close(ctx, "argument", flag2);
286 }
287
288 ypr_status(ctx, ext->flags, ext->exts, &flag);
289 ypr_description(ctx, ext->dsc, ext->exts, &flag);
290 ypr_reference(ctx, ext->ref, ext->exts, &flag);
291
292 LEVEL--;
293 ypr_close(ctx, "extension", flag);
294}
295
296static void
297yprp_feature(struct ypr_ctx *ctx, const struct lysp_feature *feat)
298{
299 int flag = 0;
300
301 ypr_open(ctx, "feature", "name", feat->name, flag);
302 LEVEL++;
303 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, feat->exts, &flag, 0);
304 yprp_iffeatures(ctx, feat->iffeatures, feat->exts, &flag);
305 ypr_status(ctx, feat->flags, feat->exts, &flag);
306 ypr_description(ctx, feat->dsc, feat->exts, &flag);
307 ypr_reference(ctx, feat->ref, feat->exts, &flag);
308 LEVEL--;
309 ypr_close(ctx, "feature", flag);
310}
311
312static void
313yprp_identity(struct ypr_ctx *ctx, const struct lysp_ident *ident)
314{
315 int flag = 0;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200316 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800317
318 ypr_open(ctx, "identity", "name", ident->name, flag);
319 LEVEL++;
320
321 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, ident->exts, &flag, 0);
322 yprp_iffeatures(ctx, ident->iffeatures, ident->exts, &flag);
323
324 LY_ARRAY_FOR(ident->bases, u) {
325 ypr_close_parent(ctx, &flag);
326 ypr_substmt(ctx, LYEXT_SUBSTMT_BASE, u, ident->bases[u], ident->exts);
327 }
328
329 ypr_status(ctx, ident->flags, ident->exts, &flag);
330 ypr_description(ctx, ident->dsc, ident->exts, &flag);
331 ypr_reference(ctx, ident->ref, ident->exts, &flag);
332
333 LEVEL--;
334 ypr_close(ctx, "identity", flag);
335}
336
337static void
338yprp_restr(struct ypr_ctx *ctx, const struct lysp_restr *restr, const char *name, const char *attr, int *flag)
339{
340 (void)flag;
341 int inner_flag = 0;
342
343 if (!restr) {
344 return;
345 }
346
Radek Krejci241f6b52020-05-21 18:13:49 +0200347 ly_print(ctx->out, "%*s<%s %s=\"", INDENT, name, attr);
FredGand944bdc2019-11-05 21:57:07 +0800348 lyxml_dump_text(ctx->out, (restr->arg[0] != 0x15 && restr->arg[0] != 0x06) ? restr->arg : &restr->arg[1], 1);
Radek Krejci241f6b52020-05-21 18:13:49 +0200349 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800350
351 LEVEL++;
352 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, restr->exts, &inner_flag, 0);
353 if (restr->arg[0] == 0x15) {
354 ypr_close_parent(ctx, &inner_flag);
355 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
356 ypr_substmt(ctx, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match", restr->exts);
357 }
358 if (restr->emsg) {
359 ypr_close_parent(ctx, &inner_flag);
360 ypr_substmt(ctx, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg, restr->exts);
361 }
362 if (restr->eapptag) {
363 ypr_close_parent(ctx, &inner_flag);
364 ypr_substmt(ctx, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag, restr->exts);
365 }
366 ypr_description(ctx, restr->dsc, restr->exts, &inner_flag);
367 ypr_reference(ctx, restr->ref, restr->exts, &inner_flag);
368
369 LEVEL--;
370 ypr_close(ctx, name, inner_flag);
371}
372
373static void
374yprp_when(struct ypr_ctx *ctx, struct lysp_when *when, int *flag)
375{
376 int inner_flag = 0;
377 (void)flag;
378
379 if (!when) {
380 return;
381 }
382
Radek Krejci241f6b52020-05-21 18:13:49 +0200383 ly_print(ctx->out, "%*s<when condition=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800384 lyxml_dump_text(ctx->out, when->cond, 1);
Radek Krejci241f6b52020-05-21 18:13:49 +0200385 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800386
387 LEVEL++;
388 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, when->exts, &inner_flag, 0);
389 ypr_description(ctx, when->dsc, when->exts, &inner_flag);
390 ypr_reference(ctx, when->ref, when->exts, &inner_flag);
391 LEVEL--;
392 ypr_close(ctx, "when", inner_flag);
393}
394
395static void
396yprp_enum(struct ypr_ctx *ctx, const struct lysp_type_enum *items, LY_DATA_TYPE type, int *flag)
397{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200398 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800399 int inner_flag;
400 (void)flag;
401
402 LY_ARRAY_FOR(items, u) {
403 if (type == LY_TYPE_BITS) {
Radek Krejci241f6b52020-05-21 18:13:49 +0200404 ly_print(ctx->out, "%*s<bit name=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800405 lyxml_dump_text(ctx->out, items[u].name, 1);
Radek Krejci241f6b52020-05-21 18:13:49 +0200406 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800407 } else { /* LY_TYPE_ENUM */
Radek Krejci241f6b52020-05-21 18:13:49 +0200408 ly_print(ctx->out, "%*s<enum name=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800409 lyxml_dump_text(ctx->out, items[u].name, 1);
Radek Krejci241f6b52020-05-21 18:13:49 +0200410 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800411 }
412 inner_flag = 0;
413 LEVEL++;
414 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, items[u].exts, &inner_flag, 0);
415 yprp_iffeatures(ctx, items[u].iffeatures, items[u].exts, &inner_flag);
416 if (items[u].flags & LYS_SET_VALUE) {
417 if (type == LY_TYPE_BITS) {
418 ypr_close_parent(ctx, &inner_flag);
419 ypr_unsigned(ctx, LYEXT_SUBSTMT_POSITION, 0, items[u].exts, items[u].value);
420 } else { /* LY_TYPE_ENUM */
421 ypr_close_parent(ctx, &inner_flag);
422 ypr_signed(ctx, LYEXT_SUBSTMT_VALUE, 0, items[u].exts, items[u].value);
423 }
424 }
425 ypr_status(ctx, items[u].flags, items[u].exts, &inner_flag);
426 ypr_description(ctx, items[u].dsc, items[u].exts, &inner_flag);
427 ypr_reference(ctx, items[u].ref, items[u].exts, &inner_flag);
428 LEVEL--;
429 ypr_close(ctx, type == LY_TYPE_BITS ? "bit" : "enum", inner_flag);
430 }
431}
432
433static void
434yprp_type(struct ypr_ctx *ctx, const struct lysp_type *type)
435{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200436 LY_ARRAY_COUNT_TYPE u;
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200437 int flag = 0;
438
FredGand944bdc2019-11-05 21:57:07 +0800439 if (!ctx || !type) {
440 return;
441 }
442
FredGand944bdc2019-11-05 21:57:07 +0800443 ypr_open(ctx, "type", "name", type->name, flag);
444 LEVEL++;
445
446 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, type->exts, &flag, 0);
447
448 if (type->range || type->length || type->patterns || type->bits || type->enums) {
449 ypr_close_parent(ctx, &flag);
450 }
451 yprp_restr(ctx, type->range, "range", "value", &flag);
452 yprp_restr(ctx, type->length, "length", "value", &flag);
453 LY_ARRAY_FOR(type->patterns, u) {
454 yprp_restr(ctx, &type->patterns[u], "pattern", "value", &flag);
455 }
456 yprp_enum(ctx, type->bits, LY_TYPE_BITS, &flag);
457 yprp_enum(ctx, type->enums, LY_TYPE_ENUM, &flag);
458
459 if (type->path) {
460 ypr_close_parent(ctx, &flag);
Michal Vasko004d3152020-06-11 19:59:22 +0200461 ypr_substmt(ctx, LYEXT_SUBSTMT_PATH, 0, type->path->expr, type->exts);
FredGand944bdc2019-11-05 21:57:07 +0800462 }
463 if (type->flags & LYS_SET_REQINST) {
464 ypr_close_parent(ctx, &flag);
465 ypr_substmt(ctx, LYEXT_SUBSTMT_REQINSTANCE, 0, type->require_instance ? "true" : "false", type->exts);
466 }
467 if (type->flags & LYS_SET_FRDIGITS) {
468 ypr_close_parent(ctx, &flag);
469 ypr_unsigned(ctx, LYEXT_SUBSTMT_FRACDIGITS, 0, type->exts, type->fraction_digits);
470 }
471 LY_ARRAY_FOR(type->bases, u) {
472 ypr_close_parent(ctx, &flag);
473 ypr_substmt(ctx, LYEXT_SUBSTMT_BASE, u, type->bases[u], type->exts);
474 }
475 LY_ARRAY_FOR(type->types, u) {
476 ypr_close_parent(ctx, &flag);
477 yprp_type(ctx, &type->types[u]);
478 }
479
480 LEVEL--;
481 ypr_close(ctx, "type", flag);
482}
483
484static void
485yprp_typedef(struct ypr_ctx *ctx, const struct lysp_tpdf *tpdf)
486{
487 LYOUT_CHECK(ctx->out);
488
489 ypr_open(ctx, "typedef", "name", tpdf->name, 1);
490 LEVEL++;
491
492 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, tpdf->exts, NULL, 0);
493
494 yprp_type(ctx, &tpdf->type);
495
496 if (tpdf->units) {
497 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, tpdf->exts);
498 }
499 if (tpdf->dflt) {
500 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, tpdf->dflt, tpdf->exts);
501 }
502
503 ypr_status(ctx, tpdf->flags, tpdf->exts, NULL);
504 ypr_description(ctx, tpdf->dsc, tpdf->exts, NULL);
505 ypr_reference(ctx, tpdf->ref, tpdf->exts, NULL);
506
507 LEVEL--;
508 ypr_close(ctx, "typedef", 1);
509}
510
511static void yprp_node(struct ypr_ctx *ctx, const struct lysp_node *node);
512static void yprp_action(struct ypr_ctx *ctx, const struct lysp_action *action);
513
514static void
515yprp_grouping(struct ypr_ctx *ctx, const struct lysp_grp *grp)
516{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200517 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800518 int flag = 0;
519 struct lysp_node *data;
520
521 LYOUT_CHECK(ctx->out);
522
523 ypr_open(ctx, "grouping", "name", grp->name, flag);
524 LEVEL++;
525
526 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, grp->exts, &flag, 0);
527 ypr_status(ctx, grp->flags, grp->exts, &flag);
528 ypr_description(ctx, grp->dsc, grp->exts, &flag);
529 ypr_reference(ctx, grp->ref, grp->exts, &flag);
530
531 LY_ARRAY_FOR(grp->typedefs, u) {
532 ypr_close_parent(ctx, &flag);
533 yprp_typedef(ctx, &grp->typedefs[u]);
534 }
535
536 LY_ARRAY_FOR(grp->groupings, u) {
537 ypr_close_parent(ctx, &flag);
538 yprp_grouping(ctx, &grp->groupings[u]);
539 }
540
541 LY_LIST_FOR(grp->data, data) {
542 ypr_close_parent(ctx, &flag);
543 yprp_node(ctx, data);
544 }
545
546 LY_ARRAY_FOR(grp->actions, u) {
547 ypr_close_parent(ctx, &flag);
548 yprp_action(ctx, &grp->actions[u]);
549 }
550
551 LEVEL--;
552 ypr_close(ctx, "grouping", flag);
553}
554
555static void
556yprp_inout(struct ypr_ctx *ctx, const struct lysp_action_inout *inout, int *flag)
557{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200558 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800559 struct lysp_node *data;
560
561 if (!inout->nodetype) {
562 /* nodetype not set -> input/output is empty */
563 return;
564 }
565 ypr_close_parent(ctx, flag);
566
567 ypr_open(ctx, (inout->nodetype == LYS_INPUT ? "input" : "output"), NULL, NULL, *flag);
568 LEVEL++;
569
570 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, inout->exts, NULL, 0);
571 LY_ARRAY_FOR(inout->musts, u) {
572 yprp_restr(ctx, &inout->musts[u], "must", "condition", NULL);
573 }
574 LY_ARRAY_FOR(inout->typedefs, u) {
575 yprp_typedef(ctx, &inout->typedefs[u]);
576 }
577 LY_ARRAY_FOR(inout->groupings, u) {
578 yprp_grouping(ctx, &inout->groupings[u]);
579 }
580
581 LY_LIST_FOR(inout->data, data) {
582 yprp_node(ctx, data);
583 }
584
585 LEVEL--;
586 ypr_close(ctx, (inout->nodetype == LYS_INPUT ? "input" : "output"), 1);
587}
588
589static void
590yprp_notification(struct ypr_ctx *ctx, const struct lysp_notif *notif)
591{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200592 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800593 int flag = 0;
594 struct lysp_node *data;
595
596 LYOUT_CHECK(ctx->out);
597
598 ypr_open(ctx, "notification", "name", notif->name, flag);
599
600 LEVEL++;
601 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, notif->exts, &flag, 0);
602 yprp_iffeatures(ctx, notif->iffeatures, notif->exts, &flag);
603
604 LY_ARRAY_FOR(notif->musts, u) {
605 ypr_close_parent(ctx, &flag);
606 yprp_restr(ctx, &notif->musts[u], "must", "condition", &flag);
607 }
608 ypr_status(ctx, notif->flags, notif->exts, &flag);
609 ypr_description(ctx, notif->dsc, notif->exts, &flag);
610 ypr_reference(ctx, notif->ref, notif->exts, &flag);
611
612 LY_ARRAY_FOR(notif->typedefs, u) {
613 ypr_close_parent(ctx, &flag);
614 yprp_typedef(ctx, &notif->typedefs[u]);
615 }
616
617 LY_ARRAY_FOR(notif->groupings, u) {
618 ypr_close_parent(ctx, &flag);
619 yprp_grouping(ctx, &notif->groupings[u]);
620 }
621
622 LY_LIST_FOR(notif->data, data) {
623 ypr_close_parent(ctx, &flag);
624 yprp_node(ctx, data);
625 }
626
627 LEVEL--;
628 ypr_close(ctx, "notification", flag);
629}
630
631static void
632yprp_action(struct ypr_ctx *ctx, const struct lysp_action *action)
633{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200634 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800635 int flag = 0;
636
637 LYOUT_CHECK(ctx->out);
638
639 ypr_open(ctx, action->parent ? "action" : "rpc", "name", action->name, flag);
640
641 LEVEL++;
642 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, action->exts, &flag, 0);
643 yprp_iffeatures(ctx, action->iffeatures, action->exts, &flag);
644 ypr_status(ctx, action->flags, action->exts, &flag);
645 ypr_description(ctx, action->dsc, action->exts, &flag);
646 ypr_reference(ctx, action->ref, action->exts, &flag);
647
648 LY_ARRAY_FOR(action->typedefs, u) {
649 ypr_close_parent(ctx, &flag);
650 yprp_typedef(ctx, &action->typedefs[u]);
651 }
652
653 LY_ARRAY_FOR(action->groupings, u) {
654 ypr_close_parent(ctx, &flag);
655 yprp_grouping(ctx, &action->groupings[u]);
656 }
657
658 yprp_inout(ctx, &action->input, &flag);
659 yprp_inout(ctx, &action->output, &flag);
660
661 LEVEL--;
662 ypr_close(ctx, action->parent ? "action" : "rpc", flag);
663}
664
665static void
666yprp_node_common1(struct ypr_ctx *ctx, const struct lysp_node *node, int *flag)
667{
668 ypr_open(ctx, lys_nodetype2str(node->nodetype), "name", node->name, *flag);
669 LEVEL++;
670
671 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, node->exts, flag, 0);
672 yprp_when(ctx, node->when, flag);
673 yprp_iffeatures(ctx, node->iffeatures, node->exts, flag);
674}
675
676static void
677yprp_node_common2(struct ypr_ctx *ctx, const struct lysp_node *node, int *flag)
678{
679 ypr_config(ctx, node->flags, node->exts, flag);
680 if (node->nodetype & (LYS_CHOICE | LYS_LEAF | LYS_ANYDATA)) {
681 ypr_mandatory(ctx, node->flags, node->exts, flag);
682 }
683 ypr_status(ctx, node->flags, node->exts, flag);
684 ypr_description(ctx, node->dsc, node->exts, flag);
685 ypr_reference(ctx, node->ref, node->exts, flag);
686}
687
688static void
689yprp_container(struct ypr_ctx *ctx, const struct lysp_node *node)
690{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200691 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800692 int flag = 0;
693 struct lysp_node *child;
694 struct lysp_node_container *cont = (struct lysp_node_container *)node;
695
696 yprp_node_common1(ctx, node, &flag);
697
698 LY_ARRAY_FOR(cont->musts, u) {
699 ypr_close_parent(ctx, &flag);
700 yprp_restr(ctx, &cont->musts[u], "must", "condition", &flag);
701 }
702 if (cont->presence) {
703 ypr_close_parent(ctx, &flag);
704 ypr_substmt(ctx, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence, cont->exts);
705 }
706
707 yprp_node_common2(ctx, node, &flag);
708
709 LY_ARRAY_FOR(cont->typedefs, u) {
710 ypr_close_parent(ctx, &flag);
711 yprp_typedef(ctx, &cont->typedefs[u]);
712 }
713
714 LY_ARRAY_FOR(cont->groupings, u) {
715 ypr_close_parent(ctx, &flag);
716 yprp_grouping(ctx, &cont->groupings[u]);
717 }
718
719 LY_LIST_FOR(cont->child, child) {
720 ypr_close_parent(ctx, &flag);
721 yprp_node(ctx, child);
722 }
723
724 LY_ARRAY_FOR(cont->actions, u) {
725 ypr_close_parent(ctx, &flag);
726 yprp_action(ctx, &cont->actions[u]);
727 }
728
729 LY_ARRAY_FOR(cont->notifs, u) {
730 ypr_close_parent(ctx, &flag);
731 yprp_notification(ctx, &cont->notifs[u]);
732 }
733
734 LEVEL--;
735 ypr_close(ctx, "container", flag);
736}
737
738static void
739yprp_case(struct ypr_ctx *ctx, const struct lysp_node *node)
740{
741 int flag = 0;
742 struct lysp_node *child;
743 struct lysp_node_case *cas = (struct lysp_node_case *)node;
744
745 yprp_node_common1(ctx, node, &flag);
746 yprp_node_common2(ctx, node, &flag);
747
748 LY_LIST_FOR(cas->child, child) {
749 ypr_close_parent(ctx, &flag);
750 yprp_node(ctx, child);
751 }
752
753 LEVEL--;
754 ypr_close(ctx, "case", flag);
755}
756
757static void
758yprp_choice(struct ypr_ctx *ctx, const struct lysp_node *node)
759{
760 int flag = 0;
761 struct lysp_node *child;
762 struct lysp_node_choice *choice = (struct lysp_node_choice *)node;
763
764 yprp_node_common1(ctx, node, &flag);
765
766 if (choice->dflt) {
767 ypr_close_parent(ctx, &flag);
768 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt, choice->exts);
769 }
770
771 yprp_node_common2(ctx, node, &flag);
772
773 LY_LIST_FOR(choice->child, child) {
774 ypr_close_parent(ctx, &flag);
775 yprp_node(ctx, child);
776 }
777
778 LEVEL--;
779 ypr_close(ctx, "choice", flag);
780}
781
782static void
783yprp_leaf(struct ypr_ctx *ctx, const struct lysp_node *node)
784{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200785 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800786 struct lysp_node_leaf *leaf = (struct lysp_node_leaf *)node;
787
788 int flag = 1;
789 yprp_node_common1(ctx, node, &flag);
790
791 yprp_type(ctx, &leaf->type);
792 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, leaf->units, leaf->exts);
793 LY_ARRAY_FOR(leaf->musts, u) {
794 yprp_restr(ctx, &leaf->musts[u], "must", "condition", &flag);
795 }
796 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, leaf->dflt, leaf->exts);
797
798 yprp_node_common2(ctx, node, &flag);
799
800 LEVEL--;
801 ypr_close(ctx, "leaf", flag);
802}
803
804static void
805yprp_leaflist(struct ypr_ctx *ctx, const struct lysp_node *node)
806{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200807 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800808 struct lysp_node_leaflist *llist = (struct lysp_node_leaflist *)node;
809 int flag = 1;
810
811 yprp_node_common1(ctx, node, &flag);
812
813 yprp_type(ctx, &llist->type);
814 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, llist->units, llist->exts);
815 LY_ARRAY_FOR(llist->musts, u) {
816 yprp_restr(ctx, &llist->musts[u], "must", "condition", NULL);
817 }
818 LY_ARRAY_FOR(llist->dflts, u) {
819 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, llist->dflts[u], llist->exts);
820 }
821
822 ypr_config(ctx, node->flags, node->exts, NULL);
823
824 if (llist->flags & LYS_SET_MIN) {
825 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, llist->exts, llist->min);
826 }
827 if (llist->flags & LYS_SET_MAX) {
828 if (llist->max) {
829 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, llist->exts, llist->max);
830 } else {
831 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", llist->exts);
832 }
833 }
834
835 if (llist->flags & LYS_ORDBY_MASK) {
836 ypr_substmt(ctx, LYEXT_SUBSTMT_ORDEREDBY, 0, (llist->flags & LYS_ORDBY_USER) ? "user" : "system", llist->exts);
837 }
838
839 ypr_status(ctx, node->flags, node->exts, &flag);
840 ypr_description(ctx, node->dsc, node->exts, &flag);
841 ypr_reference(ctx, node->ref, node->exts, &flag);
842
843 LEVEL--;
844 ypr_close(ctx, "leaf-list", flag);
845}
846
847static void
848yprp_list(struct ypr_ctx *ctx, const struct lysp_node *node)
849{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200850 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800851 int flag = 0;
852 struct lysp_node *child;
853 struct lysp_node_list *list = (struct lysp_node_list *)node;
854
855 yprp_node_common1(ctx, node, &flag);
856
857 LY_ARRAY_FOR(list->musts, u) {
858 ypr_close_parent(ctx, &flag);
859 yprp_restr(ctx, &list->musts[u], "must", "condition", &flag);
860 }
861 if (list->key) {
862 ypr_close_parent(ctx, &flag);
863 ypr_substmt(ctx, LYEXT_SUBSTMT_KEY, 0, list->key, list->exts);
864 }
865 LY_ARRAY_FOR(list->uniques, u) {
866 ypr_close_parent(ctx, &flag);
867 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, list->uniques[u], list->exts);
868 }
869
870 ypr_config(ctx, node->flags, node->exts, NULL);
871
872 if (list->flags & LYS_SET_MIN) {
873 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, list->exts, list->min);
874 }
875 if (list->flags & LYS_SET_MAX) {
876 if (list->max) {
877 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, list->exts, list->max);
878 } else {
879 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", list->exts);
880 }
881 }
882
883 if (list->flags & LYS_ORDBY_MASK) {
884 ypr_close_parent(ctx, &flag);
885 ypr_substmt(ctx, LYEXT_SUBSTMT_ORDEREDBY, 0, (list->flags & LYS_ORDBY_USER) ? "user" : "system", list->exts);
886 }
887
888 ypr_status(ctx, node->flags, node->exts, &flag);
889 ypr_description(ctx, node->dsc, node->exts, &flag);
890 ypr_reference(ctx, node->ref, node->exts, &flag);
891
892 LY_ARRAY_FOR(list->typedefs, u) {
893 ypr_close_parent(ctx, &flag);
894 yprp_typedef(ctx, &list->typedefs[u]);
895 }
896
897 LY_ARRAY_FOR(list->groupings, u) {
898 ypr_close_parent(ctx, &flag);
899 yprp_grouping(ctx, &list->groupings[u]);
900 }
901
902 LY_LIST_FOR(list->child, child) {
903 ypr_close_parent(ctx, &flag);
904 yprp_node(ctx, child);
905 }
906
907 LY_ARRAY_FOR(list->actions, u) {
908 ypr_close_parent(ctx, &flag);
909 yprp_action(ctx, &list->actions[u]);
910 }
911
912 LY_ARRAY_FOR(list->notifs, u) {
913 ypr_close_parent(ctx, &flag);
914 yprp_notification(ctx, &list->notifs[u]);
915 }
916
917 LEVEL--;
918 ypr_close(ctx, "list", flag);
919}
920
921static void
922yprp_refine(struct ypr_ctx *ctx, struct lysp_refine *refine)
923{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200924 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800925 int flag = 0;
926
927 ypr_open(ctx, "refine", "target-node", refine->nodeid, flag);
928 LEVEL++;
929
930 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, refine->exts, &flag, 0);
931 yprp_iffeatures(ctx, refine->iffeatures, refine->exts, &flag);
932
933 LY_ARRAY_FOR(refine->musts, u) {
934 ypr_close_parent(ctx, &flag);
935 yprp_restr(ctx, &refine->musts[u], "must", "condition", &flag);
936 }
937
938 if (refine->presence) {
939 ypr_close_parent(ctx, &flag);
940 ypr_substmt(ctx, LYEXT_SUBSTMT_PRESENCE, 0, refine->presence, refine->exts);
941 }
942
943 LY_ARRAY_FOR(refine->dflts, u) {
944 ypr_close_parent(ctx, &flag);
945 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, refine->dflts[u], refine->exts);
946 }
947
948 ypr_config(ctx, refine->flags, refine->exts, &flag);
949 ypr_mandatory(ctx, refine->flags, refine->exts, &flag);
950
951 if (refine->flags & LYS_SET_MIN) {
952 ypr_close_parent(ctx, &flag);
953 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, refine->exts, refine->min);
954 }
955 if (refine->flags & LYS_SET_MAX) {
956 ypr_close_parent(ctx, &flag);
957 if (refine->max) {
958 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, refine->exts, refine->max);
959 } else {
960 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", refine->exts);
961 }
962 }
963
964 ypr_description(ctx, refine->dsc, refine->exts, &flag);
965 ypr_reference(ctx, refine->ref, refine->exts, &flag);
966
967 LEVEL--;
968 ypr_close(ctx, "refine", flag);
969}
970
971static void
972yprp_augment(struct ypr_ctx *ctx, const struct lysp_augment *aug)
973{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200974 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800975 struct lysp_node *child;
976
977 ypr_open(ctx, "augment", "target-node", aug->nodeid, 1);
978 LEVEL++;
979
980 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, aug->exts, NULL, 0);
981 yprp_when(ctx, aug->when, NULL);
982 yprp_iffeatures(ctx, aug->iffeatures, aug->exts, NULL);
983 ypr_status(ctx, aug->flags, aug->exts, NULL);
984 ypr_description(ctx, aug->dsc, aug->exts, NULL);
985 ypr_reference(ctx, aug->ref, aug->exts, NULL);
986
987 LY_LIST_FOR(aug->child, child) {
988 yprp_node(ctx, child);
989 }
990
991 LY_ARRAY_FOR(aug->actions, u) {
992 yprp_action(ctx, &aug->actions[u]);
993 }
994
995 LY_ARRAY_FOR(aug->notifs, u) {
996 yprp_notification(ctx, &aug->notifs[u]);
997 }
998
999 LEVEL--;
1000 ypr_close(ctx, "augment", 1);
1001}
1002
1003
1004static void
1005yprp_uses(struct ypr_ctx *ctx, const struct lysp_node *node)
1006{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001007 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001008 int flag = 0;
1009 struct lysp_node_uses *uses = (struct lysp_node_uses *)node;
1010
1011 yprp_node_common1(ctx, node, &flag);
1012 yprp_node_common2(ctx, node, &flag);
1013
1014 LY_ARRAY_FOR(uses->refines, u) {
1015 ypr_close_parent(ctx, &flag);
1016 yprp_refine(ctx, &uses->refines[u]);
1017 }
1018
1019 LY_ARRAY_FOR(uses->augments, u) {
1020 ypr_close_parent(ctx, &flag);
1021 yprp_augment(ctx, &uses->augments[u]);
1022 }
1023
1024 LEVEL--;
1025 ypr_close(ctx, "uses", flag);
1026}
1027
1028static void
1029yprp_anydata(struct ypr_ctx *ctx, const struct lysp_node *node)
1030{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001031 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001032 int flag = 0;
1033 struct lysp_node_anydata *any = (struct lysp_node_anydata *)node;
1034
1035 yprp_node_common1(ctx, node, &flag);
1036
1037 LY_ARRAY_FOR(any->musts, u) {
1038 ypr_close_parent(ctx, &flag);
1039 yprp_restr(ctx, &any->musts[u], "must", "condition", &flag);
1040 }
1041
1042 yprp_node_common2(ctx, node, &flag);
1043
1044 LEVEL--;
1045 ypr_close(ctx, lys_nodetype2str(node->nodetype), flag);
1046}
1047
1048static void
1049yprp_node(struct ypr_ctx *ctx, const struct lysp_node *node)
1050{
1051 LYOUT_CHECK(ctx->out);
1052
1053 switch (node->nodetype) {
1054 case LYS_CONTAINER:
1055 yprp_container(ctx, node);
1056 break;
1057 case LYS_CHOICE:
1058 yprp_choice(ctx, node);
1059 break;
1060 case LYS_LEAF:
1061 yprp_leaf(ctx, node);
1062 break;
1063 case LYS_LEAFLIST:
1064 yprp_leaflist(ctx, node);
1065 break;
1066 case LYS_LIST:
1067 yprp_list(ctx, node);
1068 break;
1069 case LYS_USES:
1070 yprp_uses(ctx, node);
1071 break;
1072 case LYS_ANYXML:
1073 case LYS_ANYDATA:
1074 yprp_anydata(ctx, node);
1075 break;
1076 case LYS_CASE:
1077 yprp_case(ctx, node);
1078 break;
1079 default:
1080 break;
1081 }
1082}
1083
1084static void
1085yprp_deviation(struct ypr_ctx *ctx, const struct lysp_deviation *deviation)
1086{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001087 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001088 struct lysp_deviate_add *add;
1089 struct lysp_deviate_rpl *rpl;
1090 struct lysp_deviate_del *del;
1091 struct lysp_deviate *elem;
1092
1093 ypr_open(ctx, "deviation", "target-node", deviation->nodeid, 1);
1094 LEVEL++;
1095
1096 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, deviation->exts, NULL, 0);
1097 ypr_description(ctx, deviation->dsc, deviation->exts, NULL);
1098 ypr_reference(ctx, deviation->ref, deviation->exts, NULL);
1099
1100 LY_LIST_FOR(deviation->deviates, elem) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001101 ly_print(ctx->out, "%*s<deviate value=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001102 if (elem->mod == LYS_DEV_NOT_SUPPORTED) {
1103 if (elem->exts) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001104 ly_print(ctx->out, "not-supported\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +08001105 LEVEL++;
1106
1107 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, elem->exts, NULL, 0);
1108 } else {
Radek Krejci241f6b52020-05-21 18:13:49 +02001109 ly_print(ctx->out, "not-supported\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +08001110 continue;
1111 }
1112 } else if (elem->mod == LYS_DEV_ADD) {
1113 add = (struct lysp_deviate_add*)elem;
Radek Krejci241f6b52020-05-21 18:13:49 +02001114 ly_print(ctx->out, "add\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001115 LEVEL++;
1116
1117 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, add->exts, NULL, 0);
1118 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, add->units, add->exts);
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001119 LY_ARRAY_FOR(add->musts, u) {
1120 yprp_restr(ctx, &add->musts[u], "must", "condition", NULL);
FredGand944bdc2019-11-05 21:57:07 +08001121 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001122 LY_ARRAY_FOR(add->uniques, u) {
1123 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, add->uniques[u], add->exts);
FredGand944bdc2019-11-05 21:57:07 +08001124 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001125 LY_ARRAY_FOR(add->dflts, u) {
1126 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, add->dflts[u], add->exts);
FredGand944bdc2019-11-05 21:57:07 +08001127 }
1128 ypr_config(ctx, add->flags, add->exts, NULL);
1129 ypr_mandatory(ctx, add->flags, add->exts, NULL);
1130 if (add->flags & LYS_SET_MIN) {
1131 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, add->exts, add->min);
1132 }
1133 if (add->flags & LYS_SET_MAX) {
1134 if (add->max) {
1135 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, add->exts, add->max);
1136 } else {
1137 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", add->exts);
1138 }
1139 }
1140 } else if (elem->mod == LYS_DEV_REPLACE) {
1141 rpl = (struct lysp_deviate_rpl*)elem;
Radek Krejci241f6b52020-05-21 18:13:49 +02001142 ly_print(ctx->out, "replace\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001143 LEVEL++;
1144
1145 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, rpl->exts, NULL, 0);
1146 if (rpl->type) {
1147 yprp_type(ctx, rpl->type);
1148 }
1149 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, rpl->units, rpl->exts);
1150 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, rpl->dflt, rpl->exts);
1151 ypr_config(ctx, rpl->flags, rpl->exts, NULL);
1152 ypr_mandatory(ctx, rpl->flags, rpl->exts, NULL);
1153 if (rpl->flags & LYS_SET_MIN) {
1154 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, rpl->exts, rpl->min);
1155 }
1156 if (rpl->flags & LYS_SET_MAX) {
1157 if (rpl->max) {
1158 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, rpl->exts, rpl->max);
1159 } else {
1160 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", rpl->exts);
1161 }
1162 }
1163 } else if (elem->mod == LYS_DEV_DELETE) {
1164 del = (struct lysp_deviate_del*)elem;
Radek Krejci241f6b52020-05-21 18:13:49 +02001165 ly_print(ctx->out, "delete\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001166 LEVEL++;
1167
1168 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, del->exts, NULL, 0);
1169 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, del->units, del->exts);
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001170 LY_ARRAY_FOR(del->musts, u) {
1171 yprp_restr(ctx, &del->musts[u], "must", "condition", NULL);
FredGand944bdc2019-11-05 21:57:07 +08001172 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001173 LY_ARRAY_FOR(del->uniques, u) {
1174 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, del->uniques[u], del->exts);
FredGand944bdc2019-11-05 21:57:07 +08001175 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001176 LY_ARRAY_FOR(del->dflts, u) {
1177 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, del->dflts[u], del->exts);
FredGand944bdc2019-11-05 21:57:07 +08001178 }
1179 }
1180
1181 LEVEL--;
1182 ypr_close(ctx, "deviate", 1);
1183 }
1184
1185 LEVEL--;
1186 ypr_close(ctx, "deviation", 1);
1187}
1188
1189/**
1190 * @brief Minimal print of a schema.
1191 *
1192 * To print parsed schema when the parsed form was already removed
1193 */
1194static LY_ERR
1195ypr_missing_format(struct ypr_ctx *ctx, const struct lys_module *module)
1196{
1197 /* module-header-stmts */
1198 if (module->version) {
1199 if (module->version) {
1200 ypr_substmt(ctx, LYEXT_SUBSTMT_VERSION, 0, module->version == LYS_VERSION_1_1 ? "1.1" : "1", NULL);
1201 }
1202 }
1203 ypr_substmt(ctx, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns, NULL);
1204 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, module->prefix, NULL);
1205
1206 /* meta-stmts */
1207 if (module->org || module->contact || module->dsc || module->ref) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001208 ly_print(ctx->out, "\n");
FredGand944bdc2019-11-05 21:57:07 +08001209 }
1210 ypr_substmt(ctx, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org, NULL);
1211 ypr_substmt(ctx, LYEXT_SUBSTMT_CONTACT, 0, module->contact, NULL);
1212 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc, NULL);
1213 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, module->ref, NULL);
1214
1215 /* revision-stmts */
1216 if (module->revision) {
1217 ypr_open(ctx, "revision", "date", module->revision, -1);
1218 }
1219
1220 LEVEL--;
1221 ypr_close(ctx, "module", 1);
1222 ly_print_flush(ctx->out);
1223
1224 return LY_SUCCESS;
1225}
1226
1227static void
1228ypr_xmlns(struct ypr_ctx *ctx, const struct lys_module *module, unsigned int indent)
1229{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001230 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001231
Radek Krejci241f6b52020-05-21 18:13:49 +02001232 ly_print(ctx->out, "%*sxmlns=\"%s\"", indent + INDENT, YIN_NS_URI);
1233 ly_print(ctx->out, "\n%*sxmlns:%s=\"%s\"", indent + INDENT, module->prefix, module->ns);
FredGand944bdc2019-11-05 21:57:07 +08001234
1235 struct lysp_module *modp = module->parsed;
1236
1237 LY_ARRAY_FOR(modp->imports, u){
Radek Krejci241f6b52020-05-21 18:13:49 +02001238 ly_print(ctx->out, "\n%*sxmlns:%s=\"%s\"", indent + INDENT, modp->imports[u].prefix, modp->imports[u].module->ns);
FredGand944bdc2019-11-05 21:57:07 +08001239 }
1240}
1241
1242struct ext_substmt_info_s stmt_attr_info[] = {
1243 {NULL, NULL, 0}, /**< LY_STMT_NONE*/
1244 {"status", "value", SUBST_FLAG_ID}, /**< LY_STMT_STATUS */
1245 {"config", "value", SUBST_FLAG_ID}, /**< LY_STMT_CONFIG */
1246 {"mandatory", "value", SUBST_FLAG_ID}, /**< LY_STMT_MANDATORY */
1247 {"units", "name", SUBST_FLAG_ID}, /**< LY_STMT_UNITS */
1248 {"default", "value", SUBST_FLAG_ID}, /**< LY_STMT_DEFAULT */
1249 {"type", "name", SUBST_FLAG_ID}, /**< LY_STMT_TYPE */
1250 {"action", "name", SUBST_FLAG_ID}, /**< LY_STMT_ACTION */
1251 {"anydata", "name", SUBST_FLAG_ID}, /**< LY_STMT_ANYDATA */
1252 {"anyxml", "name", SUBST_FLAG_ID}, /**< LY_STMT_ANYXML */
1253 {"argument", "name", SUBST_FLAG_ID}, /**< LY_STMT_ARGUMENT */
1254 {"augment", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_AUGMENT */
1255 {"base", "name", SUBST_FLAG_ID}, /**< LY_STMT_BASE */
1256 {"belongs-to", "module", SUBST_FLAG_ID}, /**< LY_STMT_BELONGS_TO */
1257 {"bit", "name", SUBST_FLAG_ID}, /**< LY_STMT_BIT */
1258 {"case", "name", SUBST_FLAG_ID}, /**< LY_STMT_CASE */
1259 {"choice", "name", SUBST_FLAG_ID}, /**< LY_STMT_CHOICE */
1260 {"contact", "text", SUBST_FLAG_YIN},/**< LY_STMT_CONTACT */
1261 {"container", "name", SUBST_FLAG_ID}, /**< LY_STMT_CONTAINER */
1262 {"description", "text", SUBST_FLAG_YIN},/**< LY_STMT_DESCRIPTION */
1263 {"deviate", "value", SUBST_FLAG_ID}, /**< LY_STMT_DEVIATE */
1264 {"deviation", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_DEVIATION */
1265 {"enum", "name", SUBST_FLAG_ID}, /**< LY_STMT_ENUM */
1266 {"error-app-tag", "value", SUBST_FLAG_ID}, /**< LY_STMT_ERROR_APP_TAG */
1267 {"error-message", "value", SUBST_FLAG_YIN},/**< LY_STMT_ERROR_MESSAGE */
1268 {"extension", "name", SUBST_FLAG_ID}, /**< LY_STMT_EXTENSION */
1269 {"feature", "name", SUBST_FLAG_ID}, /**< LY_STMT_FEATURE */
1270 {"fraction-digits", "value", SUBST_FLAG_ID}, /**< LY_STMT_FRACTION_DIGITS */
1271 {"grouping", "name", SUBST_FLAG_ID}, /**< LY_STMT_GROUPING */
1272 {"identity", "name", SUBST_FLAG_ID}, /**< LY_STMT_IDENTITY */
1273 {"if-feature", "name", SUBST_FLAG_ID}, /**< LY_STMT_IF_FEATURE */
1274 {"import", "module", SUBST_FLAG_ID}, /**< LY_STMT_IMPORT */
1275 {"include", "module", SUBST_FLAG_ID}, /**< LY_STMT_INCLUDE */
1276 {"input", NULL, 0}, /**< LY_STMT_INPUT */
1277 {"key", "value", SUBST_FLAG_ID}, /**< LY_STMT_KEY */
1278 {"leaf", "name", SUBST_FLAG_ID}, /**< LY_STMT_LEAF */
1279 {"leaf-list", "name", SUBST_FLAG_ID}, /**< LY_STMT_LEAF_LIST */
1280 {"length", "value", SUBST_FLAG_ID}, /**< LY_STMT_LENGTH */
1281 {"list", "name", SUBST_FLAG_ID}, /**< LY_STMT_LIST */
1282 {"max-elements", "value", SUBST_FLAG_ID}, /**< LY_STMT_MAX_ELEMENTS */
1283 {"min-elements", "value", SUBST_FLAG_ID}, /**< LY_STMT_MIN_ELEMENTS */
1284 {"modifier", "value", SUBST_FLAG_ID}, /**< LY_STMT_MODIFIER */
1285 {"module", "name", SUBST_FLAG_ID}, /**< LY_STMT_MODULE */
1286 {"must", "condition", SUBST_FLAG_ID}, /**< LY_STMT_MUST */
1287 {"namespace", "uri", SUBST_FLAG_ID}, /**< LY_STMT_NAMESPACE */
1288 {"notification", "name", SUBST_FLAG_ID}, /**< LY_STMT_NOTIFICATION */
1289 {"ordered-by", "value", SUBST_FLAG_ID}, /**< LY_STMT_ORDERED_BY */
1290 {"organization", "text", SUBST_FLAG_YIN},/**< LY_STMT_ORGANIZATION */
1291 {"output", NULL, 0}, /**< LY_STMT_OUTPUT */
1292 {"path", "value", SUBST_FLAG_ID}, /**< LY_STMT_PATH */
1293 {"pattern", "value", SUBST_FLAG_ID}, /**< LY_STMT_PATTERN */
1294 {"position", "value", SUBST_FLAG_ID}, /**< LY_STMT_POSITION */
1295 {"prefix", "value", SUBST_FLAG_ID}, /**< LY_STMT_PREFIX */
1296 {"presence", "value", SUBST_FLAG_ID}, /**< LY_STMT_PRESENCE */
1297 {"range", "value", SUBST_FLAG_ID}, /**< LY_STMT_RANGE */
1298 {"reference", "text", SUBST_FLAG_YIN},/**< LY_STMT_REFERENCE */
1299 {"refine", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_REFINE */
1300 {"require-instance", "value", SUBST_FLAG_ID}, /**< LY_STMT_REQUIRE_INSTANCE */
1301 {"revision", "date", SUBST_FLAG_ID}, /**< LY_STMT_REVISION */
1302 {"revision-date", "date", SUBST_FLAG_ID}, /**< LY_STMT_REVISION_DATE */
1303 {"rpc", "name", SUBST_FLAG_ID}, /**< LY_STMT_RPC */
1304 {"submodule", "name", SUBST_FLAG_ID}, /**< LY_STMT_SUBMODULE */
1305 {"typedef", "name", SUBST_FLAG_ID}, /**< LY_STMT_TYPEDEF */
1306 {"unique", "tag", SUBST_FLAG_ID}, /**< LY_STMT_UNIQUE */
1307 {"uses", "name", SUBST_FLAG_ID}, /**< LY_STMT_USES */
1308 {"value", "value", SUBST_FLAG_ID}, /**< LY_STMT_VALUE */
1309 {"when", "condition", SUBST_FLAG_ID}, /**< LY_STMT_WHEN */
1310 {"yang-version", "value", SUBST_FLAG_ID}, /**< LY_STMT_YANG_VERSION */
1311 {"yin-element", "value", SUBST_FLAG_ID}, /**< LY_STMT_YIN_ELEMENT */
1312 {NULL, NULL, 0}, /**< LY_STMT_EXTENSION_INSTANCE */
1313 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_SEMICOLON */
1314 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_LEFT_BRACE */
1315 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_RIGHT_BRACE */
1316 {NULL, NULL, 0}, /**< LY_STMT_ARG_TEXT */
1317 {NULL, NULL, 0}, /**< LY_STMT_ARG_VALUE */
1318};
1319
1320static void
1321yprp_stmt(struct ypr_ctx *ctx, struct lysp_stmt *stmt)
1322{
1323 struct lysp_stmt *childstmt;
1324 int flag = stmt->child ? 1 : -1;
1325
1326 /* TODO:
1327 the extension instance substatements in extension instances (LY_STMT_EXTENSION_INSTANCE)
1328 cannot find the compiled information, so it is needed to be done,
1329 currently it is ignored */
1330 if(stmt_attr_info[stmt->kw].name) {
1331 if(stmt_attr_info[stmt->kw].flags & SUBST_FLAG_YIN) {
1332 ypr_open(ctx, stmt->stmt, NULL, NULL, flag);
1333 ypr_yin_arg(ctx, stmt_attr_info[stmt->kw].arg, stmt->arg);
1334 }
1335 else {
1336 ypr_open(ctx, stmt->stmt, stmt_attr_info[stmt->kw].arg, stmt->arg, flag);
1337 }
1338 }
1339
1340 if (stmt->child) {
1341 LEVEL++;
1342 LY_LIST_FOR(stmt->child, childstmt) {
1343 yprp_stmt(ctx, childstmt);
1344 }
1345 LEVEL--;
1346 ypr_close(ctx, stmt->stmt, flag);
1347 }
1348}
1349
1350/**
1351 * @param[in] count Number of extensions to print, 0 to print them all.
1352 */
1353static void
1354yprp_extension_instances(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001355 struct lysp_ext_instance *ext, int *flag, LY_ARRAY_COUNT_TYPE count)
FredGand944bdc2019-11-05 21:57:07 +08001356{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001357 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001358 char *str;
1359 struct lysp_stmt *stmt;
1360 const char *argument;
1361 const char *ext_argument;
1362
1363 if (!count && ext) {
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001364 count = LY_ARRAY_COUNT(ext);
FredGand944bdc2019-11-05 21:57:07 +08001365 }
1366 LY_ARRAY_FOR(ext, u) {
1367 if (!count) {
1368 break;
1369 }
1370
1371 count--;
1372 if (ext->insubstmt != substmt || ext->insubstmt_index != substmt_index) {
1373 continue;
1374 }
1375
1376 if (!ext->compiled && ext->yin) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001377 ly_print(ctx->out, "%*s<%s/> <!-- Model comes from different input format, extensions must be resolved first. -->\n", INDENT, ext[u].name);
FredGand944bdc2019-11-05 21:57:07 +08001378 continue;
1379 }
1380
1381 ypr_close_parent(ctx, flag);
1382 int inner_flag = 0;
1383 argument = NULL;
1384 ext_argument = NULL;
1385
1386 if (ext[u].compiled) {
1387 argument = ext[u].compiled->argument;
1388 ext_argument = ext[u].compiled->def->argument;
1389 } else {
1390 argument = ext[u].argument;
1391 }
1392
1393 if (ext->yin) {
1394 ypr_open(ctx, ext[u].name, NULL, NULL, 1);
1395 if (asprintf(&str, "%s:%s", ext[u].compiled->def->module->prefix, ext_argument) == -1) {
1396 LOGMEM(ctx->module->ctx);
1397 ctx->out->status = LY_EMEM;
1398 return;
1399 }
1400 LEVEL++;
1401 inner_flag = 1;
1402 ypr_yin_arg(ctx, str, argument);
1403 free(str);
1404 str = NULL;
1405 LEVEL--;
1406 } else {
1407 ypr_open(ctx, ext[u].name, ext_argument, argument, inner_flag);
1408 }
1409
1410 LEVEL++;
1411 LY_LIST_FOR(ext[u].child, stmt) {
1412 ypr_close_parent(ctx, &inner_flag);
1413 yprp_stmt(ctx, stmt);
1414 }
1415 LEVEL--;
1416 ypr_close(ctx, ext[u].name, inner_flag);
1417 }
1418}
1419
1420LY_ERR
Radek Krejci241f6b52020-05-21 18:13:49 +02001421yin_print_parsed(struct ly_out *out, const struct lys_module *module)
FredGand944bdc2019-11-05 21:57:07 +08001422{
1423 unsigned int u;
1424 struct lysp_node *data;
1425 struct lysp_module *modp = module->parsed;
1426 struct ypr_ctx ctx_ = {.out = out, .level = 0, .module = module}, *ctx = &ctx_;
1427
Radek Krejci241f6b52020-05-21 18:13:49 +02001428 ly_print(ctx->out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1429 ly_print(ctx->out, "%*s<module name=\"%s\"\n", INDENT, module->name);
FredGand944bdc2019-11-05 21:57:07 +08001430 ypr_xmlns(ctx, module, 8);
Radek Krejci241f6b52020-05-21 18:13:49 +02001431 ly_print(ctx->out, ">\n");
FredGand944bdc2019-11-05 21:57:07 +08001432
1433 LEVEL++;
1434
1435 if (!modp) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001436 ly_print(ctx->out, "%*s<!-- PARSED INFORMATION ARE NOT FULLY PRESENT -->\n", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001437 return ypr_missing_format(ctx, module);
1438 }
1439
1440 /* module-header-stmts */
1441 if (module->version) {
1442 if (module->version) {
1443 ypr_substmt(ctx, LYEXT_SUBSTMT_VERSION, 0, module->version == LYS_VERSION_1_1 ? "1.1" : "1", modp->exts);
1444 }
1445 }
1446 ypr_substmt(ctx, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns, modp->exts);
1447 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, module->prefix, modp->exts);
1448
1449 /* linkage-stmts */
1450 LY_ARRAY_FOR(modp->imports, u) {
1451 ypr_open(ctx, "import", "module", modp->imports[u].module->name, 1);
1452 LEVEL++;
1453 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->imports[u].exts, NULL, 0);
1454 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, modp->imports[u].prefix, modp->imports[u].exts);
1455 if (modp->imports[u].rev[0]) {
1456 ypr_substmt(ctx, LYEXT_SUBSTMT_REVISIONDATE, 0, modp->imports[u].rev, modp->imports[u].exts);
1457 }
1458 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, modp->imports[u].dsc, modp->imports[u].exts);
1459 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, modp->imports[u].ref, modp->imports[u].exts);
1460 LEVEL--;
1461 ypr_close(ctx, "import", 1);
1462 }
1463 LY_ARRAY_FOR(modp->includes, u) {
1464 if (modp->includes[u].rev[0] || modp->includes[u].dsc || modp->includes[u].ref || modp->includes[u].exts) {
1465 ypr_open(ctx, "include", "module", modp->includes[u].submodule->name, 1);
1466 LEVEL++;
1467 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->includes[u].exts, NULL, 0);
1468 if (modp->includes[u].rev[0]) {
1469 ypr_substmt(ctx, LYEXT_SUBSTMT_REVISIONDATE, 0, modp->includes[u].rev, modp->includes[u].exts);
1470 }
1471 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, modp->includes[u].dsc, modp->includes[u].exts);
1472 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, modp->includes[u].ref, modp->includes[u].exts);
1473 LEVEL--;
Radek Krejci241f6b52020-05-21 18:13:49 +02001474 ly_print(out, "%*s}\n", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001475 } else {
1476 ypr_open(ctx, "include", "module", modp->includes[u].submodule->name, -1);
1477 }
1478 }
1479
1480 /* meta-stmts */
1481 if (module->org || module->contact || module->dsc || module->ref) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001482 ly_print(out, "\n");
FredGand944bdc2019-11-05 21:57:07 +08001483 }
1484 ypr_substmt(ctx, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org, modp->exts);
1485 ypr_substmt(ctx, LYEXT_SUBSTMT_CONTACT, 0, module->contact, modp->exts);
1486 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc, modp->exts);
1487 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, module->ref, modp->exts);
1488
1489 /* revision-stmts */
1490 if (modp->revs) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001491 ly_print(out, "\n");
FredGand944bdc2019-11-05 21:57:07 +08001492 }
1493 LY_ARRAY_FOR(modp->revs, u) {
1494 yprp_revision(ctx, &modp->revs[u]);
1495 }
1496 /* body-stmts */
1497 LY_ARRAY_FOR(modp->extensions, u) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001498 ly_print(out, "\n");
FredGand944bdc2019-11-05 21:57:07 +08001499 yprp_extension(ctx, &modp->extensions[u]);
1500 }
1501 if (modp->exts) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001502 ly_print(out, "\n");
FredGand944bdc2019-11-05 21:57:07 +08001503 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, module->parsed->exts, NULL, 0);
1504 }
1505
1506 LY_ARRAY_FOR(modp->features, u) {
1507 yprp_feature(ctx, &modp->features[u]);
1508 }
1509
1510 LY_ARRAY_FOR(modp->identities, u) {
1511 yprp_identity(ctx, &modp->identities[u]);
1512 }
1513
1514 LY_ARRAY_FOR(modp->typedefs, u) {
1515 yprp_typedef(ctx, &modp->typedefs[u]);
1516 }
1517
1518 LY_ARRAY_FOR(modp->groupings, u) {
1519 yprp_grouping(ctx, &modp->groupings[u]);
1520 }
1521
1522 LY_LIST_FOR(modp->data, data) {
1523 yprp_node(ctx, data);
1524 }
1525
1526 LY_ARRAY_FOR(modp->augments, u) {
1527 yprp_augment(ctx, &modp->augments[u]);
1528 }
1529
1530 LY_ARRAY_FOR(modp->rpcs, u) {
1531 yprp_action(ctx, &modp->rpcs[u]);
1532 }
1533
1534 LY_ARRAY_FOR(modp->notifs, u) {
1535 yprp_notification(ctx, &modp->notifs[u]);
1536 }
1537
1538 LY_ARRAY_FOR(modp->deviations, u) {
1539 yprp_deviation(ctx, &modp->deviations[u]);
1540 }
1541
1542 LEVEL--;
Radek Krejci241f6b52020-05-21 18:13:49 +02001543 ly_print(out, "%*s</module>\n", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001544 ly_print_flush(out);
1545
1546 return LY_SUCCESS;
1547}
1548