blob: 460285c939e9c63cf0606e4adeeb8550160099bb [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
Michal Vasko7c8439f2020-08-05 13:25:19 +020048ypr_open(struct ypr_ctx *ctx, const char *elem_name, const char *attr_name, const char *attr_value, int flag)
FredGand944bdc2019-11-05 21:57:07 +080049{
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
FredGand944bdc2019-11-05 21:57:07 +080093static void
94ypr_substmt(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text, void *ext)
95{
Michal Vaskofd69e1d2020-07-03 11:57:17 +020096 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +080097 int extflag = 0;
98
99 if (!text) {
100 /* nothing to print */
101 return;
102 }
103
104 if (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) {
105 extflag = 1;
106 ypr_open(ctx, ext_substmt_info[substmt].name, NULL, NULL, extflag);
107 } else {
108 ypr_open(ctx, ext_substmt_info[substmt].name, ext_substmt_info[substmt].arg, text, extflag);
109 }
110
111 LEVEL++;
112 LY_ARRAY_FOR(ext, u) {
113 if (((struct lysp_ext_instance*)ext)[u].insubstmt != substmt || ((struct lysp_ext_instance*)ext)[u].insubstmt_index != substmt_index) {
114 continue;
115 }
116 yprp_extension_instances(ctx, substmt, substmt_index, &((struct lysp_ext_instance*)ext)[u], &extflag, 1);
117 }
118
119 /* argument as yin-element */
120 if (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) {
121 ypr_yin_arg(ctx, ext_substmt_info[substmt].arg, text);
122 }
123
124 LEVEL--;
125 ypr_close(ctx, ext_substmt_info[substmt].name, extflag);
126}
127
128static void
129ypr_unsigned(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, void *exts, unsigned int attr_value)
130{
131 char *str;
132 if (asprintf(&str, "%u", attr_value) == -1) {
133 LOGMEM(ctx->module->ctx);
134 ctx->out->status = LY_EMEM;
135 return;
136 }
137 ypr_substmt(ctx, substmt, substmt_index, str, exts);
138 free(str);
139}
140
141static void
142ypr_signed(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, void *exts, signed int attr_value)
143{
144 char *str;
145
146 if (asprintf(&str, "%d", attr_value) == -1) {
147 LOGMEM(ctx->module->ctx);
148 ctx->out->status = LY_EMEM;
149 return;
150 }
151 ypr_substmt(ctx, substmt, substmt_index, str, exts);
152 free(str);
153}
154
155static void
156yprp_revision(struct ypr_ctx *ctx, const struct lysp_revision *rev)
157{
158 if (rev->dsc || rev->ref || rev->exts) {
159 ypr_open(ctx, "revision", "date", rev->date, 1);
160 LEVEL++;
161 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, rev->exts, NULL, 0);
162 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, rev->dsc, rev->exts);
163 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, rev->ref, rev->exts);
164 LEVEL--;
165 ypr_close(ctx, "revision", 1);
166 } else {
167 ypr_open(ctx, "revision", "date", rev->date, -1);
168 }
169}
170
171static void
172ypr_mandatory(struct ypr_ctx *ctx, uint16_t flags, void *exts, int *flag)
173{
174 if (flags & LYS_MAND_MASK) {
175 ypr_close_parent(ctx, flag);
176 ypr_substmt(ctx, LYEXT_SUBSTMT_MANDATORY, 0, (flags & LYS_MAND_TRUE) ? "true" : "false", exts);
177 }
178}
179
180static void
181ypr_config(struct ypr_ctx *ctx, uint16_t flags, void *exts, int *flag)
182{
183 if (flags & LYS_CONFIG_MASK) {
184 ypr_close_parent(ctx, flag);
185 ypr_substmt(ctx, LYEXT_SUBSTMT_CONFIG, 0, (flags & LYS_CONFIG_W) ? "true" : "false", exts);
186 }
187}
188
189static void
190ypr_status(struct ypr_ctx *ctx, uint16_t flags, void *exts, int *flag)
191{
192 const char *status = NULL;
193
194 if (flags & LYS_STATUS_CURR) {
195 ypr_close_parent(ctx, flag);
196 status = "current";
197 } else if (flags & LYS_STATUS_DEPRC) {
198 ypr_close_parent(ctx, flag);
199 status = "deprecated";
200 } else if (flags & LYS_STATUS_OBSLT) {
201 ypr_close_parent(ctx, flag);
202 status = "obsolete";
203 }
204
205 ypr_substmt(ctx, LYEXT_SUBSTMT_STATUS, 0, status, exts);
206}
207
208static void
209ypr_description(struct ypr_ctx *ctx, const char *dsc, void *exts, int *flag)
210{
211 if (dsc) {
212 ypr_close_parent(ctx, flag);
213 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, dsc, exts);
214 }
215}
216
217static void
218ypr_reference(struct ypr_ctx *ctx, const char *ref, void *exts, int *flag)
219{
220 if (ref) {
221 ypr_close_parent(ctx, flag);
222 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, ref, exts);
223 }
224}
225
226static void
227yprp_iffeatures(struct ypr_ctx *ctx, const char **iff, struct lysp_ext_instance *exts, int *flag)
228{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200229 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800230 int extflag;
231
232 LY_ARRAY_FOR(iff, u) {
233 ypr_close_parent(ctx, flag);
234 extflag = 0;
235
Radek Krejci241f6b52020-05-21 18:13:49 +0200236 ly_print(ctx->out, "%*s<if-feature name=\"%s", INDENT, iff[u]);
FredGand944bdc2019-11-05 21:57:07 +0800237
238 /* extensions */
239 LEVEL++;
240 LY_ARRAY_FOR(exts, u) {
241 if (exts[u].insubstmt != LYEXT_SUBSTMT_IFFEATURE || exts[u].insubstmt_index != u) {
242 continue;
243 }
244 yprp_extension_instances(ctx, LYEXT_SUBSTMT_IFFEATURE, u, &exts[u], &extflag, 1);
245 }
246 LEVEL--;
Radek Krejci241f6b52020-05-21 18:13:49 +0200247 ly_print(ctx->out, "\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +0800248 }
249}
250
251static void
252yprp_extension(struct ypr_ctx *ctx, const struct lysp_ext *ext)
253{
254 int flag = 0, flag2 = 0;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200255 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800256
257 ypr_open(ctx, "extension", "name", ext->name, flag);
258 LEVEL++;
259
260 if (ext->exts) {
261 ypr_close_parent(ctx, &flag);
262 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, ext->exts, &flag, 0);
263 }
264
265 if (ext->argument) {
266 ypr_close_parent(ctx, &flag);
267 ypr_open(ctx, "argument", "name", ext->argument, flag2);
268
269 LEVEL++;
270 if (ext->exts) {
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200271 u = -1;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200272 while ((u = lysp_ext_instance_iter(ext->exts, u + 1, LYEXT_SUBSTMT_ARGUMENT)) != LY_ARRAY_COUNT(ext->exts)) {
FredGand944bdc2019-11-05 21:57:07 +0800273 ypr_close_parent(ctx, &flag2);
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200274 yprp_extension_instances(ctx, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->exts[u], &flag2, 1);
FredGand944bdc2019-11-05 21:57:07 +0800275 }
276 }
277 if ((ext->flags & LYS_YINELEM_MASK) ||
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200278 (ext->exts && lysp_ext_instance_iter(ext->exts, 0, LYEXT_SUBSTMT_YINELEM) != LY_ARRAY_COUNT(ext->exts))) {
FredGand944bdc2019-11-05 21:57:07 +0800279 ypr_close_parent(ctx, &flag2);
280 ypr_substmt(ctx, LYEXT_SUBSTMT_YINELEM, 0, (ext->flags & LYS_YINELEM_TRUE) ? "true" : "false", ext->exts);
281 }
282 LEVEL--;
283 ypr_close(ctx, "argument", flag2);
284 }
285
286 ypr_status(ctx, ext->flags, ext->exts, &flag);
287 ypr_description(ctx, ext->dsc, ext->exts, &flag);
288 ypr_reference(ctx, ext->ref, ext->exts, &flag);
289
290 LEVEL--;
291 ypr_close(ctx, "extension", flag);
292}
293
294static void
295yprp_feature(struct ypr_ctx *ctx, const struct lysp_feature *feat)
296{
297 int flag = 0;
298
299 ypr_open(ctx, "feature", "name", feat->name, flag);
300 LEVEL++;
301 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, feat->exts, &flag, 0);
302 yprp_iffeatures(ctx, feat->iffeatures, feat->exts, &flag);
303 ypr_status(ctx, feat->flags, feat->exts, &flag);
304 ypr_description(ctx, feat->dsc, feat->exts, &flag);
305 ypr_reference(ctx, feat->ref, feat->exts, &flag);
306 LEVEL--;
307 ypr_close(ctx, "feature", flag);
308}
309
310static void
311yprp_identity(struct ypr_ctx *ctx, const struct lysp_ident *ident)
312{
313 int flag = 0;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200314 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800315
316 ypr_open(ctx, "identity", "name", ident->name, flag);
317 LEVEL++;
318
319 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, ident->exts, &flag, 0);
320 yprp_iffeatures(ctx, ident->iffeatures, ident->exts, &flag);
321
322 LY_ARRAY_FOR(ident->bases, u) {
323 ypr_close_parent(ctx, &flag);
324 ypr_substmt(ctx, LYEXT_SUBSTMT_BASE, u, ident->bases[u], ident->exts);
325 }
326
327 ypr_status(ctx, ident->flags, ident->exts, &flag);
328 ypr_description(ctx, ident->dsc, ident->exts, &flag);
329 ypr_reference(ctx, ident->ref, ident->exts, &flag);
330
331 LEVEL--;
332 ypr_close(ctx, "identity", flag);
333}
334
335static void
336yprp_restr(struct ypr_ctx *ctx, const struct lysp_restr *restr, const char *name, const char *attr, int *flag)
337{
338 (void)flag;
339 int inner_flag = 0;
340
341 if (!restr) {
342 return;
343 }
344
Radek Krejci241f6b52020-05-21 18:13:49 +0200345 ly_print(ctx->out, "%*s<%s %s=\"", INDENT, name, attr);
FredGand944bdc2019-11-05 21:57:07 +0800346 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 +0200347 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800348
349 LEVEL++;
350 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, restr->exts, &inner_flag, 0);
351 if (restr->arg[0] == 0x15) {
352 ypr_close_parent(ctx, &inner_flag);
353 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
354 ypr_substmt(ctx, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match", restr->exts);
355 }
356 if (restr->emsg) {
357 ypr_close_parent(ctx, &inner_flag);
358 ypr_substmt(ctx, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg, restr->exts);
359 }
360 if (restr->eapptag) {
361 ypr_close_parent(ctx, &inner_flag);
362 ypr_substmt(ctx, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag, restr->exts);
363 }
364 ypr_description(ctx, restr->dsc, restr->exts, &inner_flag);
365 ypr_reference(ctx, restr->ref, restr->exts, &inner_flag);
366
367 LEVEL--;
368 ypr_close(ctx, name, inner_flag);
369}
370
371static void
372yprp_when(struct ypr_ctx *ctx, struct lysp_when *when, int *flag)
373{
374 int inner_flag = 0;
375 (void)flag;
376
377 if (!when) {
378 return;
379 }
380
Radek Krejci241f6b52020-05-21 18:13:49 +0200381 ly_print(ctx->out, "%*s<when condition=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800382 lyxml_dump_text(ctx->out, when->cond, 1);
Radek Krejci241f6b52020-05-21 18:13:49 +0200383 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800384
385 LEVEL++;
386 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, when->exts, &inner_flag, 0);
387 ypr_description(ctx, when->dsc, when->exts, &inner_flag);
388 ypr_reference(ctx, when->ref, when->exts, &inner_flag);
389 LEVEL--;
390 ypr_close(ctx, "when", inner_flag);
391}
392
393static void
394yprp_enum(struct ypr_ctx *ctx, const struct lysp_type_enum *items, LY_DATA_TYPE type, int *flag)
395{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200396 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800397 int inner_flag;
398 (void)flag;
399
400 LY_ARRAY_FOR(items, u) {
401 if (type == LY_TYPE_BITS) {
Radek Krejci241f6b52020-05-21 18:13:49 +0200402 ly_print(ctx->out, "%*s<bit name=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800403 lyxml_dump_text(ctx->out, items[u].name, 1);
Radek Krejci241f6b52020-05-21 18:13:49 +0200404 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800405 } else { /* LY_TYPE_ENUM */
Radek Krejci241f6b52020-05-21 18:13:49 +0200406 ly_print(ctx->out, "%*s<enum name=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800407 lyxml_dump_text(ctx->out, items[u].name, 1);
Radek Krejci241f6b52020-05-21 18:13:49 +0200408 ly_print(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800409 }
410 inner_flag = 0;
411 LEVEL++;
412 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, items[u].exts, &inner_flag, 0);
413 yprp_iffeatures(ctx, items[u].iffeatures, items[u].exts, &inner_flag);
414 if (items[u].flags & LYS_SET_VALUE) {
415 if (type == LY_TYPE_BITS) {
416 ypr_close_parent(ctx, &inner_flag);
417 ypr_unsigned(ctx, LYEXT_SUBSTMT_POSITION, 0, items[u].exts, items[u].value);
418 } else { /* LY_TYPE_ENUM */
419 ypr_close_parent(ctx, &inner_flag);
420 ypr_signed(ctx, LYEXT_SUBSTMT_VALUE, 0, items[u].exts, items[u].value);
421 }
422 }
423 ypr_status(ctx, items[u].flags, items[u].exts, &inner_flag);
424 ypr_description(ctx, items[u].dsc, items[u].exts, &inner_flag);
425 ypr_reference(ctx, items[u].ref, items[u].exts, &inner_flag);
426 LEVEL--;
427 ypr_close(ctx, type == LY_TYPE_BITS ? "bit" : "enum", inner_flag);
428 }
429}
430
431static void
432yprp_type(struct ypr_ctx *ctx, const struct lysp_type *type)
433{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200434 LY_ARRAY_COUNT_TYPE u;
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200435 int flag = 0;
436
FredGand944bdc2019-11-05 21:57:07 +0800437 if (!ctx || !type) {
438 return;
439 }
440
FredGand944bdc2019-11-05 21:57:07 +0800441 ypr_open(ctx, "type", "name", type->name, flag);
442 LEVEL++;
443
444 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, type->exts, &flag, 0);
445
446 if (type->range || type->length || type->patterns || type->bits || type->enums) {
447 ypr_close_parent(ctx, &flag);
448 }
449 yprp_restr(ctx, type->range, "range", "value", &flag);
450 yprp_restr(ctx, type->length, "length", "value", &flag);
451 LY_ARRAY_FOR(type->patterns, u) {
452 yprp_restr(ctx, &type->patterns[u], "pattern", "value", &flag);
453 }
454 yprp_enum(ctx, type->bits, LY_TYPE_BITS, &flag);
455 yprp_enum(ctx, type->enums, LY_TYPE_ENUM, &flag);
456
457 if (type->path) {
458 ypr_close_parent(ctx, &flag);
Michal Vasko004d3152020-06-11 19:59:22 +0200459 ypr_substmt(ctx, LYEXT_SUBSTMT_PATH, 0, type->path->expr, type->exts);
FredGand944bdc2019-11-05 21:57:07 +0800460 }
461 if (type->flags & LYS_SET_REQINST) {
462 ypr_close_parent(ctx, &flag);
463 ypr_substmt(ctx, LYEXT_SUBSTMT_REQINSTANCE, 0, type->require_instance ? "true" : "false", type->exts);
464 }
465 if (type->flags & LYS_SET_FRDIGITS) {
466 ypr_close_parent(ctx, &flag);
467 ypr_unsigned(ctx, LYEXT_SUBSTMT_FRACDIGITS, 0, type->exts, type->fraction_digits);
468 }
469 LY_ARRAY_FOR(type->bases, u) {
470 ypr_close_parent(ctx, &flag);
471 ypr_substmt(ctx, LYEXT_SUBSTMT_BASE, u, type->bases[u], type->exts);
472 }
473 LY_ARRAY_FOR(type->types, u) {
474 ypr_close_parent(ctx, &flag);
475 yprp_type(ctx, &type->types[u]);
476 }
477
478 LEVEL--;
479 ypr_close(ctx, "type", flag);
480}
481
482static void
483yprp_typedef(struct ypr_ctx *ctx, const struct lysp_tpdf *tpdf)
484{
485 LYOUT_CHECK(ctx->out);
486
487 ypr_open(ctx, "typedef", "name", tpdf->name, 1);
488 LEVEL++;
489
490 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, tpdf->exts, NULL, 0);
491
492 yprp_type(ctx, &tpdf->type);
493
494 if (tpdf->units) {
495 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, tpdf->exts);
496 }
497 if (tpdf->dflt) {
498 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, tpdf->dflt, tpdf->exts);
499 }
500
501 ypr_status(ctx, tpdf->flags, tpdf->exts, NULL);
502 ypr_description(ctx, tpdf->dsc, tpdf->exts, NULL);
503 ypr_reference(ctx, tpdf->ref, tpdf->exts, NULL);
504
505 LEVEL--;
506 ypr_close(ctx, "typedef", 1);
507}
508
509static void yprp_node(struct ypr_ctx *ctx, const struct lysp_node *node);
510static void yprp_action(struct ypr_ctx *ctx, const struct lysp_action *action);
511
512static void
513yprp_grouping(struct ypr_ctx *ctx, const struct lysp_grp *grp)
514{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200515 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800516 int flag = 0;
517 struct lysp_node *data;
518
519 LYOUT_CHECK(ctx->out);
520
521 ypr_open(ctx, "grouping", "name", grp->name, flag);
522 LEVEL++;
523
524 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, grp->exts, &flag, 0);
525 ypr_status(ctx, grp->flags, grp->exts, &flag);
526 ypr_description(ctx, grp->dsc, grp->exts, &flag);
527 ypr_reference(ctx, grp->ref, grp->exts, &flag);
528
529 LY_ARRAY_FOR(grp->typedefs, u) {
530 ypr_close_parent(ctx, &flag);
531 yprp_typedef(ctx, &grp->typedefs[u]);
532 }
533
534 LY_ARRAY_FOR(grp->groupings, u) {
535 ypr_close_parent(ctx, &flag);
536 yprp_grouping(ctx, &grp->groupings[u]);
537 }
538
539 LY_LIST_FOR(grp->data, data) {
540 ypr_close_parent(ctx, &flag);
541 yprp_node(ctx, data);
542 }
543
544 LY_ARRAY_FOR(grp->actions, u) {
545 ypr_close_parent(ctx, &flag);
546 yprp_action(ctx, &grp->actions[u]);
547 }
548
549 LEVEL--;
550 ypr_close(ctx, "grouping", flag);
551}
552
553static void
554yprp_inout(struct ypr_ctx *ctx, const struct lysp_action_inout *inout, int *flag)
555{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200556 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800557 struct lysp_node *data;
558
559 if (!inout->nodetype) {
560 /* nodetype not set -> input/output is empty */
561 return;
562 }
563 ypr_close_parent(ctx, flag);
564
565 ypr_open(ctx, (inout->nodetype == LYS_INPUT ? "input" : "output"), NULL, NULL, *flag);
566 LEVEL++;
567
568 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, inout->exts, NULL, 0);
569 LY_ARRAY_FOR(inout->musts, u) {
570 yprp_restr(ctx, &inout->musts[u], "must", "condition", NULL);
571 }
572 LY_ARRAY_FOR(inout->typedefs, u) {
573 yprp_typedef(ctx, &inout->typedefs[u]);
574 }
575 LY_ARRAY_FOR(inout->groupings, u) {
576 yprp_grouping(ctx, &inout->groupings[u]);
577 }
578
579 LY_LIST_FOR(inout->data, data) {
580 yprp_node(ctx, data);
581 }
582
583 LEVEL--;
584 ypr_close(ctx, (inout->nodetype == LYS_INPUT ? "input" : "output"), 1);
585}
586
587static void
588yprp_notification(struct ypr_ctx *ctx, const struct lysp_notif *notif)
589{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200590 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800591 int flag = 0;
592 struct lysp_node *data;
593
594 LYOUT_CHECK(ctx->out);
595
596 ypr_open(ctx, "notification", "name", notif->name, flag);
597
598 LEVEL++;
599 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, notif->exts, &flag, 0);
600 yprp_iffeatures(ctx, notif->iffeatures, notif->exts, &flag);
601
602 LY_ARRAY_FOR(notif->musts, u) {
603 ypr_close_parent(ctx, &flag);
604 yprp_restr(ctx, &notif->musts[u], "must", "condition", &flag);
605 }
606 ypr_status(ctx, notif->flags, notif->exts, &flag);
607 ypr_description(ctx, notif->dsc, notif->exts, &flag);
608 ypr_reference(ctx, notif->ref, notif->exts, &flag);
609
610 LY_ARRAY_FOR(notif->typedefs, u) {
611 ypr_close_parent(ctx, &flag);
612 yprp_typedef(ctx, &notif->typedefs[u]);
613 }
614
615 LY_ARRAY_FOR(notif->groupings, u) {
616 ypr_close_parent(ctx, &flag);
617 yprp_grouping(ctx, &notif->groupings[u]);
618 }
619
620 LY_LIST_FOR(notif->data, data) {
621 ypr_close_parent(ctx, &flag);
622 yprp_node(ctx, data);
623 }
624
625 LEVEL--;
626 ypr_close(ctx, "notification", flag);
627}
628
629static void
630yprp_action(struct ypr_ctx *ctx, const struct lysp_action *action)
631{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200632 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800633 int flag = 0;
634
635 LYOUT_CHECK(ctx->out);
636
637 ypr_open(ctx, action->parent ? "action" : "rpc", "name", action->name, flag);
638
639 LEVEL++;
640 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, action->exts, &flag, 0);
641 yprp_iffeatures(ctx, action->iffeatures, action->exts, &flag);
642 ypr_status(ctx, action->flags, action->exts, &flag);
643 ypr_description(ctx, action->dsc, action->exts, &flag);
644 ypr_reference(ctx, action->ref, action->exts, &flag);
645
646 LY_ARRAY_FOR(action->typedefs, u) {
647 ypr_close_parent(ctx, &flag);
648 yprp_typedef(ctx, &action->typedefs[u]);
649 }
650
651 LY_ARRAY_FOR(action->groupings, u) {
652 ypr_close_parent(ctx, &flag);
653 yprp_grouping(ctx, &action->groupings[u]);
654 }
655
656 yprp_inout(ctx, &action->input, &flag);
657 yprp_inout(ctx, &action->output, &flag);
658
659 LEVEL--;
660 ypr_close(ctx, action->parent ? "action" : "rpc", flag);
661}
662
663static void
664yprp_node_common1(struct ypr_ctx *ctx, const struct lysp_node *node, int *flag)
665{
666 ypr_open(ctx, lys_nodetype2str(node->nodetype), "name", node->name, *flag);
667 LEVEL++;
668
669 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, node->exts, flag, 0);
670 yprp_when(ctx, node->when, flag);
671 yprp_iffeatures(ctx, node->iffeatures, node->exts, flag);
672}
673
674static void
675yprp_node_common2(struct ypr_ctx *ctx, const struct lysp_node *node, int *flag)
676{
677 ypr_config(ctx, node->flags, node->exts, flag);
678 if (node->nodetype & (LYS_CHOICE | LYS_LEAF | LYS_ANYDATA)) {
679 ypr_mandatory(ctx, node->flags, node->exts, flag);
680 }
681 ypr_status(ctx, node->flags, node->exts, flag);
682 ypr_description(ctx, node->dsc, node->exts, flag);
683 ypr_reference(ctx, node->ref, node->exts, flag);
684}
685
686static void
687yprp_container(struct ypr_ctx *ctx, const struct lysp_node *node)
688{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200689 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800690 int flag = 0;
691 struct lysp_node *child;
692 struct lysp_node_container *cont = (struct lysp_node_container *)node;
693
694 yprp_node_common1(ctx, node, &flag);
695
696 LY_ARRAY_FOR(cont->musts, u) {
697 ypr_close_parent(ctx, &flag);
698 yprp_restr(ctx, &cont->musts[u], "must", "condition", &flag);
699 }
700 if (cont->presence) {
701 ypr_close_parent(ctx, &flag);
702 ypr_substmt(ctx, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence, cont->exts);
703 }
704
705 yprp_node_common2(ctx, node, &flag);
706
707 LY_ARRAY_FOR(cont->typedefs, u) {
708 ypr_close_parent(ctx, &flag);
709 yprp_typedef(ctx, &cont->typedefs[u]);
710 }
711
712 LY_ARRAY_FOR(cont->groupings, u) {
713 ypr_close_parent(ctx, &flag);
714 yprp_grouping(ctx, &cont->groupings[u]);
715 }
716
717 LY_LIST_FOR(cont->child, child) {
718 ypr_close_parent(ctx, &flag);
719 yprp_node(ctx, child);
720 }
721
722 LY_ARRAY_FOR(cont->actions, u) {
723 ypr_close_parent(ctx, &flag);
724 yprp_action(ctx, &cont->actions[u]);
725 }
726
727 LY_ARRAY_FOR(cont->notifs, u) {
728 ypr_close_parent(ctx, &flag);
729 yprp_notification(ctx, &cont->notifs[u]);
730 }
731
732 LEVEL--;
733 ypr_close(ctx, "container", flag);
734}
735
736static void
737yprp_case(struct ypr_ctx *ctx, const struct lysp_node *node)
738{
739 int flag = 0;
740 struct lysp_node *child;
741 struct lysp_node_case *cas = (struct lysp_node_case *)node;
742
743 yprp_node_common1(ctx, node, &flag);
744 yprp_node_common2(ctx, node, &flag);
745
746 LY_LIST_FOR(cas->child, child) {
747 ypr_close_parent(ctx, &flag);
748 yprp_node(ctx, child);
749 }
750
751 LEVEL--;
752 ypr_close(ctx, "case", flag);
753}
754
755static void
756yprp_choice(struct ypr_ctx *ctx, const struct lysp_node *node)
757{
758 int flag = 0;
759 struct lysp_node *child;
760 struct lysp_node_choice *choice = (struct lysp_node_choice *)node;
761
762 yprp_node_common1(ctx, node, &flag);
763
764 if (choice->dflt) {
765 ypr_close_parent(ctx, &flag);
766 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt, choice->exts);
767 }
768
769 yprp_node_common2(ctx, node, &flag);
770
771 LY_LIST_FOR(choice->child, child) {
772 ypr_close_parent(ctx, &flag);
773 yprp_node(ctx, child);
774 }
775
776 LEVEL--;
777 ypr_close(ctx, "choice", flag);
778}
779
780static void
781yprp_leaf(struct ypr_ctx *ctx, const struct lysp_node *node)
782{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200783 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800784 struct lysp_node_leaf *leaf = (struct lysp_node_leaf *)node;
785
786 int flag = 1;
787 yprp_node_common1(ctx, node, &flag);
788
789 yprp_type(ctx, &leaf->type);
790 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, leaf->units, leaf->exts);
791 LY_ARRAY_FOR(leaf->musts, u) {
792 yprp_restr(ctx, &leaf->musts[u], "must", "condition", &flag);
793 }
794 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, leaf->dflt, leaf->exts);
795
796 yprp_node_common2(ctx, node, &flag);
797
798 LEVEL--;
799 ypr_close(ctx, "leaf", flag);
800}
801
802static void
803yprp_leaflist(struct ypr_ctx *ctx, const struct lysp_node *node)
804{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200805 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800806 struct lysp_node_leaflist *llist = (struct lysp_node_leaflist *)node;
807 int flag = 1;
808
809 yprp_node_common1(ctx, node, &flag);
810
811 yprp_type(ctx, &llist->type);
812 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, llist->units, llist->exts);
813 LY_ARRAY_FOR(llist->musts, u) {
814 yprp_restr(ctx, &llist->musts[u], "must", "condition", NULL);
815 }
816 LY_ARRAY_FOR(llist->dflts, u) {
817 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, llist->dflts[u], llist->exts);
818 }
819
820 ypr_config(ctx, node->flags, node->exts, NULL);
821
822 if (llist->flags & LYS_SET_MIN) {
823 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, llist->exts, llist->min);
824 }
825 if (llist->flags & LYS_SET_MAX) {
826 if (llist->max) {
827 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, llist->exts, llist->max);
828 } else {
829 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", llist->exts);
830 }
831 }
832
833 if (llist->flags & LYS_ORDBY_MASK) {
834 ypr_substmt(ctx, LYEXT_SUBSTMT_ORDEREDBY, 0, (llist->flags & LYS_ORDBY_USER) ? "user" : "system", llist->exts);
835 }
836
837 ypr_status(ctx, node->flags, node->exts, &flag);
838 ypr_description(ctx, node->dsc, node->exts, &flag);
839 ypr_reference(ctx, node->ref, node->exts, &flag);
840
841 LEVEL--;
842 ypr_close(ctx, "leaf-list", flag);
843}
844
845static void
846yprp_list(struct ypr_ctx *ctx, const struct lysp_node *node)
847{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200848 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800849 int flag = 0;
850 struct lysp_node *child;
851 struct lysp_node_list *list = (struct lysp_node_list *)node;
852
853 yprp_node_common1(ctx, node, &flag);
854
855 LY_ARRAY_FOR(list->musts, u) {
856 ypr_close_parent(ctx, &flag);
857 yprp_restr(ctx, &list->musts[u], "must", "condition", &flag);
858 }
859 if (list->key) {
860 ypr_close_parent(ctx, &flag);
861 ypr_substmt(ctx, LYEXT_SUBSTMT_KEY, 0, list->key, list->exts);
862 }
863 LY_ARRAY_FOR(list->uniques, u) {
864 ypr_close_parent(ctx, &flag);
865 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, list->uniques[u], list->exts);
866 }
867
868 ypr_config(ctx, node->flags, node->exts, NULL);
869
870 if (list->flags & LYS_SET_MIN) {
871 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, list->exts, list->min);
872 }
873 if (list->flags & LYS_SET_MAX) {
874 if (list->max) {
875 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, list->exts, list->max);
876 } else {
877 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", list->exts);
878 }
879 }
880
881 if (list->flags & LYS_ORDBY_MASK) {
882 ypr_close_parent(ctx, &flag);
883 ypr_substmt(ctx, LYEXT_SUBSTMT_ORDEREDBY, 0, (list->flags & LYS_ORDBY_USER) ? "user" : "system", list->exts);
884 }
885
886 ypr_status(ctx, node->flags, node->exts, &flag);
887 ypr_description(ctx, node->dsc, node->exts, &flag);
888 ypr_reference(ctx, node->ref, node->exts, &flag);
889
890 LY_ARRAY_FOR(list->typedefs, u) {
891 ypr_close_parent(ctx, &flag);
892 yprp_typedef(ctx, &list->typedefs[u]);
893 }
894
895 LY_ARRAY_FOR(list->groupings, u) {
896 ypr_close_parent(ctx, &flag);
897 yprp_grouping(ctx, &list->groupings[u]);
898 }
899
900 LY_LIST_FOR(list->child, child) {
901 ypr_close_parent(ctx, &flag);
902 yprp_node(ctx, child);
903 }
904
905 LY_ARRAY_FOR(list->actions, u) {
906 ypr_close_parent(ctx, &flag);
907 yprp_action(ctx, &list->actions[u]);
908 }
909
910 LY_ARRAY_FOR(list->notifs, u) {
911 ypr_close_parent(ctx, &flag);
912 yprp_notification(ctx, &list->notifs[u]);
913 }
914
915 LEVEL--;
916 ypr_close(ctx, "list", flag);
917}
918
919static void
920yprp_refine(struct ypr_ctx *ctx, struct lysp_refine *refine)
921{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200922 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800923 int flag = 0;
924
925 ypr_open(ctx, "refine", "target-node", refine->nodeid, flag);
926 LEVEL++;
927
928 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, refine->exts, &flag, 0);
929 yprp_iffeatures(ctx, refine->iffeatures, refine->exts, &flag);
930
931 LY_ARRAY_FOR(refine->musts, u) {
932 ypr_close_parent(ctx, &flag);
933 yprp_restr(ctx, &refine->musts[u], "must", "condition", &flag);
934 }
935
936 if (refine->presence) {
937 ypr_close_parent(ctx, &flag);
938 ypr_substmt(ctx, LYEXT_SUBSTMT_PRESENCE, 0, refine->presence, refine->exts);
939 }
940
941 LY_ARRAY_FOR(refine->dflts, u) {
942 ypr_close_parent(ctx, &flag);
943 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, refine->dflts[u], refine->exts);
944 }
945
946 ypr_config(ctx, refine->flags, refine->exts, &flag);
947 ypr_mandatory(ctx, refine->flags, refine->exts, &flag);
948
949 if (refine->flags & LYS_SET_MIN) {
950 ypr_close_parent(ctx, &flag);
951 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, refine->exts, refine->min);
952 }
953 if (refine->flags & LYS_SET_MAX) {
954 ypr_close_parent(ctx, &flag);
955 if (refine->max) {
956 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, refine->exts, refine->max);
957 } else {
958 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", refine->exts);
959 }
960 }
961
962 ypr_description(ctx, refine->dsc, refine->exts, &flag);
963 ypr_reference(ctx, refine->ref, refine->exts, &flag);
964
965 LEVEL--;
966 ypr_close(ctx, "refine", flag);
967}
968
969static void
970yprp_augment(struct ypr_ctx *ctx, const struct lysp_augment *aug)
971{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200972 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800973 struct lysp_node *child;
974
975 ypr_open(ctx, "augment", "target-node", aug->nodeid, 1);
976 LEVEL++;
977
978 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, aug->exts, NULL, 0);
979 yprp_when(ctx, aug->when, NULL);
980 yprp_iffeatures(ctx, aug->iffeatures, aug->exts, NULL);
981 ypr_status(ctx, aug->flags, aug->exts, NULL);
982 ypr_description(ctx, aug->dsc, aug->exts, NULL);
983 ypr_reference(ctx, aug->ref, aug->exts, NULL);
984
985 LY_LIST_FOR(aug->child, child) {
986 yprp_node(ctx, child);
987 }
988
989 LY_ARRAY_FOR(aug->actions, u) {
990 yprp_action(ctx, &aug->actions[u]);
991 }
992
993 LY_ARRAY_FOR(aug->notifs, u) {
994 yprp_notification(ctx, &aug->notifs[u]);
995 }
996
997 LEVEL--;
998 ypr_close(ctx, "augment", 1);
999}
1000
FredGand944bdc2019-11-05 21:57:07 +08001001static void
1002yprp_uses(struct ypr_ctx *ctx, const struct lysp_node *node)
1003{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001004 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001005 int flag = 0;
1006 struct lysp_node_uses *uses = (struct lysp_node_uses *)node;
1007
1008 yprp_node_common1(ctx, node, &flag);
1009 yprp_node_common2(ctx, node, &flag);
1010
1011 LY_ARRAY_FOR(uses->refines, u) {
1012 ypr_close_parent(ctx, &flag);
1013 yprp_refine(ctx, &uses->refines[u]);
1014 }
1015
1016 LY_ARRAY_FOR(uses->augments, u) {
1017 ypr_close_parent(ctx, &flag);
1018 yprp_augment(ctx, &uses->augments[u]);
1019 }
1020
1021 LEVEL--;
1022 ypr_close(ctx, "uses", flag);
1023}
1024
1025static void
1026yprp_anydata(struct ypr_ctx *ctx, const struct lysp_node *node)
1027{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001028 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001029 int flag = 0;
1030 struct lysp_node_anydata *any = (struct lysp_node_anydata *)node;
1031
1032 yprp_node_common1(ctx, node, &flag);
1033
1034 LY_ARRAY_FOR(any->musts, u) {
1035 ypr_close_parent(ctx, &flag);
1036 yprp_restr(ctx, &any->musts[u], "must", "condition", &flag);
1037 }
1038
1039 yprp_node_common2(ctx, node, &flag);
1040
1041 LEVEL--;
1042 ypr_close(ctx, lys_nodetype2str(node->nodetype), flag);
1043}
1044
1045static void
1046yprp_node(struct ypr_ctx *ctx, const struct lysp_node *node)
1047{
1048 LYOUT_CHECK(ctx->out);
1049
1050 switch (node->nodetype) {
1051 case LYS_CONTAINER:
1052 yprp_container(ctx, node);
1053 break;
1054 case LYS_CHOICE:
1055 yprp_choice(ctx, node);
1056 break;
1057 case LYS_LEAF:
1058 yprp_leaf(ctx, node);
1059 break;
1060 case LYS_LEAFLIST:
1061 yprp_leaflist(ctx, node);
1062 break;
1063 case LYS_LIST:
1064 yprp_list(ctx, node);
1065 break;
1066 case LYS_USES:
1067 yprp_uses(ctx, node);
1068 break;
1069 case LYS_ANYXML:
1070 case LYS_ANYDATA:
1071 yprp_anydata(ctx, node);
1072 break;
1073 case LYS_CASE:
1074 yprp_case(ctx, node);
1075 break;
1076 default:
1077 break;
1078 }
1079}
1080
1081static void
1082yprp_deviation(struct ypr_ctx *ctx, const struct lysp_deviation *deviation)
1083{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001084 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001085 struct lysp_deviate_add *add;
1086 struct lysp_deviate_rpl *rpl;
1087 struct lysp_deviate_del *del;
1088 struct lysp_deviate *elem;
1089
1090 ypr_open(ctx, "deviation", "target-node", deviation->nodeid, 1);
1091 LEVEL++;
1092
1093 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, deviation->exts, NULL, 0);
1094 ypr_description(ctx, deviation->dsc, deviation->exts, NULL);
1095 ypr_reference(ctx, deviation->ref, deviation->exts, NULL);
1096
1097 LY_LIST_FOR(deviation->deviates, elem) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001098 ly_print(ctx->out, "%*s<deviate value=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001099 if (elem->mod == LYS_DEV_NOT_SUPPORTED) {
1100 if (elem->exts) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001101 ly_print(ctx->out, "not-supported\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +08001102 LEVEL++;
1103
1104 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, elem->exts, NULL, 0);
1105 } else {
Radek Krejci241f6b52020-05-21 18:13:49 +02001106 ly_print(ctx->out, "not-supported\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +08001107 continue;
1108 }
1109 } else if (elem->mod == LYS_DEV_ADD) {
1110 add = (struct lysp_deviate_add*)elem;
Radek Krejci241f6b52020-05-21 18:13:49 +02001111 ly_print(ctx->out, "add\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001112 LEVEL++;
1113
1114 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, add->exts, NULL, 0);
1115 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, add->units, add->exts);
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001116 LY_ARRAY_FOR(add->musts, u) {
1117 yprp_restr(ctx, &add->musts[u], "must", "condition", NULL);
FredGand944bdc2019-11-05 21:57:07 +08001118 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001119 LY_ARRAY_FOR(add->uniques, u) {
1120 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, add->uniques[u], add->exts);
FredGand944bdc2019-11-05 21:57:07 +08001121 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001122 LY_ARRAY_FOR(add->dflts, u) {
1123 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, add->dflts[u], add->exts);
FredGand944bdc2019-11-05 21:57:07 +08001124 }
1125 ypr_config(ctx, add->flags, add->exts, NULL);
1126 ypr_mandatory(ctx, add->flags, add->exts, NULL);
1127 if (add->flags & LYS_SET_MIN) {
1128 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, add->exts, add->min);
1129 }
1130 if (add->flags & LYS_SET_MAX) {
1131 if (add->max) {
1132 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, add->exts, add->max);
1133 } else {
1134 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", add->exts);
1135 }
1136 }
1137 } else if (elem->mod == LYS_DEV_REPLACE) {
1138 rpl = (struct lysp_deviate_rpl*)elem;
Radek Krejci241f6b52020-05-21 18:13:49 +02001139 ly_print(ctx->out, "replace\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001140 LEVEL++;
1141
1142 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, rpl->exts, NULL, 0);
1143 if (rpl->type) {
1144 yprp_type(ctx, rpl->type);
1145 }
1146 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, rpl->units, rpl->exts);
1147 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, rpl->dflt, rpl->exts);
1148 ypr_config(ctx, rpl->flags, rpl->exts, NULL);
1149 ypr_mandatory(ctx, rpl->flags, rpl->exts, NULL);
1150 if (rpl->flags & LYS_SET_MIN) {
1151 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, rpl->exts, rpl->min);
1152 }
1153 if (rpl->flags & LYS_SET_MAX) {
1154 if (rpl->max) {
1155 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, rpl->exts, rpl->max);
1156 } else {
1157 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", rpl->exts);
1158 }
1159 }
1160 } else if (elem->mod == LYS_DEV_DELETE) {
1161 del = (struct lysp_deviate_del*)elem;
Radek Krejci241f6b52020-05-21 18:13:49 +02001162 ly_print(ctx->out, "delete\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001163 LEVEL++;
1164
1165 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, del->exts, NULL, 0);
1166 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, del->units, del->exts);
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001167 LY_ARRAY_FOR(del->musts, u) {
1168 yprp_restr(ctx, &del->musts[u], "must", "condition", NULL);
FredGand944bdc2019-11-05 21:57:07 +08001169 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001170 LY_ARRAY_FOR(del->uniques, u) {
1171 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, del->uniques[u], del->exts);
FredGand944bdc2019-11-05 21:57:07 +08001172 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001173 LY_ARRAY_FOR(del->dflts, u) {
1174 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, del->dflts[u], del->exts);
FredGand944bdc2019-11-05 21:57:07 +08001175 }
1176 }
1177
1178 LEVEL--;
1179 ypr_close(ctx, "deviate", 1);
1180 }
1181
1182 LEVEL--;
1183 ypr_close(ctx, "deviation", 1);
1184}
1185
FredGand944bdc2019-11-05 21:57:07 +08001186static void
1187ypr_xmlns(struct ypr_ctx *ctx, const struct lys_module *module, unsigned int indent)
1188{
Radek Krejci241f6b52020-05-21 18:13:49 +02001189 ly_print(ctx->out, "%*sxmlns=\"%s\"", indent + INDENT, YIN_NS_URI);
1190 ly_print(ctx->out, "\n%*sxmlns:%s=\"%s\"", indent + INDENT, module->prefix, module->ns);
Michal Vasko7c8439f2020-08-05 13:25:19 +02001191}
FredGand944bdc2019-11-05 21:57:07 +08001192
Michal Vasko7c8439f2020-08-05 13:25:19 +02001193static void
1194ypr_import_xmlns(struct ypr_ctx *ctx, const struct lysp_module *modp, unsigned int indent)
1195{
1196 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001197
1198 LY_ARRAY_FOR(modp->imports, u){
Radek Krejci241f6b52020-05-21 18:13:49 +02001199 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 +08001200 }
1201}
1202
1203struct ext_substmt_info_s stmt_attr_info[] = {
1204 {NULL, NULL, 0}, /**< LY_STMT_NONE*/
1205 {"status", "value", SUBST_FLAG_ID}, /**< LY_STMT_STATUS */
1206 {"config", "value", SUBST_FLAG_ID}, /**< LY_STMT_CONFIG */
1207 {"mandatory", "value", SUBST_FLAG_ID}, /**< LY_STMT_MANDATORY */
1208 {"units", "name", SUBST_FLAG_ID}, /**< LY_STMT_UNITS */
1209 {"default", "value", SUBST_FLAG_ID}, /**< LY_STMT_DEFAULT */
1210 {"type", "name", SUBST_FLAG_ID}, /**< LY_STMT_TYPE */
1211 {"action", "name", SUBST_FLAG_ID}, /**< LY_STMT_ACTION */
1212 {"anydata", "name", SUBST_FLAG_ID}, /**< LY_STMT_ANYDATA */
1213 {"anyxml", "name", SUBST_FLAG_ID}, /**< LY_STMT_ANYXML */
1214 {"argument", "name", SUBST_FLAG_ID}, /**< LY_STMT_ARGUMENT */
1215 {"augment", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_AUGMENT */
1216 {"base", "name", SUBST_FLAG_ID}, /**< LY_STMT_BASE */
1217 {"belongs-to", "module", SUBST_FLAG_ID}, /**< LY_STMT_BELONGS_TO */
1218 {"bit", "name", SUBST_FLAG_ID}, /**< LY_STMT_BIT */
1219 {"case", "name", SUBST_FLAG_ID}, /**< LY_STMT_CASE */
1220 {"choice", "name", SUBST_FLAG_ID}, /**< LY_STMT_CHOICE */
1221 {"contact", "text", SUBST_FLAG_YIN},/**< LY_STMT_CONTACT */
1222 {"container", "name", SUBST_FLAG_ID}, /**< LY_STMT_CONTAINER */
1223 {"description", "text", SUBST_FLAG_YIN},/**< LY_STMT_DESCRIPTION */
1224 {"deviate", "value", SUBST_FLAG_ID}, /**< LY_STMT_DEVIATE */
1225 {"deviation", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_DEVIATION */
1226 {"enum", "name", SUBST_FLAG_ID}, /**< LY_STMT_ENUM */
1227 {"error-app-tag", "value", SUBST_FLAG_ID}, /**< LY_STMT_ERROR_APP_TAG */
1228 {"error-message", "value", SUBST_FLAG_YIN},/**< LY_STMT_ERROR_MESSAGE */
1229 {"extension", "name", SUBST_FLAG_ID}, /**< LY_STMT_EXTENSION */
1230 {"feature", "name", SUBST_FLAG_ID}, /**< LY_STMT_FEATURE */
1231 {"fraction-digits", "value", SUBST_FLAG_ID}, /**< LY_STMT_FRACTION_DIGITS */
1232 {"grouping", "name", SUBST_FLAG_ID}, /**< LY_STMT_GROUPING */
1233 {"identity", "name", SUBST_FLAG_ID}, /**< LY_STMT_IDENTITY */
1234 {"if-feature", "name", SUBST_FLAG_ID}, /**< LY_STMT_IF_FEATURE */
1235 {"import", "module", SUBST_FLAG_ID}, /**< LY_STMT_IMPORT */
1236 {"include", "module", SUBST_FLAG_ID}, /**< LY_STMT_INCLUDE */
1237 {"input", NULL, 0}, /**< LY_STMT_INPUT */
1238 {"key", "value", SUBST_FLAG_ID}, /**< LY_STMT_KEY */
1239 {"leaf", "name", SUBST_FLAG_ID}, /**< LY_STMT_LEAF */
1240 {"leaf-list", "name", SUBST_FLAG_ID}, /**< LY_STMT_LEAF_LIST */
1241 {"length", "value", SUBST_FLAG_ID}, /**< LY_STMT_LENGTH */
1242 {"list", "name", SUBST_FLAG_ID}, /**< LY_STMT_LIST */
1243 {"max-elements", "value", SUBST_FLAG_ID}, /**< LY_STMT_MAX_ELEMENTS */
1244 {"min-elements", "value", SUBST_FLAG_ID}, /**< LY_STMT_MIN_ELEMENTS */
1245 {"modifier", "value", SUBST_FLAG_ID}, /**< LY_STMT_MODIFIER */
1246 {"module", "name", SUBST_FLAG_ID}, /**< LY_STMT_MODULE */
1247 {"must", "condition", SUBST_FLAG_ID}, /**< LY_STMT_MUST */
1248 {"namespace", "uri", SUBST_FLAG_ID}, /**< LY_STMT_NAMESPACE */
1249 {"notification", "name", SUBST_FLAG_ID}, /**< LY_STMT_NOTIFICATION */
1250 {"ordered-by", "value", SUBST_FLAG_ID}, /**< LY_STMT_ORDERED_BY */
1251 {"organization", "text", SUBST_FLAG_YIN},/**< LY_STMT_ORGANIZATION */
1252 {"output", NULL, 0}, /**< LY_STMT_OUTPUT */
1253 {"path", "value", SUBST_FLAG_ID}, /**< LY_STMT_PATH */
1254 {"pattern", "value", SUBST_FLAG_ID}, /**< LY_STMT_PATTERN */
1255 {"position", "value", SUBST_FLAG_ID}, /**< LY_STMT_POSITION */
1256 {"prefix", "value", SUBST_FLAG_ID}, /**< LY_STMT_PREFIX */
1257 {"presence", "value", SUBST_FLAG_ID}, /**< LY_STMT_PRESENCE */
1258 {"range", "value", SUBST_FLAG_ID}, /**< LY_STMT_RANGE */
1259 {"reference", "text", SUBST_FLAG_YIN},/**< LY_STMT_REFERENCE */
1260 {"refine", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_REFINE */
1261 {"require-instance", "value", SUBST_FLAG_ID}, /**< LY_STMT_REQUIRE_INSTANCE */
1262 {"revision", "date", SUBST_FLAG_ID}, /**< LY_STMT_REVISION */
1263 {"revision-date", "date", SUBST_FLAG_ID}, /**< LY_STMT_REVISION_DATE */
1264 {"rpc", "name", SUBST_FLAG_ID}, /**< LY_STMT_RPC */
1265 {"submodule", "name", SUBST_FLAG_ID}, /**< LY_STMT_SUBMODULE */
1266 {"typedef", "name", SUBST_FLAG_ID}, /**< LY_STMT_TYPEDEF */
1267 {"unique", "tag", SUBST_FLAG_ID}, /**< LY_STMT_UNIQUE */
1268 {"uses", "name", SUBST_FLAG_ID}, /**< LY_STMT_USES */
1269 {"value", "value", SUBST_FLAG_ID}, /**< LY_STMT_VALUE */
1270 {"when", "condition", SUBST_FLAG_ID}, /**< LY_STMT_WHEN */
1271 {"yang-version", "value", SUBST_FLAG_ID}, /**< LY_STMT_YANG_VERSION */
1272 {"yin-element", "value", SUBST_FLAG_ID}, /**< LY_STMT_YIN_ELEMENT */
1273 {NULL, NULL, 0}, /**< LY_STMT_EXTENSION_INSTANCE */
1274 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_SEMICOLON */
1275 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_LEFT_BRACE */
1276 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_RIGHT_BRACE */
1277 {NULL, NULL, 0}, /**< LY_STMT_ARG_TEXT */
1278 {NULL, NULL, 0}, /**< LY_STMT_ARG_VALUE */
1279};
1280
1281static void
1282yprp_stmt(struct ypr_ctx *ctx, struct lysp_stmt *stmt)
1283{
1284 struct lysp_stmt *childstmt;
1285 int flag = stmt->child ? 1 : -1;
1286
1287 /* TODO:
1288 the extension instance substatements in extension instances (LY_STMT_EXTENSION_INSTANCE)
1289 cannot find the compiled information, so it is needed to be done,
1290 currently it is ignored */
1291 if(stmt_attr_info[stmt->kw].name) {
1292 if(stmt_attr_info[stmt->kw].flags & SUBST_FLAG_YIN) {
1293 ypr_open(ctx, stmt->stmt, NULL, NULL, flag);
1294 ypr_yin_arg(ctx, stmt_attr_info[stmt->kw].arg, stmt->arg);
1295 }
1296 else {
1297 ypr_open(ctx, stmt->stmt, stmt_attr_info[stmt->kw].arg, stmt->arg, flag);
1298 }
1299 }
1300
1301 if (stmt->child) {
1302 LEVEL++;
1303 LY_LIST_FOR(stmt->child, childstmt) {
1304 yprp_stmt(ctx, childstmt);
1305 }
1306 LEVEL--;
1307 ypr_close(ctx, stmt->stmt, flag);
1308 }
1309}
1310
1311/**
1312 * @param[in] count Number of extensions to print, 0 to print them all.
1313 */
1314static void
1315yprp_extension_instances(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001316 struct lysp_ext_instance *ext, int *flag, LY_ARRAY_COUNT_TYPE count)
FredGand944bdc2019-11-05 21:57:07 +08001317{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001318 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001319 char *str;
1320 struct lysp_stmt *stmt;
1321 const char *argument;
1322 const char *ext_argument;
1323
1324 if (!count && ext) {
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001325 count = LY_ARRAY_COUNT(ext);
FredGand944bdc2019-11-05 21:57:07 +08001326 }
1327 LY_ARRAY_FOR(ext, u) {
1328 if (!count) {
1329 break;
1330 }
1331
1332 count--;
1333 if (ext->insubstmt != substmt || ext->insubstmt_index != substmt_index) {
1334 continue;
1335 }
1336
1337 if (!ext->compiled && ext->yin) {
Radek Krejci241f6b52020-05-21 18:13:49 +02001338 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 +08001339 continue;
1340 }
1341
1342 ypr_close_parent(ctx, flag);
1343 int inner_flag = 0;
1344 argument = NULL;
1345 ext_argument = NULL;
1346
1347 if (ext[u].compiled) {
1348 argument = ext[u].compiled->argument;
1349 ext_argument = ext[u].compiled->def->argument;
1350 } else {
1351 argument = ext[u].argument;
1352 }
1353
1354 if (ext->yin) {
1355 ypr_open(ctx, ext[u].name, NULL, NULL, 1);
1356 if (asprintf(&str, "%s:%s", ext[u].compiled->def->module->prefix, ext_argument) == -1) {
1357 LOGMEM(ctx->module->ctx);
1358 ctx->out->status = LY_EMEM;
1359 return;
1360 }
1361 LEVEL++;
1362 inner_flag = 1;
1363 ypr_yin_arg(ctx, str, argument);
1364 free(str);
1365 str = NULL;
1366 LEVEL--;
1367 } else {
1368 ypr_open(ctx, ext[u].name, ext_argument, argument, inner_flag);
1369 }
1370
1371 LEVEL++;
1372 LY_LIST_FOR(ext[u].child, stmt) {
1373 ypr_close_parent(ctx, &inner_flag);
1374 yprp_stmt(ctx, stmt);
1375 }
1376 LEVEL--;
1377 ypr_close(ctx, ext[u].name, inner_flag);
1378 }
1379}
1380
Michal Vasko7c8439f2020-08-05 13:25:19 +02001381static void
1382yin_print_parsed_linkage(struct ypr_ctx *ctx, const struct lysp_module *modp)
FredGand944bdc2019-11-05 21:57:07 +08001383{
Michal Vasko7c8439f2020-08-05 13:25:19 +02001384 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001385
FredGand944bdc2019-11-05 21:57:07 +08001386 LY_ARRAY_FOR(modp->imports, u) {
Michal Vasko7c8439f2020-08-05 13:25:19 +02001387 ypr_open(ctx, "import", "module", modp->imports[u].name, 1);
FredGand944bdc2019-11-05 21:57:07 +08001388 LEVEL++;
1389 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->imports[u].exts, NULL, 0);
1390 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, modp->imports[u].prefix, modp->imports[u].exts);
1391 if (modp->imports[u].rev[0]) {
1392 ypr_substmt(ctx, LYEXT_SUBSTMT_REVISIONDATE, 0, modp->imports[u].rev, modp->imports[u].exts);
1393 }
1394 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, modp->imports[u].dsc, modp->imports[u].exts);
1395 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, modp->imports[u].ref, modp->imports[u].exts);
1396 LEVEL--;
1397 ypr_close(ctx, "import", 1);
1398 }
1399 LY_ARRAY_FOR(modp->includes, u) {
1400 if (modp->includes[u].rev[0] || modp->includes[u].dsc || modp->includes[u].ref || modp->includes[u].exts) {
Michal Vasko7c8439f2020-08-05 13:25:19 +02001401 ypr_open(ctx, "include", "module", modp->includes[u].name, 1);
FredGand944bdc2019-11-05 21:57:07 +08001402 LEVEL++;
1403 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->includes[u].exts, NULL, 0);
1404 if (modp->includes[u].rev[0]) {
1405 ypr_substmt(ctx, LYEXT_SUBSTMT_REVISIONDATE, 0, modp->includes[u].rev, modp->includes[u].exts);
1406 }
1407 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, modp->includes[u].dsc, modp->includes[u].exts);
1408 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, modp->includes[u].ref, modp->includes[u].exts);
1409 LEVEL--;
Michal Vasko7c8439f2020-08-05 13:25:19 +02001410 ly_print(ctx->out, "%*s}\n", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001411 } else {
Michal Vasko7c8439f2020-08-05 13:25:19 +02001412 ypr_open(ctx, "include", "module", modp->includes[u].name, -1);
FredGand944bdc2019-11-05 21:57:07 +08001413 }
1414 }
Michal Vasko7c8439f2020-08-05 13:25:19 +02001415}
FredGand944bdc2019-11-05 21:57:07 +08001416
Michal Vasko7c8439f2020-08-05 13:25:19 +02001417static void
1418yin_print_parsed_body(struct ypr_ctx *ctx, const struct lysp_module *modp)
1419{
1420 LY_ARRAY_COUNT_TYPE u;
1421 struct lysp_node *data;
FredGand944bdc2019-11-05 21:57:07 +08001422
FredGand944bdc2019-11-05 21:57:07 +08001423 LY_ARRAY_FOR(modp->extensions, u) {
Michal Vasko7c8439f2020-08-05 13:25:19 +02001424 ly_print(ctx->out, "\n");
FredGand944bdc2019-11-05 21:57:07 +08001425 yprp_extension(ctx, &modp->extensions[u]);
1426 }
1427 if (modp->exts) {
Michal Vasko7c8439f2020-08-05 13:25:19 +02001428 ly_print(ctx->out, "\n");
1429 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->exts, NULL, 0);
FredGand944bdc2019-11-05 21:57:07 +08001430 }
1431
1432 LY_ARRAY_FOR(modp->features, u) {
1433 yprp_feature(ctx, &modp->features[u]);
1434 }
1435
1436 LY_ARRAY_FOR(modp->identities, u) {
1437 yprp_identity(ctx, &modp->identities[u]);
1438 }
1439
1440 LY_ARRAY_FOR(modp->typedefs, u) {
1441 yprp_typedef(ctx, &modp->typedefs[u]);
1442 }
1443
1444 LY_ARRAY_FOR(modp->groupings, u) {
1445 yprp_grouping(ctx, &modp->groupings[u]);
1446 }
1447
1448 LY_LIST_FOR(modp->data, data) {
1449 yprp_node(ctx, data);
1450 }
1451
1452 LY_ARRAY_FOR(modp->augments, u) {
1453 yprp_augment(ctx, &modp->augments[u]);
1454 }
1455
1456 LY_ARRAY_FOR(modp->rpcs, u) {
1457 yprp_action(ctx, &modp->rpcs[u]);
1458 }
1459
1460 LY_ARRAY_FOR(modp->notifs, u) {
1461 yprp_notification(ctx, &modp->notifs[u]);
1462 }
1463
1464 LY_ARRAY_FOR(modp->deviations, u) {
1465 yprp_deviation(ctx, &modp->deviations[u]);
1466 }
Michal Vasko7c8439f2020-08-05 13:25:19 +02001467}
1468
1469LY_ERR
1470yin_print_parsed_module(struct ly_out *out, const struct lys_module *module, const struct lysp_module *modp)
1471{
1472 LY_ARRAY_COUNT_TYPE u;
1473 struct ypr_ctx ctx_ = {.out = out, .level = 0, .module = module}, *ctx = &ctx_;
1474
1475 ly_print(ctx->out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1476 ly_print(ctx->out, "%*s<module name=\"%s\"\n", INDENT, module->name);
1477 ypr_xmlns(ctx, module, 8);
1478 ypr_import_xmlns(ctx, modp, 8);
1479 ly_print(ctx->out, ">\n");
1480
1481 LEVEL++;
1482
1483 /* module-header-stmts */
1484 if (module->version) {
1485 ypr_substmt(ctx, LYEXT_SUBSTMT_VERSION, 0, module->version == LYS_VERSION_1_1 ? "1.1" : "1", modp->exts);
1486 }
1487 ypr_substmt(ctx, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns, modp->exts);
1488 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, module->prefix, modp->exts);
1489
1490 /* linkage-stmts (import/include) */
1491 yin_print_parsed_linkage(ctx, modp);
1492
1493 /* meta-stmts */
1494 if (module->org || module->contact || module->dsc || module->ref) {
1495 ly_print(out, "\n");
1496 }
1497 ypr_substmt(ctx, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org, modp->exts);
1498 ypr_substmt(ctx, LYEXT_SUBSTMT_CONTACT, 0, module->contact, modp->exts);
1499 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc, modp->exts);
1500 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, module->ref, modp->exts);
1501
1502 /* revision-stmts */
1503 if (modp->revs) {
1504 ly_print(out, "\n");
1505 }
1506 LY_ARRAY_FOR(modp->revs, u) {
1507 yprp_revision(ctx, &modp->revs[u]);
1508 }
1509
1510 /* body-stmts */
1511 yin_print_parsed_body(ctx, modp);
FredGand944bdc2019-11-05 21:57:07 +08001512
1513 LEVEL--;
Radek Krejci241f6b52020-05-21 18:13:49 +02001514 ly_print(out, "%*s</module>\n", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001515 ly_print_flush(out);
1516
1517 return LY_SUCCESS;
1518}
1519
Michal Vasko7c8439f2020-08-05 13:25:19 +02001520static void
1521yprp_belongsto(struct ypr_ctx *ctx, const struct lysp_submodule *submodp)
1522{
1523 ypr_open(ctx, "belongs-to", "module", submodp->belongsto, 1);
1524 LEVEL++;
1525 yprp_extension_instances(ctx, LYEXT_SUBSTMT_BELONGSTO, 0, submodp->exts, NULL, 0);
1526 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, submodp->prefix, submodp->exts);
1527 LEVEL--;
1528 ypr_close(ctx, "belongs-to", 1);
1529}
1530
1531LY_ERR
1532yin_print_parsed_submodule(struct ly_out *out, const struct lys_module *module, const struct lysp_submodule *submodp)
1533{
1534 LY_ARRAY_COUNT_TYPE u;
1535 struct ypr_ctx ctx_ = {.out = out, .level = 0, .module = module}, *ctx = &ctx_;
1536
1537 ly_print(ctx->out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1538 ly_print(ctx->out, "%*s<submodule name=\"%s\"\n", INDENT, submodp->name);
1539 ypr_xmlns(ctx, module, 8);
1540 ypr_import_xmlns(ctx, (struct lysp_module *)submodp, 8);
1541 ly_print(ctx->out, ">\n");
1542
1543 LEVEL++;
1544
1545 /* submodule-header-stmts */
1546 if (submodp->version) {
1547 ypr_substmt(ctx, LYEXT_SUBSTMT_VERSION, 0, submodp->version == LYS_VERSION_1_1 ? "1.1" : "1", submodp->exts);
1548 }
1549 yprp_belongsto(ctx, submodp);
1550
1551 /* linkage-stmts (import/include) */
1552 yin_print_parsed_linkage(ctx, (struct lysp_module *)submodp);
1553
1554 /* meta-stmts */
1555 if (submodp->org || submodp->contact || submodp->dsc || submodp->ref) {
1556 ly_print(out, "\n");
1557 }
1558 ypr_substmt(ctx, LYEXT_SUBSTMT_ORGANIZATION, 0, submodp->org, submodp->exts);
1559 ypr_substmt(ctx, LYEXT_SUBSTMT_CONTACT, 0, submodp->contact, submodp->exts);
1560 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, submodp->dsc, submodp->exts);
1561 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, submodp->ref, submodp->exts);
1562
1563 /* revision-stmts */
1564 if (submodp->revs) {
1565 ly_print(out, "\n");
1566 }
1567 LY_ARRAY_FOR(submodp->revs, u) {
1568 yprp_revision(ctx, &submodp->revs[u]);
1569 }
1570
1571 /* body-stmts */
1572 yin_print_parsed_body(ctx, (struct lysp_module *)submodp);
1573
1574 LEVEL--;
1575 ly_print(out, "%*s</submodule>\n", INDENT);
1576 ly_print_flush(out);
1577
1578 return LY_SUCCESS;
1579}