blob: 91309cbde5742ba00602984e0312f1a29d5c3b1b [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 Krejci47fab892020-11-05 17:02:41 +010024#include "out.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020025#include "out_internal.h"
FredGand944bdc2019-11-05 21:57:07 +080026#include "printer_internal.h"
27#include "tree.h"
28#include "tree_schema.h"
29#include "tree_schema_internal.h"
FredGand944bdc2019-11-05 21:57:07 +080030#include "xml.h"
Michal Vasko004d3152020-06-11 19:59:22 +020031#include "xpath.h"
FredGand944bdc2019-11-05 21:57:07 +080032
33/**
34 * @brief YIN printer context.
35 */
36struct ypr_ctx {
Radek Krejci1deb5be2020-08-26 16:43:36 +020037 struct ly_out *out; /**< output specification */
38 uint16_t level; /**< current indentation level: 0 - no formatting, >= 1 indentation levels */
39 uint32_t options; /**< Schema output options (see @ref schemaprinterflags). */
FredGand944bdc2019-11-05 21:57:07 +080040 const struct lys_module *module; /**< schema to print */
41};
42
FredGand944bdc2019-11-05 21:57:07 +080043static void yprp_extension_instances(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
Radek Krejci1deb5be2020-08-26 16:43:36 +020044 struct lysp_ext_instance *ext, int8_t *flag, LY_ARRAY_COUNT_TYPE count);
FredGand944bdc2019-11-05 21:57:07 +080045
46static void
Radek Krejci1deb5be2020-08-26 16:43:36 +020047ypr_open(struct ypr_ctx *ctx, const char *elem_name, const char *attr_name, const char *attr_value, int8_t flag)
FredGand944bdc2019-11-05 21:57:07 +080048{
Michal Vasko5233e962020-08-14 14:26:20 +020049 ly_print_(ctx->out, "%*s<%s", INDENT, elem_name);
FredGand944bdc2019-11-05 21:57:07 +080050
51 if (attr_name) {
Michal Vasko5233e962020-08-14 14:26:20 +020052 ly_print_(ctx->out, " %s=\"", attr_name);
FredGand944bdc2019-11-05 21:57:07 +080053 lyxml_dump_text(ctx->out, attr_value, 1);
Michal Vasko5233e962020-08-14 14:26:20 +020054 ly_print_(ctx->out, "\"%s", flag == -1 ? "/>\n" : flag == 1 ? ">\n" : "");
FredGand944bdc2019-11-05 21:57:07 +080055 } else if (flag) {
Michal Vasko5233e962020-08-14 14:26:20 +020056 ly_print_(ctx->out, flag == -1 ? "/>\n" : ">\n");
FredGand944bdc2019-11-05 21:57:07 +080057 }
58}
59
60static void
Radek Krejci1deb5be2020-08-26 16:43:36 +020061ypr_close(struct ypr_ctx *ctx, const char *elem_name, int8_t flag)
FredGand944bdc2019-11-05 21:57:07 +080062{
63 if (flag) {
Michal Vasko5233e962020-08-14 14:26:20 +020064 ly_print_(ctx->out, "%*s</%s>\n", INDENT, elem_name);
FredGand944bdc2019-11-05 21:57:07 +080065 } else {
Michal Vasko5233e962020-08-14 14:26:20 +020066 ly_print_(ctx->out, "/>\n");
FredGand944bdc2019-11-05 21:57:07 +080067 }
68}
69
70/*
71 * par_close_flag
72 * 0 - parent not yet closed, printing >\n, setting flag to 1
73 * 1 or NULL - parent already closed, do nothing
74 */
75static void
Radek Krejci1deb5be2020-08-26 16:43:36 +020076ypr_close_parent(struct ypr_ctx *ctx, int8_t *par_close_flag)
FredGand944bdc2019-11-05 21:57:07 +080077{
78 if (par_close_flag && !(*par_close_flag)) {
79 (*par_close_flag) = 1;
Michal Vasko5233e962020-08-14 14:26:20 +020080 ly_print_(ctx->out, ">\n");
FredGand944bdc2019-11-05 21:57:07 +080081 }
82}
83
84static void
85ypr_yin_arg(struct ypr_ctx *ctx, const char *arg, const char *text)
86{
Michal Vasko5233e962020-08-14 14:26:20 +020087 ly_print_(ctx->out, "%*s<%s>", INDENT, arg);
FredGand944bdc2019-11-05 21:57:07 +080088 lyxml_dump_text(ctx->out, text, 0);
Michal Vasko5233e962020-08-14 14:26:20 +020089 ly_print_(ctx->out, "</%s>\n", arg);
FredGand944bdc2019-11-05 21:57:07 +080090}
91
FredGand944bdc2019-11-05 21:57:07 +080092static void
93ypr_substmt(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text, void *ext)
94{
Michal Vaskofd69e1d2020-07-03 11:57:17 +020095 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +020096 int8_t extflag = 0;
FredGand944bdc2019-11-05 21:57:07 +080097
98 if (!text) {
99 /* nothing to print */
100 return;
101 }
102
103 if (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) {
104 extflag = 1;
105 ypr_open(ctx, ext_substmt_info[substmt].name, NULL, NULL, extflag);
106 } else {
107 ypr_open(ctx, ext_substmt_info[substmt].name, ext_substmt_info[substmt].arg, text, extflag);
108 }
109
110 LEVEL++;
111 LY_ARRAY_FOR(ext, u) {
Michal Vasko69730152020-10-09 16:30:07 +0200112 if ((((struct lysp_ext_instance *)ext)[u].insubstmt != substmt) || (((struct lysp_ext_instance *)ext)[u].insubstmt_index != substmt_index)) {
FredGand944bdc2019-11-05 21:57:07 +0800113 continue;
114 }
Michal Vasko22df3f02020-08-24 13:29:22 +0200115 yprp_extension_instances(ctx, substmt, substmt_index, &((struct lysp_ext_instance *)ext)[u], &extflag, 1);
FredGand944bdc2019-11-05 21:57:07 +0800116 }
117
118 /* argument as yin-element */
119 if (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) {
120 ypr_yin_arg(ctx, ext_substmt_info[substmt].arg, text);
121 }
122
123 LEVEL--;
124 ypr_close(ctx, ext_substmt_info[substmt].name, extflag);
125}
126
127static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200128ypr_unsigned(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, void *exts, unsigned long int attr_value)
FredGand944bdc2019-11-05 21:57:07 +0800129{
130 char *str;
Michal Vasko69730152020-10-09 16:30:07 +0200131
Radek Krejci1deb5be2020-08-26 16:43:36 +0200132 if (asprintf(&str, "%lu", attr_value) == -1) {
FredGand944bdc2019-11-05 21:57:07 +0800133 LOGMEM(ctx->module->ctx);
FredGand944bdc2019-11-05 21:57:07 +0800134 return;
135 }
136 ypr_substmt(ctx, substmt, substmt_index, str, exts);
137 free(str);
138}
139
140static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200141ypr_signed(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index, void *exts, signed long int attr_value)
FredGand944bdc2019-11-05 21:57:07 +0800142{
143 char *str;
144
Radek Krejci1deb5be2020-08-26 16:43:36 +0200145 if (asprintf(&str, "%ld", attr_value) == -1) {
FredGand944bdc2019-11-05 21:57:07 +0800146 LOGMEM(ctx->module->ctx);
FredGand944bdc2019-11-05 21:57:07 +0800147 return;
148 }
149 ypr_substmt(ctx, substmt, substmt_index, str, exts);
150 free(str);
151}
152
153static void
154yprp_revision(struct ypr_ctx *ctx, const struct lysp_revision *rev)
155{
156 if (rev->dsc || rev->ref || rev->exts) {
157 ypr_open(ctx, "revision", "date", rev->date, 1);
158 LEVEL++;
159 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, rev->exts, NULL, 0);
160 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, rev->dsc, rev->exts);
161 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, rev->ref, rev->exts);
162 LEVEL--;
163 ypr_close(ctx, "revision", 1);
164 } else {
165 ypr_open(ctx, "revision", "date", rev->date, -1);
166 }
167}
168
169static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200170ypr_mandatory(struct ypr_ctx *ctx, uint16_t flags, void *exts, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800171{
172 if (flags & LYS_MAND_MASK) {
173 ypr_close_parent(ctx, flag);
174 ypr_substmt(ctx, LYEXT_SUBSTMT_MANDATORY, 0, (flags & LYS_MAND_TRUE) ? "true" : "false", exts);
175 }
176}
177
178static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200179ypr_config(struct ypr_ctx *ctx, uint16_t flags, void *exts, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800180{
181 if (flags & LYS_CONFIG_MASK) {
182 ypr_close_parent(ctx, flag);
183 ypr_substmt(ctx, LYEXT_SUBSTMT_CONFIG, 0, (flags & LYS_CONFIG_W) ? "true" : "false", exts);
184 }
185}
186
187static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200188ypr_status(struct ypr_ctx *ctx, uint16_t flags, void *exts, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800189{
190 const char *status = NULL;
191
192 if (flags & LYS_STATUS_CURR) {
193 ypr_close_parent(ctx, flag);
194 status = "current";
195 } else if (flags & LYS_STATUS_DEPRC) {
196 ypr_close_parent(ctx, flag);
197 status = "deprecated";
198 } else if (flags & LYS_STATUS_OBSLT) {
199 ypr_close_parent(ctx, flag);
200 status = "obsolete";
201 }
202
203 ypr_substmt(ctx, LYEXT_SUBSTMT_STATUS, 0, status, exts);
204}
205
206static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200207ypr_description(struct ypr_ctx *ctx, const char *dsc, void *exts, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800208{
209 if (dsc) {
210 ypr_close_parent(ctx, flag);
211 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, dsc, exts);
212 }
213}
214
215static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200216ypr_reference(struct ypr_ctx *ctx, const char *ref, void *exts, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800217{
218 if (ref) {
219 ypr_close_parent(ctx, flag);
220 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, ref, exts);
221 }
222}
223
224static void
Michal Vasko7f45cf22020-10-01 12:49:44 +0200225yprp_iffeatures(struct ypr_ctx *ctx, struct lysp_qname *iffs, struct lysp_ext_instance *exts, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800226{
Michal Vasko7f45cf22020-10-01 12:49:44 +0200227 LY_ARRAY_COUNT_TYPE u, v;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200228 int8_t extflag;
FredGand944bdc2019-11-05 21:57:07 +0800229
Michal Vasko7f45cf22020-10-01 12:49:44 +0200230 LY_ARRAY_FOR(iffs, u) {
FredGand944bdc2019-11-05 21:57:07 +0800231 ypr_close_parent(ctx, flag);
232 extflag = 0;
233
Michal Vasko7f45cf22020-10-01 12:49:44 +0200234 ly_print_(ctx->out, "%*s<if-feature name=\"%s", INDENT, iffs[u].str);
FredGand944bdc2019-11-05 21:57:07 +0800235
236 /* extensions */
237 LEVEL++;
Michal Vasko7f45cf22020-10-01 12:49:44 +0200238 LY_ARRAY_FOR(exts, v) {
239 yprp_extension_instances(ctx, LYEXT_SUBSTMT_IFFEATURE, u, &exts[v], &extflag, 1);
FredGand944bdc2019-11-05 21:57:07 +0800240 }
241 LEVEL--;
Michal Vasko5233e962020-08-14 14:26:20 +0200242 ly_print_(ctx->out, "\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +0800243 }
244}
245
246static void
247yprp_extension(struct ypr_ctx *ctx, const struct lysp_ext *ext)
248{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200249 int8_t flag = 0, flag2 = 0;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200250 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800251
252 ypr_open(ctx, "extension", "name", ext->name, flag);
253 LEVEL++;
254
255 if (ext->exts) {
256 ypr_close_parent(ctx, &flag);
257 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, ext->exts, &flag, 0);
258 }
259
260 if (ext->argument) {
261 ypr_close_parent(ctx, &flag);
262 ypr_open(ctx, "argument", "name", ext->argument, flag2);
263
264 LEVEL++;
265 if (ext->exts) {
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200266 u = -1;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200267 while ((u = lysp_ext_instance_iter(ext->exts, u + 1, LYEXT_SUBSTMT_ARGUMENT)) != LY_ARRAY_COUNT(ext->exts)) {
FredGand944bdc2019-11-05 21:57:07 +0800268 ypr_close_parent(ctx, &flag2);
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200269 yprp_extension_instances(ctx, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->exts[u], &flag2, 1);
FredGand944bdc2019-11-05 21:57:07 +0800270 }
271 }
272 if ((ext->flags & LYS_YINELEM_MASK) ||
Michal Vasko69730152020-10-09 16:30:07 +0200273 (ext->exts && (lysp_ext_instance_iter(ext->exts, 0, LYEXT_SUBSTMT_YINELEM) != LY_ARRAY_COUNT(ext->exts)))) {
FredGand944bdc2019-11-05 21:57:07 +0800274 ypr_close_parent(ctx, &flag2);
275 ypr_substmt(ctx, LYEXT_SUBSTMT_YINELEM, 0, (ext->flags & LYS_YINELEM_TRUE) ? "true" : "false", ext->exts);
276 }
277 LEVEL--;
278 ypr_close(ctx, "argument", flag2);
279 }
280
281 ypr_status(ctx, ext->flags, ext->exts, &flag);
282 ypr_description(ctx, ext->dsc, ext->exts, &flag);
283 ypr_reference(ctx, ext->ref, ext->exts, &flag);
284
285 LEVEL--;
286 ypr_close(ctx, "extension", flag);
287}
288
289static void
290yprp_feature(struct ypr_ctx *ctx, const struct lysp_feature *feat)
291{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200292 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800293
294 ypr_open(ctx, "feature", "name", feat->name, flag);
295 LEVEL++;
296 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, feat->exts, &flag, 0);
297 yprp_iffeatures(ctx, feat->iffeatures, feat->exts, &flag);
298 ypr_status(ctx, feat->flags, feat->exts, &flag);
299 ypr_description(ctx, feat->dsc, feat->exts, &flag);
300 ypr_reference(ctx, feat->ref, feat->exts, &flag);
301 LEVEL--;
302 ypr_close(ctx, "feature", flag);
303}
304
305static void
306yprp_identity(struct ypr_ctx *ctx, const struct lysp_ident *ident)
307{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200308 int8_t flag = 0;
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200309 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800310
311 ypr_open(ctx, "identity", "name", ident->name, flag);
312 LEVEL++;
313
314 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, ident->exts, &flag, 0);
315 yprp_iffeatures(ctx, ident->iffeatures, ident->exts, &flag);
316
317 LY_ARRAY_FOR(ident->bases, u) {
318 ypr_close_parent(ctx, &flag);
319 ypr_substmt(ctx, LYEXT_SUBSTMT_BASE, u, ident->bases[u], ident->exts);
320 }
321
322 ypr_status(ctx, ident->flags, ident->exts, &flag);
323 ypr_description(ctx, ident->dsc, ident->exts, &flag);
324 ypr_reference(ctx, ident->ref, ident->exts, &flag);
325
326 LEVEL--;
327 ypr_close(ctx, "identity", flag);
328}
329
330static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200331yprp_restr(struct ypr_ctx *ctx, const struct lysp_restr *restr, const char *name, const char *attr, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800332{
333 (void)flag;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200334 int8_t inner_flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800335
336 if (!restr) {
337 return;
338 }
339
Michal Vasko5233e962020-08-14 14:26:20 +0200340 ly_print_(ctx->out, "%*s<%s %s=\"", INDENT, name, attr);
Michal Vasko7f45cf22020-10-01 12:49:44 +0200341 lyxml_dump_text(ctx->out, (restr->arg.str[0] != 0x15 && restr->arg.str[0] != 0x06) ? restr->arg.str : &restr->arg.str[1], 1);
Michal Vasko5233e962020-08-14 14:26:20 +0200342 ly_print_(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800343
344 LEVEL++;
345 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, restr->exts, &inner_flag, 0);
Michal Vasko7f45cf22020-10-01 12:49:44 +0200346 if (restr->arg.str[0] == 0x15) {
FredGand944bdc2019-11-05 21:57:07 +0800347 ypr_close_parent(ctx, &inner_flag);
348 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
349 ypr_substmt(ctx, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match", restr->exts);
350 }
351 if (restr->emsg) {
352 ypr_close_parent(ctx, &inner_flag);
353 ypr_substmt(ctx, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg, restr->exts);
354 }
355 if (restr->eapptag) {
356 ypr_close_parent(ctx, &inner_flag);
357 ypr_substmt(ctx, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag, restr->exts);
358 }
359 ypr_description(ctx, restr->dsc, restr->exts, &inner_flag);
360 ypr_reference(ctx, restr->ref, restr->exts, &inner_flag);
361
362 LEVEL--;
363 ypr_close(ctx, name, inner_flag);
364}
365
366static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200367yprp_when(struct ypr_ctx *ctx, struct lysp_when *when, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800368{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200369 int8_t inner_flag = 0;
Michal Vasko69730152020-10-09 16:30:07 +0200370
FredGand944bdc2019-11-05 21:57:07 +0800371 (void)flag;
372
373 if (!when) {
374 return;
375 }
376
Michal Vasko5233e962020-08-14 14:26:20 +0200377 ly_print_(ctx->out, "%*s<when condition=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800378 lyxml_dump_text(ctx->out, when->cond, 1);
Michal Vasko5233e962020-08-14 14:26:20 +0200379 ly_print_(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800380
381 LEVEL++;
382 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, when->exts, &inner_flag, 0);
383 ypr_description(ctx, when->dsc, when->exts, &inner_flag);
384 ypr_reference(ctx, when->ref, when->exts, &inner_flag);
385 LEVEL--;
386 ypr_close(ctx, "when", inner_flag);
387}
388
389static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200390yprp_enum(struct ypr_ctx *ctx, const struct lysp_type_enum *items, LY_DATA_TYPE type, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800391{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200392 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200393 int8_t inner_flag;
Michal Vasko69730152020-10-09 16:30:07 +0200394
FredGand944bdc2019-11-05 21:57:07 +0800395 (void)flag;
396
397 LY_ARRAY_FOR(items, u) {
398 if (type == LY_TYPE_BITS) {
Michal Vasko5233e962020-08-14 14:26:20 +0200399 ly_print_(ctx->out, "%*s<bit name=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800400 lyxml_dump_text(ctx->out, items[u].name, 1);
Michal Vasko5233e962020-08-14 14:26:20 +0200401 ly_print_(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800402 } else { /* LY_TYPE_ENUM */
Michal Vasko5233e962020-08-14 14:26:20 +0200403 ly_print_(ctx->out, "%*s<enum name=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +0800404 lyxml_dump_text(ctx->out, items[u].name, 1);
Michal Vasko5233e962020-08-14 14:26:20 +0200405 ly_print_(ctx->out, "\"");
FredGand944bdc2019-11-05 21:57:07 +0800406 }
407 inner_flag = 0;
408 LEVEL++;
409 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, items[u].exts, &inner_flag, 0);
410 yprp_iffeatures(ctx, items[u].iffeatures, items[u].exts, &inner_flag);
411 if (items[u].flags & LYS_SET_VALUE) {
412 if (type == LY_TYPE_BITS) {
413 ypr_close_parent(ctx, &inner_flag);
414 ypr_unsigned(ctx, LYEXT_SUBSTMT_POSITION, 0, items[u].exts, items[u].value);
415 } else { /* LY_TYPE_ENUM */
416 ypr_close_parent(ctx, &inner_flag);
417 ypr_signed(ctx, LYEXT_SUBSTMT_VALUE, 0, items[u].exts, items[u].value);
418 }
419 }
420 ypr_status(ctx, items[u].flags, items[u].exts, &inner_flag);
421 ypr_description(ctx, items[u].dsc, items[u].exts, &inner_flag);
422 ypr_reference(ctx, items[u].ref, items[u].exts, &inner_flag);
423 LEVEL--;
424 ypr_close(ctx, type == LY_TYPE_BITS ? "bit" : "enum", inner_flag);
425 }
426}
427
428static void
429yprp_type(struct ypr_ctx *ctx, const struct lysp_type *type)
430{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200431 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200432 int8_t flag = 0;
Radek Krejci7eb54ba2020-05-18 16:30:04 +0200433
FredGand944bdc2019-11-05 21:57:07 +0800434 if (!ctx || !type) {
435 return;
436 }
437
FredGand944bdc2019-11-05 21:57:07 +0800438 ypr_open(ctx, "type", "name", type->name, flag);
439 LEVEL++;
440
441 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, type->exts, &flag, 0);
442
443 if (type->range || type->length || type->patterns || type->bits || type->enums) {
444 ypr_close_parent(ctx, &flag);
445 }
446 yprp_restr(ctx, type->range, "range", "value", &flag);
447 yprp_restr(ctx, type->length, "length", "value", &flag);
448 LY_ARRAY_FOR(type->patterns, u) {
449 yprp_restr(ctx, &type->patterns[u], "pattern", "value", &flag);
450 }
451 yprp_enum(ctx, type->bits, LY_TYPE_BITS, &flag);
452 yprp_enum(ctx, type->enums, LY_TYPE_ENUM, &flag);
453
454 if (type->path) {
455 ypr_close_parent(ctx, &flag);
Michal Vasko004d3152020-06-11 19:59:22 +0200456 ypr_substmt(ctx, LYEXT_SUBSTMT_PATH, 0, type->path->expr, type->exts);
FredGand944bdc2019-11-05 21:57:07 +0800457 }
458 if (type->flags & LYS_SET_REQINST) {
459 ypr_close_parent(ctx, &flag);
460 ypr_substmt(ctx, LYEXT_SUBSTMT_REQINSTANCE, 0, type->require_instance ? "true" : "false", type->exts);
461 }
462 if (type->flags & LYS_SET_FRDIGITS) {
463 ypr_close_parent(ctx, &flag);
464 ypr_unsigned(ctx, LYEXT_SUBSTMT_FRACDIGITS, 0, type->exts, type->fraction_digits);
465 }
466 LY_ARRAY_FOR(type->bases, u) {
467 ypr_close_parent(ctx, &flag);
468 ypr_substmt(ctx, LYEXT_SUBSTMT_BASE, u, type->bases[u], type->exts);
469 }
470 LY_ARRAY_FOR(type->types, u) {
471 ypr_close_parent(ctx, &flag);
472 yprp_type(ctx, &type->types[u]);
473 }
474
475 LEVEL--;
476 ypr_close(ctx, "type", flag);
477}
478
479static void
480yprp_typedef(struct ypr_ctx *ctx, const struct lysp_tpdf *tpdf)
481{
FredGand944bdc2019-11-05 21:57:07 +0800482 ypr_open(ctx, "typedef", "name", tpdf->name, 1);
483 LEVEL++;
484
485 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, tpdf->exts, NULL, 0);
486
487 yprp_type(ctx, &tpdf->type);
488
489 if (tpdf->units) {
490 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, tpdf->exts);
491 }
Michal Vasko7f45cf22020-10-01 12:49:44 +0200492 if (tpdf->dflt.str) {
493 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, tpdf->dflt.str, tpdf->exts);
FredGand944bdc2019-11-05 21:57:07 +0800494 }
495
496 ypr_status(ctx, tpdf->flags, tpdf->exts, NULL);
497 ypr_description(ctx, tpdf->dsc, tpdf->exts, NULL);
498 ypr_reference(ctx, tpdf->ref, tpdf->exts, NULL);
499
500 LEVEL--;
501 ypr_close(ctx, "typedef", 1);
502}
503
504static void yprp_node(struct ypr_ctx *ctx, const struct lysp_node *node);
505static void yprp_action(struct ypr_ctx *ctx, const struct lysp_action *action);
506
507static void
508yprp_grouping(struct ypr_ctx *ctx, const struct lysp_grp *grp)
509{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200510 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200511 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800512 struct lysp_node *data;
513
FredGand944bdc2019-11-05 21:57:07 +0800514 ypr_open(ctx, "grouping", "name", grp->name, flag);
515 LEVEL++;
516
517 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, grp->exts, &flag, 0);
518 ypr_status(ctx, grp->flags, grp->exts, &flag);
519 ypr_description(ctx, grp->dsc, grp->exts, &flag);
520 ypr_reference(ctx, grp->ref, grp->exts, &flag);
521
522 LY_ARRAY_FOR(grp->typedefs, u) {
523 ypr_close_parent(ctx, &flag);
524 yprp_typedef(ctx, &grp->typedefs[u]);
525 }
526
527 LY_ARRAY_FOR(grp->groupings, u) {
528 ypr_close_parent(ctx, &flag);
529 yprp_grouping(ctx, &grp->groupings[u]);
530 }
531
532 LY_LIST_FOR(grp->data, data) {
533 ypr_close_parent(ctx, &flag);
534 yprp_node(ctx, data);
535 }
536
537 LY_ARRAY_FOR(grp->actions, u) {
538 ypr_close_parent(ctx, &flag);
539 yprp_action(ctx, &grp->actions[u]);
540 }
541
542 LEVEL--;
543 ypr_close(ctx, "grouping", flag);
544}
545
546static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200547yprp_inout(struct ypr_ctx *ctx, const struct lysp_action_inout *inout, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800548{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200549 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800550 struct lysp_node *data;
551
Michal Vasko7f45cf22020-10-01 12:49:44 +0200552 if (!inout->data) {
553 /* input/output is empty */
FredGand944bdc2019-11-05 21:57:07 +0800554 return;
555 }
556 ypr_close_parent(ctx, flag);
557
558 ypr_open(ctx, (inout->nodetype == LYS_INPUT ? "input" : "output"), NULL, NULL, *flag);
559 LEVEL++;
560
561 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, inout->exts, NULL, 0);
562 LY_ARRAY_FOR(inout->musts, u) {
563 yprp_restr(ctx, &inout->musts[u], "must", "condition", NULL);
564 }
565 LY_ARRAY_FOR(inout->typedefs, u) {
566 yprp_typedef(ctx, &inout->typedefs[u]);
567 }
568 LY_ARRAY_FOR(inout->groupings, u) {
569 yprp_grouping(ctx, &inout->groupings[u]);
570 }
571
572 LY_LIST_FOR(inout->data, data) {
573 yprp_node(ctx, data);
574 }
575
576 LEVEL--;
577 ypr_close(ctx, (inout->nodetype == LYS_INPUT ? "input" : "output"), 1);
578}
579
580static void
581yprp_notification(struct ypr_ctx *ctx, const struct lysp_notif *notif)
582{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200583 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200584 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800585 struct lysp_node *data;
586
FredGand944bdc2019-11-05 21:57:07 +0800587 ypr_open(ctx, "notification", "name", notif->name, flag);
588
589 LEVEL++;
590 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, notif->exts, &flag, 0);
591 yprp_iffeatures(ctx, notif->iffeatures, notif->exts, &flag);
592
593 LY_ARRAY_FOR(notif->musts, u) {
594 ypr_close_parent(ctx, &flag);
595 yprp_restr(ctx, &notif->musts[u], "must", "condition", &flag);
596 }
597 ypr_status(ctx, notif->flags, notif->exts, &flag);
598 ypr_description(ctx, notif->dsc, notif->exts, &flag);
599 ypr_reference(ctx, notif->ref, notif->exts, &flag);
600
601 LY_ARRAY_FOR(notif->typedefs, u) {
602 ypr_close_parent(ctx, &flag);
603 yprp_typedef(ctx, &notif->typedefs[u]);
604 }
605
606 LY_ARRAY_FOR(notif->groupings, u) {
607 ypr_close_parent(ctx, &flag);
608 yprp_grouping(ctx, &notif->groupings[u]);
609 }
610
611 LY_LIST_FOR(notif->data, data) {
612 ypr_close_parent(ctx, &flag);
613 yprp_node(ctx, data);
614 }
615
616 LEVEL--;
617 ypr_close(ctx, "notification", flag);
618}
619
620static void
621yprp_action(struct ypr_ctx *ctx, const struct lysp_action *action)
622{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200623 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200624 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800625
FredGand944bdc2019-11-05 21:57:07 +0800626 ypr_open(ctx, action->parent ? "action" : "rpc", "name", action->name, flag);
627
628 LEVEL++;
629 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, action->exts, &flag, 0);
630 yprp_iffeatures(ctx, action->iffeatures, action->exts, &flag);
631 ypr_status(ctx, action->flags, action->exts, &flag);
632 ypr_description(ctx, action->dsc, action->exts, &flag);
633 ypr_reference(ctx, action->ref, action->exts, &flag);
634
635 LY_ARRAY_FOR(action->typedefs, u) {
636 ypr_close_parent(ctx, &flag);
637 yprp_typedef(ctx, &action->typedefs[u]);
638 }
639
640 LY_ARRAY_FOR(action->groupings, u) {
641 ypr_close_parent(ctx, &flag);
642 yprp_grouping(ctx, &action->groupings[u]);
643 }
644
645 yprp_inout(ctx, &action->input, &flag);
646 yprp_inout(ctx, &action->output, &flag);
647
648 LEVEL--;
649 ypr_close(ctx, action->parent ? "action" : "rpc", flag);
650}
651
652static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200653yprp_node_common1(struct ypr_ctx *ctx, const struct lysp_node *node, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800654{
655 ypr_open(ctx, lys_nodetype2str(node->nodetype), "name", node->name, *flag);
656 LEVEL++;
657
658 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, node->exts, flag, 0);
659 yprp_when(ctx, node->when, flag);
660 yprp_iffeatures(ctx, node->iffeatures, node->exts, flag);
661}
662
663static void
Radek Krejci1deb5be2020-08-26 16:43:36 +0200664yprp_node_common2(struct ypr_ctx *ctx, const struct lysp_node *node, int8_t *flag)
FredGand944bdc2019-11-05 21:57:07 +0800665{
666 ypr_config(ctx, node->flags, node->exts, flag);
667 if (node->nodetype & (LYS_CHOICE | LYS_LEAF | LYS_ANYDATA)) {
668 ypr_mandatory(ctx, node->flags, node->exts, flag);
669 }
670 ypr_status(ctx, node->flags, node->exts, flag);
671 ypr_description(ctx, node->dsc, node->exts, flag);
672 ypr_reference(ctx, node->ref, node->exts, flag);
673}
674
675static void
676yprp_container(struct ypr_ctx *ctx, const struct lysp_node *node)
677{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200678 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200679 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800680 struct lysp_node *child;
681 struct lysp_node_container *cont = (struct lysp_node_container *)node;
682
683 yprp_node_common1(ctx, node, &flag);
684
685 LY_ARRAY_FOR(cont->musts, u) {
686 ypr_close_parent(ctx, &flag);
687 yprp_restr(ctx, &cont->musts[u], "must", "condition", &flag);
688 }
689 if (cont->presence) {
690 ypr_close_parent(ctx, &flag);
691 ypr_substmt(ctx, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence, cont->exts);
692 }
693
694 yprp_node_common2(ctx, node, &flag);
695
696 LY_ARRAY_FOR(cont->typedefs, u) {
697 ypr_close_parent(ctx, &flag);
698 yprp_typedef(ctx, &cont->typedefs[u]);
699 }
700
701 LY_ARRAY_FOR(cont->groupings, u) {
702 ypr_close_parent(ctx, &flag);
703 yprp_grouping(ctx, &cont->groupings[u]);
704 }
705
706 LY_LIST_FOR(cont->child, child) {
707 ypr_close_parent(ctx, &flag);
708 yprp_node(ctx, child);
709 }
710
711 LY_ARRAY_FOR(cont->actions, u) {
712 ypr_close_parent(ctx, &flag);
713 yprp_action(ctx, &cont->actions[u]);
714 }
715
716 LY_ARRAY_FOR(cont->notifs, u) {
717 ypr_close_parent(ctx, &flag);
718 yprp_notification(ctx, &cont->notifs[u]);
719 }
720
721 LEVEL--;
722 ypr_close(ctx, "container", flag);
723}
724
725static void
726yprp_case(struct ypr_ctx *ctx, const struct lysp_node *node)
727{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200728 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800729 struct lysp_node *child;
730 struct lysp_node_case *cas = (struct lysp_node_case *)node;
731
732 yprp_node_common1(ctx, node, &flag);
733 yprp_node_common2(ctx, node, &flag);
734
735 LY_LIST_FOR(cas->child, child) {
736 ypr_close_parent(ctx, &flag);
737 yprp_node(ctx, child);
738 }
739
740 LEVEL--;
741 ypr_close(ctx, "case", flag);
742}
743
744static void
745yprp_choice(struct ypr_ctx *ctx, const struct lysp_node *node)
746{
Radek Krejci1deb5be2020-08-26 16:43:36 +0200747 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800748 struct lysp_node *child;
749 struct lysp_node_choice *choice = (struct lysp_node_choice *)node;
750
751 yprp_node_common1(ctx, node, &flag);
752
Michal Vasko7f45cf22020-10-01 12:49:44 +0200753 if (choice->dflt.str) {
FredGand944bdc2019-11-05 21:57:07 +0800754 ypr_close_parent(ctx, &flag);
Michal Vasko7f45cf22020-10-01 12:49:44 +0200755 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt.str, choice->exts);
FredGand944bdc2019-11-05 21:57:07 +0800756 }
757
758 yprp_node_common2(ctx, node, &flag);
759
760 LY_LIST_FOR(choice->child, child) {
761 ypr_close_parent(ctx, &flag);
762 yprp_node(ctx, child);
763 }
764
765 LEVEL--;
766 ypr_close(ctx, "choice", flag);
767}
768
769static void
770yprp_leaf(struct ypr_ctx *ctx, const struct lysp_node *node)
771{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200772 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800773 struct lysp_node_leaf *leaf = (struct lysp_node_leaf *)node;
774
Radek Krejci1deb5be2020-08-26 16:43:36 +0200775 int8_t flag = 1;
Michal Vasko69730152020-10-09 16:30:07 +0200776
FredGand944bdc2019-11-05 21:57:07 +0800777 yprp_node_common1(ctx, node, &flag);
778
779 yprp_type(ctx, &leaf->type);
780 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, leaf->units, leaf->exts);
781 LY_ARRAY_FOR(leaf->musts, u) {
782 yprp_restr(ctx, &leaf->musts[u], "must", "condition", &flag);
783 }
Michal Vasko7f45cf22020-10-01 12:49:44 +0200784 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, leaf->dflt.str, leaf->exts);
FredGand944bdc2019-11-05 21:57:07 +0800785
786 yprp_node_common2(ctx, node, &flag);
787
788 LEVEL--;
789 ypr_close(ctx, "leaf", flag);
790}
791
792static void
793yprp_leaflist(struct ypr_ctx *ctx, const struct lysp_node *node)
794{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200795 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800796 struct lysp_node_leaflist *llist = (struct lysp_node_leaflist *)node;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200797 int8_t flag = 1;
FredGand944bdc2019-11-05 21:57:07 +0800798
799 yprp_node_common1(ctx, node, &flag);
800
801 yprp_type(ctx, &llist->type);
802 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, llist->units, llist->exts);
803 LY_ARRAY_FOR(llist->musts, u) {
804 yprp_restr(ctx, &llist->musts[u], "must", "condition", NULL);
805 }
806 LY_ARRAY_FOR(llist->dflts, u) {
Michal Vasko7f45cf22020-10-01 12:49:44 +0200807 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, llist->dflts[u].str, llist->exts);
FredGand944bdc2019-11-05 21:57:07 +0800808 }
809
810 ypr_config(ctx, node->flags, node->exts, NULL);
811
812 if (llist->flags & LYS_SET_MIN) {
813 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, llist->exts, llist->min);
814 }
815 if (llist->flags & LYS_SET_MAX) {
816 if (llist->max) {
817 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, llist->exts, llist->max);
818 } else {
819 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", llist->exts);
820 }
821 }
822
823 if (llist->flags & LYS_ORDBY_MASK) {
824 ypr_substmt(ctx, LYEXT_SUBSTMT_ORDEREDBY, 0, (llist->flags & LYS_ORDBY_USER) ? "user" : "system", llist->exts);
825 }
826
827 ypr_status(ctx, node->flags, node->exts, &flag);
828 ypr_description(ctx, node->dsc, node->exts, &flag);
829 ypr_reference(ctx, node->ref, node->exts, &flag);
830
831 LEVEL--;
832 ypr_close(ctx, "leaf-list", flag);
833}
834
835static void
836yprp_list(struct ypr_ctx *ctx, const struct lysp_node *node)
837{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200838 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200839 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800840 struct lysp_node *child;
841 struct lysp_node_list *list = (struct lysp_node_list *)node;
842
843 yprp_node_common1(ctx, node, &flag);
844
845 LY_ARRAY_FOR(list->musts, u) {
846 ypr_close_parent(ctx, &flag);
847 yprp_restr(ctx, &list->musts[u], "must", "condition", &flag);
848 }
849 if (list->key) {
850 ypr_close_parent(ctx, &flag);
851 ypr_substmt(ctx, LYEXT_SUBSTMT_KEY, 0, list->key, list->exts);
852 }
853 LY_ARRAY_FOR(list->uniques, u) {
854 ypr_close_parent(ctx, &flag);
Michal Vasko7f45cf22020-10-01 12:49:44 +0200855 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, list->uniques[u].str, list->exts);
FredGand944bdc2019-11-05 21:57:07 +0800856 }
857
858 ypr_config(ctx, node->flags, node->exts, NULL);
859
860 if (list->flags & LYS_SET_MIN) {
861 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, list->exts, list->min);
862 }
863 if (list->flags & LYS_SET_MAX) {
864 if (list->max) {
865 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, list->exts, list->max);
866 } else {
867 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", list->exts);
868 }
869 }
870
871 if (list->flags & LYS_ORDBY_MASK) {
872 ypr_close_parent(ctx, &flag);
873 ypr_substmt(ctx, LYEXT_SUBSTMT_ORDEREDBY, 0, (list->flags & LYS_ORDBY_USER) ? "user" : "system", list->exts);
874 }
875
876 ypr_status(ctx, node->flags, node->exts, &flag);
877 ypr_description(ctx, node->dsc, node->exts, &flag);
878 ypr_reference(ctx, node->ref, node->exts, &flag);
879
880 LY_ARRAY_FOR(list->typedefs, u) {
881 ypr_close_parent(ctx, &flag);
882 yprp_typedef(ctx, &list->typedefs[u]);
883 }
884
885 LY_ARRAY_FOR(list->groupings, u) {
886 ypr_close_parent(ctx, &flag);
887 yprp_grouping(ctx, &list->groupings[u]);
888 }
889
890 LY_LIST_FOR(list->child, child) {
891 ypr_close_parent(ctx, &flag);
892 yprp_node(ctx, child);
893 }
894
895 LY_ARRAY_FOR(list->actions, u) {
896 ypr_close_parent(ctx, &flag);
897 yprp_action(ctx, &list->actions[u]);
898 }
899
900 LY_ARRAY_FOR(list->notifs, u) {
901 ypr_close_parent(ctx, &flag);
902 yprp_notification(ctx, &list->notifs[u]);
903 }
904
905 LEVEL--;
906 ypr_close(ctx, "list", flag);
907}
908
909static void
910yprp_refine(struct ypr_ctx *ctx, struct lysp_refine *refine)
911{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200912 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200913 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800914
915 ypr_open(ctx, "refine", "target-node", refine->nodeid, flag);
916 LEVEL++;
917
918 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, refine->exts, &flag, 0);
919 yprp_iffeatures(ctx, refine->iffeatures, refine->exts, &flag);
920
921 LY_ARRAY_FOR(refine->musts, u) {
922 ypr_close_parent(ctx, &flag);
923 yprp_restr(ctx, &refine->musts[u], "must", "condition", &flag);
924 }
925
926 if (refine->presence) {
927 ypr_close_parent(ctx, &flag);
928 ypr_substmt(ctx, LYEXT_SUBSTMT_PRESENCE, 0, refine->presence, refine->exts);
929 }
930
931 LY_ARRAY_FOR(refine->dflts, u) {
932 ypr_close_parent(ctx, &flag);
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200933 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, refine->dflts[u].str, refine->exts);
FredGand944bdc2019-11-05 21:57:07 +0800934 }
935
936 ypr_config(ctx, refine->flags, refine->exts, &flag);
937 ypr_mandatory(ctx, refine->flags, refine->exts, &flag);
938
939 if (refine->flags & LYS_SET_MIN) {
940 ypr_close_parent(ctx, &flag);
941 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, refine->exts, refine->min);
942 }
943 if (refine->flags & LYS_SET_MAX) {
944 ypr_close_parent(ctx, &flag);
945 if (refine->max) {
946 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, refine->exts, refine->max);
947 } else {
948 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", refine->exts);
949 }
950 }
951
952 ypr_description(ctx, refine->dsc, refine->exts, &flag);
953 ypr_reference(ctx, refine->ref, refine->exts, &flag);
954
955 LEVEL--;
956 ypr_close(ctx, "refine", flag);
957}
958
959static void
960yprp_augment(struct ypr_ctx *ctx, const struct lysp_augment *aug)
961{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200962 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +0800963 struct lysp_node *child;
964
965 ypr_open(ctx, "augment", "target-node", aug->nodeid, 1);
966 LEVEL++;
967
968 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, aug->exts, NULL, 0);
969 yprp_when(ctx, aug->when, NULL);
970 yprp_iffeatures(ctx, aug->iffeatures, aug->exts, NULL);
971 ypr_status(ctx, aug->flags, aug->exts, NULL);
972 ypr_description(ctx, aug->dsc, aug->exts, NULL);
973 ypr_reference(ctx, aug->ref, aug->exts, NULL);
974
975 LY_LIST_FOR(aug->child, child) {
976 yprp_node(ctx, child);
977 }
978
979 LY_ARRAY_FOR(aug->actions, u) {
980 yprp_action(ctx, &aug->actions[u]);
981 }
982
983 LY_ARRAY_FOR(aug->notifs, u) {
984 yprp_notification(ctx, &aug->notifs[u]);
985 }
986
987 LEVEL--;
988 ypr_close(ctx, "augment", 1);
989}
990
FredGand944bdc2019-11-05 21:57:07 +0800991static void
992yprp_uses(struct ypr_ctx *ctx, const struct lysp_node *node)
993{
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200994 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +0200995 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +0800996 struct lysp_node_uses *uses = (struct lysp_node_uses *)node;
997
998 yprp_node_common1(ctx, node, &flag);
999 yprp_node_common2(ctx, node, &flag);
1000
1001 LY_ARRAY_FOR(uses->refines, u) {
1002 ypr_close_parent(ctx, &flag);
1003 yprp_refine(ctx, &uses->refines[u]);
1004 }
1005
1006 LY_ARRAY_FOR(uses->augments, u) {
1007 ypr_close_parent(ctx, &flag);
1008 yprp_augment(ctx, &uses->augments[u]);
1009 }
1010
1011 LEVEL--;
1012 ypr_close(ctx, "uses", flag);
1013}
1014
1015static void
1016yprp_anydata(struct ypr_ctx *ctx, const struct lysp_node *node)
1017{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001018 LY_ARRAY_COUNT_TYPE u;
Radek Krejci1deb5be2020-08-26 16:43:36 +02001019 int8_t flag = 0;
FredGand944bdc2019-11-05 21:57:07 +08001020 struct lysp_node_anydata *any = (struct lysp_node_anydata *)node;
1021
1022 yprp_node_common1(ctx, node, &flag);
1023
1024 LY_ARRAY_FOR(any->musts, u) {
1025 ypr_close_parent(ctx, &flag);
1026 yprp_restr(ctx, &any->musts[u], "must", "condition", &flag);
1027 }
1028
1029 yprp_node_common2(ctx, node, &flag);
1030
1031 LEVEL--;
1032 ypr_close(ctx, lys_nodetype2str(node->nodetype), flag);
1033}
1034
1035static void
1036yprp_node(struct ypr_ctx *ctx, const struct lysp_node *node)
1037{
FredGand944bdc2019-11-05 21:57:07 +08001038 switch (node->nodetype) {
1039 case LYS_CONTAINER:
1040 yprp_container(ctx, node);
1041 break;
1042 case LYS_CHOICE:
1043 yprp_choice(ctx, node);
1044 break;
1045 case LYS_LEAF:
1046 yprp_leaf(ctx, node);
1047 break;
1048 case LYS_LEAFLIST:
1049 yprp_leaflist(ctx, node);
1050 break;
1051 case LYS_LIST:
1052 yprp_list(ctx, node);
1053 break;
1054 case LYS_USES:
1055 yprp_uses(ctx, node);
1056 break;
1057 case LYS_ANYXML:
1058 case LYS_ANYDATA:
1059 yprp_anydata(ctx, node);
1060 break;
1061 case LYS_CASE:
1062 yprp_case(ctx, node);
1063 break;
1064 default:
1065 break;
1066 }
1067}
1068
1069static void
1070yprp_deviation(struct ypr_ctx *ctx, const struct lysp_deviation *deviation)
1071{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001072 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001073 struct lysp_deviate_add *add;
1074 struct lysp_deviate_rpl *rpl;
1075 struct lysp_deviate_del *del;
1076 struct lysp_deviate *elem;
1077
1078 ypr_open(ctx, "deviation", "target-node", deviation->nodeid, 1);
1079 LEVEL++;
1080
1081 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, deviation->exts, NULL, 0);
1082 ypr_description(ctx, deviation->dsc, deviation->exts, NULL);
1083 ypr_reference(ctx, deviation->ref, deviation->exts, NULL);
1084
1085 LY_LIST_FOR(deviation->deviates, elem) {
Michal Vasko5233e962020-08-14 14:26:20 +02001086 ly_print_(ctx->out, "%*s<deviate value=\"", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001087 if (elem->mod == LYS_DEV_NOT_SUPPORTED) {
1088 if (elem->exts) {
Michal Vasko5233e962020-08-14 14:26:20 +02001089 ly_print_(ctx->out, "not-supported\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +08001090 LEVEL++;
1091
1092 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, elem->exts, NULL, 0);
1093 } else {
Michal Vasko5233e962020-08-14 14:26:20 +02001094 ly_print_(ctx->out, "not-supported\"/>\n");
FredGand944bdc2019-11-05 21:57:07 +08001095 continue;
1096 }
1097 } else if (elem->mod == LYS_DEV_ADD) {
Michal Vasko22df3f02020-08-24 13:29:22 +02001098 add = (struct lysp_deviate_add *)elem;
Michal Vasko5233e962020-08-14 14:26:20 +02001099 ly_print_(ctx->out, "add\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001100 LEVEL++;
1101
1102 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, add->exts, NULL, 0);
1103 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, add->units, add->exts);
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001104 LY_ARRAY_FOR(add->musts, u) {
1105 yprp_restr(ctx, &add->musts[u], "must", "condition", NULL);
FredGand944bdc2019-11-05 21:57:07 +08001106 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001107 LY_ARRAY_FOR(add->uniques, u) {
Michal Vasko5d24f6c2020-10-13 13:49:06 +02001108 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, add->uniques[u].str, add->exts);
FredGand944bdc2019-11-05 21:57:07 +08001109 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001110 LY_ARRAY_FOR(add->dflts, u) {
Michal Vasko5d24f6c2020-10-13 13:49:06 +02001111 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, add->dflts[u].str, add->exts);
FredGand944bdc2019-11-05 21:57:07 +08001112 }
1113 ypr_config(ctx, add->flags, add->exts, NULL);
1114 ypr_mandatory(ctx, add->flags, add->exts, NULL);
1115 if (add->flags & LYS_SET_MIN) {
1116 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, add->exts, add->min);
1117 }
1118 if (add->flags & LYS_SET_MAX) {
1119 if (add->max) {
1120 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, add->exts, add->max);
1121 } else {
1122 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", add->exts);
1123 }
1124 }
1125 } else if (elem->mod == LYS_DEV_REPLACE) {
Michal Vasko22df3f02020-08-24 13:29:22 +02001126 rpl = (struct lysp_deviate_rpl *)elem;
Michal Vasko5233e962020-08-14 14:26:20 +02001127 ly_print_(ctx->out, "replace\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001128 LEVEL++;
1129
1130 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, rpl->exts, NULL, 0);
1131 if (rpl->type) {
1132 yprp_type(ctx, rpl->type);
1133 }
1134 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, rpl->units, rpl->exts);
Michal Vasko5d24f6c2020-10-13 13:49:06 +02001135 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, rpl->dflt.str, rpl->exts);
FredGand944bdc2019-11-05 21:57:07 +08001136 ypr_config(ctx, rpl->flags, rpl->exts, NULL);
1137 ypr_mandatory(ctx, rpl->flags, rpl->exts, NULL);
1138 if (rpl->flags & LYS_SET_MIN) {
1139 ypr_unsigned(ctx, LYEXT_SUBSTMT_MIN, 0, rpl->exts, rpl->min);
1140 }
1141 if (rpl->flags & LYS_SET_MAX) {
1142 if (rpl->max) {
1143 ypr_unsigned(ctx, LYEXT_SUBSTMT_MAX, 0, rpl->exts, rpl->max);
1144 } else {
1145 ypr_substmt(ctx, LYEXT_SUBSTMT_MAX, 0, "unbounded", rpl->exts);
1146 }
1147 }
1148 } else if (elem->mod == LYS_DEV_DELETE) {
Michal Vasko22df3f02020-08-24 13:29:22 +02001149 del = (struct lysp_deviate_del *)elem;
Michal Vasko5233e962020-08-14 14:26:20 +02001150 ly_print_(ctx->out, "delete\">\n");
FredGand944bdc2019-11-05 21:57:07 +08001151 LEVEL++;
1152
1153 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, del->exts, NULL, 0);
1154 ypr_substmt(ctx, LYEXT_SUBSTMT_UNITS, 0, del->units, del->exts);
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001155 LY_ARRAY_FOR(del->musts, u) {
1156 yprp_restr(ctx, &del->musts[u], "must", "condition", NULL);
FredGand944bdc2019-11-05 21:57:07 +08001157 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001158 LY_ARRAY_FOR(del->uniques, u) {
Michal Vasko5d24f6c2020-10-13 13:49:06 +02001159 ypr_substmt(ctx, LYEXT_SUBSTMT_UNIQUE, u, del->uniques[u].str, del->exts);
FredGand944bdc2019-11-05 21:57:07 +08001160 }
Radek Krejci7eb54ba2020-05-18 16:30:04 +02001161 LY_ARRAY_FOR(del->dflts, u) {
Michal Vasko5d24f6c2020-10-13 13:49:06 +02001162 ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, del->dflts[u].str, del->exts);
FredGand944bdc2019-11-05 21:57:07 +08001163 }
1164 }
1165
1166 LEVEL--;
1167 ypr_close(ctx, "deviate", 1);
1168 }
1169
1170 LEVEL--;
1171 ypr_close(ctx, "deviation", 1);
1172}
1173
FredGand944bdc2019-11-05 21:57:07 +08001174static void
Radek Krejci1deb5be2020-08-26 16:43:36 +02001175ypr_xmlns(struct ypr_ctx *ctx, const struct lys_module *module, uint16_t indent)
FredGand944bdc2019-11-05 21:57:07 +08001176{
Michal Vasko5233e962020-08-14 14:26:20 +02001177 ly_print_(ctx->out, "%*sxmlns=\"%s\"", indent + INDENT, YIN_NS_URI);
1178 ly_print_(ctx->out, "\n%*sxmlns:%s=\"%s\"", indent + INDENT, module->prefix, module->ns);
Michal Vasko7c8439f2020-08-05 13:25:19 +02001179}
FredGand944bdc2019-11-05 21:57:07 +08001180
Michal Vasko7c8439f2020-08-05 13:25:19 +02001181static void
Radek Krejci1deb5be2020-08-26 16:43:36 +02001182ypr_import_xmlns(struct ypr_ctx *ctx, const struct lysp_module *modp, uint16_t indent)
Michal Vasko7c8439f2020-08-05 13:25:19 +02001183{
1184 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001185
1186 LY_ARRAY_FOR(modp->imports, u){
Michal Vasko5233e962020-08-14 14:26:20 +02001187 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 +08001188 }
1189}
1190
1191struct ext_substmt_info_s stmt_attr_info[] = {
1192 {NULL, NULL, 0}, /**< LY_STMT_NONE*/
1193 {"status", "value", SUBST_FLAG_ID}, /**< LY_STMT_STATUS */
1194 {"config", "value", SUBST_FLAG_ID}, /**< LY_STMT_CONFIG */
1195 {"mandatory", "value", SUBST_FLAG_ID}, /**< LY_STMT_MANDATORY */
1196 {"units", "name", SUBST_FLAG_ID}, /**< LY_STMT_UNITS */
1197 {"default", "value", SUBST_FLAG_ID}, /**< LY_STMT_DEFAULT */
1198 {"type", "name", SUBST_FLAG_ID}, /**< LY_STMT_TYPE */
1199 {"action", "name", SUBST_FLAG_ID}, /**< LY_STMT_ACTION */
1200 {"anydata", "name", SUBST_FLAG_ID}, /**< LY_STMT_ANYDATA */
1201 {"anyxml", "name", SUBST_FLAG_ID}, /**< LY_STMT_ANYXML */
1202 {"argument", "name", SUBST_FLAG_ID}, /**< LY_STMT_ARGUMENT */
1203 {"augment", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_AUGMENT */
1204 {"base", "name", SUBST_FLAG_ID}, /**< LY_STMT_BASE */
1205 {"belongs-to", "module", SUBST_FLAG_ID}, /**< LY_STMT_BELONGS_TO */
1206 {"bit", "name", SUBST_FLAG_ID}, /**< LY_STMT_BIT */
1207 {"case", "name", SUBST_FLAG_ID}, /**< LY_STMT_CASE */
1208 {"choice", "name", SUBST_FLAG_ID}, /**< LY_STMT_CHOICE */
1209 {"contact", "text", SUBST_FLAG_YIN},/**< LY_STMT_CONTACT */
1210 {"container", "name", SUBST_FLAG_ID}, /**< LY_STMT_CONTAINER */
1211 {"description", "text", SUBST_FLAG_YIN},/**< LY_STMT_DESCRIPTION */
1212 {"deviate", "value", SUBST_FLAG_ID}, /**< LY_STMT_DEVIATE */
1213 {"deviation", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_DEVIATION */
1214 {"enum", "name", SUBST_FLAG_ID}, /**< LY_STMT_ENUM */
1215 {"error-app-tag", "value", SUBST_FLAG_ID}, /**< LY_STMT_ERROR_APP_TAG */
1216 {"error-message", "value", SUBST_FLAG_YIN},/**< LY_STMT_ERROR_MESSAGE */
1217 {"extension", "name", SUBST_FLAG_ID}, /**< LY_STMT_EXTENSION */
1218 {"feature", "name", SUBST_FLAG_ID}, /**< LY_STMT_FEATURE */
1219 {"fraction-digits", "value", SUBST_FLAG_ID}, /**< LY_STMT_FRACTION_DIGITS */
1220 {"grouping", "name", SUBST_FLAG_ID}, /**< LY_STMT_GROUPING */
1221 {"identity", "name", SUBST_FLAG_ID}, /**< LY_STMT_IDENTITY */
1222 {"if-feature", "name", SUBST_FLAG_ID}, /**< LY_STMT_IF_FEATURE */
1223 {"import", "module", SUBST_FLAG_ID}, /**< LY_STMT_IMPORT */
1224 {"include", "module", SUBST_FLAG_ID}, /**< LY_STMT_INCLUDE */
1225 {"input", NULL, 0}, /**< LY_STMT_INPUT */
1226 {"key", "value", SUBST_FLAG_ID}, /**< LY_STMT_KEY */
1227 {"leaf", "name", SUBST_FLAG_ID}, /**< LY_STMT_LEAF */
1228 {"leaf-list", "name", SUBST_FLAG_ID}, /**< LY_STMT_LEAF_LIST */
1229 {"length", "value", SUBST_FLAG_ID}, /**< LY_STMT_LENGTH */
1230 {"list", "name", SUBST_FLAG_ID}, /**< LY_STMT_LIST */
1231 {"max-elements", "value", SUBST_FLAG_ID}, /**< LY_STMT_MAX_ELEMENTS */
1232 {"min-elements", "value", SUBST_FLAG_ID}, /**< LY_STMT_MIN_ELEMENTS */
1233 {"modifier", "value", SUBST_FLAG_ID}, /**< LY_STMT_MODIFIER */
1234 {"module", "name", SUBST_FLAG_ID}, /**< LY_STMT_MODULE */
1235 {"must", "condition", SUBST_FLAG_ID}, /**< LY_STMT_MUST */
1236 {"namespace", "uri", SUBST_FLAG_ID}, /**< LY_STMT_NAMESPACE */
1237 {"notification", "name", SUBST_FLAG_ID}, /**< LY_STMT_NOTIFICATION */
1238 {"ordered-by", "value", SUBST_FLAG_ID}, /**< LY_STMT_ORDERED_BY */
1239 {"organization", "text", SUBST_FLAG_YIN},/**< LY_STMT_ORGANIZATION */
1240 {"output", NULL, 0}, /**< LY_STMT_OUTPUT */
1241 {"path", "value", SUBST_FLAG_ID}, /**< LY_STMT_PATH */
1242 {"pattern", "value", SUBST_FLAG_ID}, /**< LY_STMT_PATTERN */
1243 {"position", "value", SUBST_FLAG_ID}, /**< LY_STMT_POSITION */
1244 {"prefix", "value", SUBST_FLAG_ID}, /**< LY_STMT_PREFIX */
1245 {"presence", "value", SUBST_FLAG_ID}, /**< LY_STMT_PRESENCE */
1246 {"range", "value", SUBST_FLAG_ID}, /**< LY_STMT_RANGE */
1247 {"reference", "text", SUBST_FLAG_YIN},/**< LY_STMT_REFERENCE */
1248 {"refine", "target-node", SUBST_FLAG_ID}, /**< LY_STMT_REFINE */
1249 {"require-instance", "value", SUBST_FLAG_ID}, /**< LY_STMT_REQUIRE_INSTANCE */
1250 {"revision", "date", SUBST_FLAG_ID}, /**< LY_STMT_REVISION */
1251 {"revision-date", "date", SUBST_FLAG_ID}, /**< LY_STMT_REVISION_DATE */
1252 {"rpc", "name", SUBST_FLAG_ID}, /**< LY_STMT_RPC */
1253 {"submodule", "name", SUBST_FLAG_ID}, /**< LY_STMT_SUBMODULE */
1254 {"typedef", "name", SUBST_FLAG_ID}, /**< LY_STMT_TYPEDEF */
1255 {"unique", "tag", SUBST_FLAG_ID}, /**< LY_STMT_UNIQUE */
1256 {"uses", "name", SUBST_FLAG_ID}, /**< LY_STMT_USES */
1257 {"value", "value", SUBST_FLAG_ID}, /**< LY_STMT_VALUE */
1258 {"when", "condition", SUBST_FLAG_ID}, /**< LY_STMT_WHEN */
1259 {"yang-version", "value", SUBST_FLAG_ID}, /**< LY_STMT_YANG_VERSION */
1260 {"yin-element", "value", SUBST_FLAG_ID}, /**< LY_STMT_YIN_ELEMENT */
1261 {NULL, NULL, 0}, /**< LY_STMT_EXTENSION_INSTANCE */
1262 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_SEMICOLON */
1263 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_LEFT_BRACE */
1264 {NULL, NULL, 0}, /**< LY_STMT_SYNTAX_RIGHT_BRACE */
1265 {NULL, NULL, 0}, /**< LY_STMT_ARG_TEXT */
1266 {NULL, NULL, 0}, /**< LY_STMT_ARG_VALUE */
1267};
1268
1269static void
1270yprp_stmt(struct ypr_ctx *ctx, struct lysp_stmt *stmt)
1271{
1272 struct lysp_stmt *childstmt;
Radek Krejci1deb5be2020-08-26 16:43:36 +02001273 int8_t flag = stmt->child ? 1 : -1;
FredGand944bdc2019-11-05 21:57:07 +08001274
1275 /* TODO:
1276 the extension instance substatements in extension instances (LY_STMT_EXTENSION_INSTANCE)
1277 cannot find the compiled information, so it is needed to be done,
1278 currently it is ignored */
Michal Vaskod989ba02020-08-24 10:59:24 +02001279 if (stmt_attr_info[stmt->kw].name) {
1280 if (stmt_attr_info[stmt->kw].flags & SUBST_FLAG_YIN) {
FredGand944bdc2019-11-05 21:57:07 +08001281 ypr_open(ctx, stmt->stmt, NULL, NULL, flag);
1282 ypr_yin_arg(ctx, stmt_attr_info[stmt->kw].arg, stmt->arg);
Radek Krejci0f969882020-08-21 16:56:47 +02001283 } else {
FredGand944bdc2019-11-05 21:57:07 +08001284 ypr_open(ctx, stmt->stmt, stmt_attr_info[stmt->kw].arg, stmt->arg, flag);
1285 }
1286 }
1287
1288 if (stmt->child) {
1289 LEVEL++;
1290 LY_LIST_FOR(stmt->child, childstmt) {
1291 yprp_stmt(ctx, childstmt);
1292 }
1293 LEVEL--;
1294 ypr_close(ctx, stmt->stmt, flag);
1295 }
1296}
1297
1298/**
1299 * @param[in] count Number of extensions to print, 0 to print them all.
1300 */
1301static void
1302yprp_extension_instances(struct ypr_ctx *ctx, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
Radek Krejci1deb5be2020-08-26 16:43:36 +02001303 struct lysp_ext_instance *ext, int8_t *flag, LY_ARRAY_COUNT_TYPE count)
FredGand944bdc2019-11-05 21:57:07 +08001304{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001305 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001306 char *str;
1307 struct lysp_stmt *stmt;
1308 const char *argument;
1309 const char *ext_argument;
Radek Krejci1deb5be2020-08-26 16:43:36 +02001310 int8_t inner_flag = 0;
FredGand944bdc2019-11-05 21:57:07 +08001311
1312 if (!count && ext) {
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001313 count = LY_ARRAY_COUNT(ext);
FredGand944bdc2019-11-05 21:57:07 +08001314 }
1315 LY_ARRAY_FOR(ext, u) {
1316 if (!count) {
1317 break;
1318 }
1319
1320 count--;
Michal Vasko3e9bc2f2020-11-04 17:13:56 +01001321 if ((ext->flags & LYS_INTERNAL) || (ext->insubstmt != substmt) || (ext->insubstmt_index != substmt_index)) {
FredGand944bdc2019-11-05 21:57:07 +08001322 continue;
1323 }
1324
1325 if (!ext->compiled && ext->yin) {
Michal Vasko5233e962020-08-14 14:26:20 +02001326 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 +08001327 continue;
1328 }
1329
1330 ypr_close_parent(ctx, flag);
Radek Krejci1deb5be2020-08-26 16:43:36 +02001331 inner_flag = 0;
FredGand944bdc2019-11-05 21:57:07 +08001332 argument = NULL;
1333 ext_argument = NULL;
1334
1335 if (ext[u].compiled) {
1336 argument = ext[u].compiled->argument;
1337 ext_argument = ext[u].compiled->def->argument;
1338 } else {
1339 argument = ext[u].argument;
1340 }
1341
1342 if (ext->yin) {
1343 ypr_open(ctx, ext[u].name, NULL, NULL, 1);
1344 if (asprintf(&str, "%s:%s", ext[u].compiled->def->module->prefix, ext_argument) == -1) {
1345 LOGMEM(ctx->module->ctx);
FredGand944bdc2019-11-05 21:57:07 +08001346 return;
1347 }
1348 LEVEL++;
1349 inner_flag = 1;
1350 ypr_yin_arg(ctx, str, argument);
1351 free(str);
1352 str = NULL;
1353 LEVEL--;
1354 } else {
1355 ypr_open(ctx, ext[u].name, ext_argument, argument, inner_flag);
1356 }
1357
1358 LEVEL++;
1359 LY_LIST_FOR(ext[u].child, stmt) {
1360 ypr_close_parent(ctx, &inner_flag);
1361 yprp_stmt(ctx, stmt);
1362 }
1363 LEVEL--;
1364 ypr_close(ctx, ext[u].name, inner_flag);
1365 }
1366}
1367
Michal Vasko7c8439f2020-08-05 13:25:19 +02001368static void
1369yin_print_parsed_linkage(struct ypr_ctx *ctx, const struct lysp_module *modp)
FredGand944bdc2019-11-05 21:57:07 +08001370{
Michal Vasko7c8439f2020-08-05 13:25:19 +02001371 LY_ARRAY_COUNT_TYPE u;
FredGand944bdc2019-11-05 21:57:07 +08001372
FredGand944bdc2019-11-05 21:57:07 +08001373 LY_ARRAY_FOR(modp->imports, u) {
Michal Vasko3e9bc2f2020-11-04 17:13:56 +01001374 if (modp->imports[u].flags & LYS_INTERNAL) {
1375 continue;
1376 }
1377
Michal Vasko7c8439f2020-08-05 13:25:19 +02001378 ypr_open(ctx, "import", "module", modp->imports[u].name, 1);
FredGand944bdc2019-11-05 21:57:07 +08001379 LEVEL++;
1380 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->imports[u].exts, NULL, 0);
1381 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, modp->imports[u].prefix, modp->imports[u].exts);
1382 if (modp->imports[u].rev[0]) {
1383 ypr_substmt(ctx, LYEXT_SUBSTMT_REVISIONDATE, 0, modp->imports[u].rev, modp->imports[u].exts);
1384 }
1385 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, modp->imports[u].dsc, modp->imports[u].exts);
1386 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, modp->imports[u].ref, modp->imports[u].exts);
1387 LEVEL--;
1388 ypr_close(ctx, "import", 1);
1389 }
1390 LY_ARRAY_FOR(modp->includes, u) {
1391 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 +02001392 ypr_open(ctx, "include", "module", modp->includes[u].name, 1);
FredGand944bdc2019-11-05 21:57:07 +08001393 LEVEL++;
1394 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->includes[u].exts, NULL, 0);
1395 if (modp->includes[u].rev[0]) {
1396 ypr_substmt(ctx, LYEXT_SUBSTMT_REVISIONDATE, 0, modp->includes[u].rev, modp->includes[u].exts);
1397 }
1398 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, modp->includes[u].dsc, modp->includes[u].exts);
1399 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, modp->includes[u].ref, modp->includes[u].exts);
1400 LEVEL--;
Michal Vasko5233e962020-08-14 14:26:20 +02001401 ly_print_(ctx->out, "%*s}\n", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001402 } else {
Michal Vasko7c8439f2020-08-05 13:25:19 +02001403 ypr_open(ctx, "include", "module", modp->includes[u].name, -1);
FredGand944bdc2019-11-05 21:57:07 +08001404 }
1405 }
Michal Vasko7c8439f2020-08-05 13:25:19 +02001406}
FredGand944bdc2019-11-05 21:57:07 +08001407
Michal Vasko7c8439f2020-08-05 13:25:19 +02001408static void
1409yin_print_parsed_body(struct ypr_ctx *ctx, const struct lysp_module *modp)
1410{
1411 LY_ARRAY_COUNT_TYPE u;
1412 struct lysp_node *data;
FredGand944bdc2019-11-05 21:57:07 +08001413
FredGand944bdc2019-11-05 21:57:07 +08001414 LY_ARRAY_FOR(modp->extensions, u) {
Michal Vasko5233e962020-08-14 14:26:20 +02001415 ly_print_(ctx->out, "\n");
FredGand944bdc2019-11-05 21:57:07 +08001416 yprp_extension(ctx, &modp->extensions[u]);
1417 }
1418 if (modp->exts) {
Michal Vasko5233e962020-08-14 14:26:20 +02001419 ly_print_(ctx->out, "\n");
Michal Vasko7c8439f2020-08-05 13:25:19 +02001420 yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, modp->exts, NULL, 0);
FredGand944bdc2019-11-05 21:57:07 +08001421 }
1422
1423 LY_ARRAY_FOR(modp->features, u) {
1424 yprp_feature(ctx, &modp->features[u]);
1425 }
1426
1427 LY_ARRAY_FOR(modp->identities, u) {
1428 yprp_identity(ctx, &modp->identities[u]);
1429 }
1430
1431 LY_ARRAY_FOR(modp->typedefs, u) {
1432 yprp_typedef(ctx, &modp->typedefs[u]);
1433 }
1434
1435 LY_ARRAY_FOR(modp->groupings, u) {
1436 yprp_grouping(ctx, &modp->groupings[u]);
1437 }
1438
1439 LY_LIST_FOR(modp->data, data) {
1440 yprp_node(ctx, data);
1441 }
1442
1443 LY_ARRAY_FOR(modp->augments, u) {
1444 yprp_augment(ctx, &modp->augments[u]);
1445 }
1446
1447 LY_ARRAY_FOR(modp->rpcs, u) {
1448 yprp_action(ctx, &modp->rpcs[u]);
1449 }
1450
1451 LY_ARRAY_FOR(modp->notifs, u) {
1452 yprp_notification(ctx, &modp->notifs[u]);
1453 }
1454
1455 LY_ARRAY_FOR(modp->deviations, u) {
1456 yprp_deviation(ctx, &modp->deviations[u]);
1457 }
Michal Vasko7c8439f2020-08-05 13:25:19 +02001458}
1459
1460LY_ERR
Radek Krejci1deb5be2020-08-26 16:43:36 +02001461yin_print_parsed_module(struct ly_out *out, const struct lys_module *module, const struct lysp_module *modp, uint32_t options)
Michal Vasko7c8439f2020-08-05 13:25:19 +02001462{
1463 LY_ARRAY_COUNT_TYPE u;
Radek Krejci52f65552020-09-01 17:03:35 +02001464 struct ypr_ctx ctx_ = {.out = out, .level = 0, .module = module, .options = options}, *ctx = &ctx_;
Michal Vasko7c8439f2020-08-05 13:25:19 +02001465
Michal Vasko5233e962020-08-14 14:26:20 +02001466 ly_print_(ctx->out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1467 ly_print_(ctx->out, "%*s<module name=\"%s\"\n", INDENT, module->name);
Michal Vasko7c8439f2020-08-05 13:25:19 +02001468 ypr_xmlns(ctx, module, 8);
1469 ypr_import_xmlns(ctx, modp, 8);
Michal Vasko5233e962020-08-14 14:26:20 +02001470 ly_print_(ctx->out, ">\n");
Michal Vasko7c8439f2020-08-05 13:25:19 +02001471
1472 LEVEL++;
1473
1474 /* module-header-stmts */
Michal Vasko5d24f6c2020-10-13 13:49:06 +02001475 if (modp->version) {
1476 ypr_substmt(ctx, LYEXT_SUBSTMT_VERSION, 0, modp->version == LYS_VERSION_1_1 ? "1.1" : "1", modp->exts);
Michal Vasko7c8439f2020-08-05 13:25:19 +02001477 }
1478 ypr_substmt(ctx, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns, modp->exts);
1479 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, module->prefix, modp->exts);
1480
1481 /* linkage-stmts (import/include) */
1482 yin_print_parsed_linkage(ctx, modp);
1483
1484 /* meta-stmts */
1485 if (module->org || module->contact || module->dsc || module->ref) {
Michal Vasko5233e962020-08-14 14:26:20 +02001486 ly_print_(out, "\n");
Michal Vasko7c8439f2020-08-05 13:25:19 +02001487 }
1488 ypr_substmt(ctx, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org, modp->exts);
1489 ypr_substmt(ctx, LYEXT_SUBSTMT_CONTACT, 0, module->contact, modp->exts);
1490 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc, modp->exts);
1491 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, module->ref, modp->exts);
1492
1493 /* revision-stmts */
1494 if (modp->revs) {
Michal Vasko5233e962020-08-14 14:26:20 +02001495 ly_print_(out, "\n");
Michal Vasko7c8439f2020-08-05 13:25:19 +02001496 }
1497 LY_ARRAY_FOR(modp->revs, u) {
1498 yprp_revision(ctx, &modp->revs[u]);
1499 }
1500
1501 /* body-stmts */
1502 yin_print_parsed_body(ctx, modp);
FredGand944bdc2019-11-05 21:57:07 +08001503
1504 LEVEL--;
Michal Vasko5233e962020-08-14 14:26:20 +02001505 ly_print_(out, "%*s</module>\n", INDENT);
FredGand944bdc2019-11-05 21:57:07 +08001506 ly_print_flush(out);
1507
1508 return LY_SUCCESS;
1509}
1510
Michal Vasko7c8439f2020-08-05 13:25:19 +02001511static void
1512yprp_belongsto(struct ypr_ctx *ctx, const struct lysp_submodule *submodp)
1513{
Michal Vaskoc3781c32020-10-06 14:04:08 +02001514 ypr_open(ctx, "belongs-to", "module", submodp->mod->name, 1);
Michal Vasko7c8439f2020-08-05 13:25:19 +02001515 LEVEL++;
1516 yprp_extension_instances(ctx, LYEXT_SUBSTMT_BELONGSTO, 0, submodp->exts, NULL, 0);
1517 ypr_substmt(ctx, LYEXT_SUBSTMT_PREFIX, 0, submodp->prefix, submodp->exts);
1518 LEVEL--;
1519 ypr_close(ctx, "belongs-to", 1);
1520}
1521
1522LY_ERR
Radek Krejci1deb5be2020-08-26 16:43:36 +02001523yin_print_parsed_submodule(struct ly_out *out, const struct lys_module *module, const struct lysp_submodule *submodp, uint32_t options)
Michal Vasko7c8439f2020-08-05 13:25:19 +02001524{
1525 LY_ARRAY_COUNT_TYPE u;
Radek Krejci52f65552020-09-01 17:03:35 +02001526 struct ypr_ctx ctx_ = {.out = out, .level = 0, .module = module, .options = options}, *ctx = &ctx_;
Michal Vasko7c8439f2020-08-05 13:25:19 +02001527
Michal Vasko5233e962020-08-14 14:26:20 +02001528 ly_print_(ctx->out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1529 ly_print_(ctx->out, "%*s<submodule name=\"%s\"\n", INDENT, submodp->name);
Michal Vasko7c8439f2020-08-05 13:25:19 +02001530 ypr_xmlns(ctx, module, 8);
1531 ypr_import_xmlns(ctx, (struct lysp_module *)submodp, 8);
Michal Vasko5233e962020-08-14 14:26:20 +02001532 ly_print_(ctx->out, ">\n");
Michal Vasko7c8439f2020-08-05 13:25:19 +02001533
1534 LEVEL++;
1535
1536 /* submodule-header-stmts */
1537 if (submodp->version) {
1538 ypr_substmt(ctx, LYEXT_SUBSTMT_VERSION, 0, submodp->version == LYS_VERSION_1_1 ? "1.1" : "1", submodp->exts);
1539 }
1540 yprp_belongsto(ctx, submodp);
1541
1542 /* linkage-stmts (import/include) */
1543 yin_print_parsed_linkage(ctx, (struct lysp_module *)submodp);
1544
1545 /* meta-stmts */
1546 if (submodp->org || submodp->contact || submodp->dsc || submodp->ref) {
Michal Vasko5233e962020-08-14 14:26:20 +02001547 ly_print_(out, "\n");
Michal Vasko7c8439f2020-08-05 13:25:19 +02001548 }
1549 ypr_substmt(ctx, LYEXT_SUBSTMT_ORGANIZATION, 0, submodp->org, submodp->exts);
1550 ypr_substmt(ctx, LYEXT_SUBSTMT_CONTACT, 0, submodp->contact, submodp->exts);
1551 ypr_substmt(ctx, LYEXT_SUBSTMT_DESCRIPTION, 0, submodp->dsc, submodp->exts);
1552 ypr_substmt(ctx, LYEXT_SUBSTMT_REFERENCE, 0, submodp->ref, submodp->exts);
1553
1554 /* revision-stmts */
1555 if (submodp->revs) {
Michal Vasko5233e962020-08-14 14:26:20 +02001556 ly_print_(out, "\n");
Michal Vasko7c8439f2020-08-05 13:25:19 +02001557 }
1558 LY_ARRAY_FOR(submodp->revs, u) {
1559 yprp_revision(ctx, &submodp->revs[u]);
1560 }
1561
1562 /* body-stmts */
1563 yin_print_parsed_body(ctx, (struct lysp_module *)submodp);
1564
1565 LEVEL--;
Michal Vasko5233e962020-08-14 14:26:20 +02001566 ly_print_(out, "%*s</submodule>\n", INDENT);
Michal Vasko7c8439f2020-08-05 13:25:19 +02001567 ly_print_flush(out);
1568
1569 return LY_SUCCESS;
1570}