blob: c975d71a746d7c7bcd77206e1cf628129495c94b [file] [log] [blame]
Radek Krejcida04f4a2015-05-21 12:54:09 +02001/**
Radek Krejciefdd0ce2015-05-26 16:48:29 +02002 * @file printer/yang.c
Radek Krejcida04f4a2015-05-21 12:54:09 +02003 * @author Radek Krejci <rkrejci@cesnet.cz>
Radek Krejciefdd0ce2015-05-26 16:48:29 +02004 * @brief YANG printer for libyang data model structure
Radek Krejcida04f4a2015-05-21 12:54:09 +02005 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
Radek Krejci54f6fb32016-02-24 12:56:39 +01008 * 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
Michal Vasko8de098c2016-02-26 10:00:25 +010011 *
Radek Krejci54f6fb32016-02-24 12:56:39 +010012 * https://opensource.org/licenses/BSD-3-Clause
Radek Krejcida04f4a2015-05-21 12:54:09 +020013 */
Radek Krejci43e3c312017-01-11 11:34:44 +010014#define _GNU_SOURCE
15#include <stdio.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020016#include <stdlib.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020017#include <string.h>
Michal Vasko25cb6c62016-02-12 14:36:21 +010018#include <stdint.h>
Michal Vaskof30ea3e2016-12-06 12:16:02 +010019#include <assert.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020020
Radek Krejci998a0b82015-08-17 13:14:36 +020021#include "common.h"
Radek Krejcia68ddeb2017-02-24 12:49:44 +010022#include "context.h"
Radek Krejci76b07902015-10-09 09:11:25 +020023#include "printer.h"
Michal Vasko2d162e12015-09-24 14:33:29 +020024#include "tree_schema.h"
Radek Krejcida04f4a2015-05-21 12:54:09 +020025
26#define INDENT ""
27#define LEVEL (level*2)
28
Michal Vasko1e62a092015-12-01 12:27:20 +010029static void yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask);
Radek Krejci8d6b7422017-02-03 14:42:13 +010030static void yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
31 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
32 struct lys_ext_instance **ext, unsigned int count);
Radek Krejcida04f4a2015-05-21 12:54:09 +020033
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020034static void
Michal Vasko25cb6c62016-02-12 14:36:21 +010035yang_encode(struct lyout *out, const char *text, int len)
36{
37 int i, start_len;
38 const char *start;
39 char special = 0;
40
41 if (!len) {
42 return;
43 }
44
45 if (len < 0) {
46 len = strlen(text);
47 }
48
49 start = text;
50 start_len = 0;
51 for (i = 0; i < len; ++i) {
52 switch (text[i]) {
53 case '\n':
54 case '\t':
55 case '\"':
56 case '\\':
57 special = text[i];
58 break;
59 default:
60 ++start_len;
61 break;
62 }
63
64 if (special) {
65 ly_write(out, start, start_len);
66 switch (special) {
67 case '\n':
68 ly_write(out, "\\n", 2);
69 break;
70 case '\t':
71 ly_write(out, "\\t", 2);
72 break;
73 case '\"':
74 ly_write(out, "\\\"", 2);
75 break;
76 case '\\':
77 ly_write(out, "\\\\", 2);
78 break;
79 }
80
81 start += start_len + 1;
82 start_len = 0;
83
84 special = 0;
85 }
86 }
87
88 ly_write(out, start, start_len);
89}
90
91static void
Radek Krejci32cce7c2015-12-09 16:44:13 +010092yang_print_open(struct lyout *out, int *flag)
93{
94 if (flag && !*flag) {
95 *flag = 1;
96 ly_print(out, " {\n");
97 }
98}
99
100static void
101yang_print_close(struct lyout *out, int level, int flag)
102{
103 if (flag) {
104 ly_print(out, "%*s}\n", LEVEL, INDENT);
105 } else {
106 ly_print(out, ";\n");
107 }
108}
109
110static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100111yang_print_text(struct lyout *out, int level, const char *name, const char *text, int singleline, int closed)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200112{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200113 const char *s, *t;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200114
Radek Krejci8d81e002015-12-10 11:18:59 +0100115 if (singleline) {
116 ly_print(out, "%*s%s \"", LEVEL, INDENT, name);
117 } else {
118 ly_print(out, "%*s%s\n", LEVEL, INDENT, name);
119 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200120
Radek Krejci8d81e002015-12-10 11:18:59 +0100121 ly_print(out, "%*s\"", LEVEL, INDENT);
122 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200123 t = text;
124 while ((s = strchr(t, '\n'))) {
Michal Vasko25cb6c62016-02-12 14:36:21 +0100125 yang_encode(out, t, s - t);
126 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200127 t = s + 1;
Radek Krejciadb8d8e2017-02-20 13:32:51 +0100128 if (*t != '\n') {
129 ly_print(out, "%*s ", LEVEL, INDENT);
130 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200131 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200132
范昌虎1006995277de5fc2016-10-08 07:33:29 -0400133 yang_encode(out, t, strlen(t));
Radek Krejci43e3c312017-01-11 11:34:44 +0100134 if (closed) {
135 ly_print(out, "\";\n");
136 } else {
137 ly_print(out, "\"");
138 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200139 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200140
141}
142
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200143static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100144yang_print_substmt(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text,
145 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size)
146{
Radek Krejcicfce0292017-01-13 12:37:57 +0100147 int i = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100148
149 if (!text) {
150 /* nothing to print */
151 return;
152 }
153
Radek Krejcicfce0292017-01-13 12:37:57 +0100154 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100155 i = lys_ext_iter(ext, ext_size, i + 1, substmt);
Radek Krejcifebdad72017-02-06 11:35:51 +0100156 } while (i != -1 && ext[i]->insubstmt_index != substmt_index);
Radek Krejcicfce0292017-01-13 12:37:57 +0100157
Radek Krejci43e3c312017-01-11 11:34:44 +0100158 if (ext_substmt_info[substmt].flags & SUBST_FLAG_ID) {
159 ly_print(out, "%*s%s %s%s", LEVEL, INDENT, ext_substmt_info[substmt].name, text, i == -1 ? ";\n" : "");
160 } else {
161 yang_print_text(out, level, ext_substmt_info[substmt].name, text,
162 (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) ? 0 : 1, i == -1 ? 1 : 0);
163 }
164
165 if (i != -1) {
166 ly_print(out, " {\n");
167 do {
168 yang_print_extension_instances(out, level + 1, module, substmt, substmt_index, &ext[i], 1);
169 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100170 i = lys_ext_iter(ext, ext_size, i + 1, substmt);
Radek Krejcifebdad72017-02-06 11:35:51 +0100171 } while (i != -1 && ext[i]->insubstmt_index != substmt_index);
Radek Krejci43e3c312017-01-11 11:34:44 +0100172 } while (i != -1);
173 ly_print(out, "%*s}\n", LEVEL, INDENT);
174 }
175}
176
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200177static void
Radek Krejci9ff0a922016-07-14 13:08:05 +0200178yang_print_iffeature(struct lyout *out, int level, const struct lys_module *module, struct lys_iffeature *iffeature)
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200179{
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200180 ly_print(out, "%*sif-feature \"", LEVEL, INDENT);
Michal Vasko77e8a952017-02-03 15:10:08 +0100181 ly_print_iffeature(out, module, iffeature, 0);
Radek Krejci43e3c312017-01-11 11:34:44 +0100182
183 /* extensions */
184 if (iffeature->ext_size) {
185 ly_print(out, "\" {\n");
186 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0, iffeature->ext, iffeature->ext_size);
187 ly_print(out, "%*s}\n", LEVEL, INDENT);
188 } else {
189 ly_print(out, "\";\n");
190 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200191}
192
Radek Krejci5dd25122017-01-11 17:28:13 +0100193/*
194 * Covers:
195 * extension (instances), if-features, config, mandatory, status, description, reference
196 */
197#define SNODE_COMMON_EXT 0x01
198#define SNODE_COMMON_IFF 0x02
199#define SNODE_COMMON_CONFIG 0x04
200#define SNODE_COMMON_MAND 0x08
201#define SNODE_COMMON_STATUS 0x10
202#define SNODE_COMMON_DSC 0x20
203#define SNODE_COMMON_REF 0x40
204static void
205yang_print_snode_common(struct lyout *out, int level, const struct lys_node *node, const struct lys_module *module,
206 int *flag, int mask)
207{
208 int i;
209 const char *status = NULL;
210
211 /* extensions */
212 if ((mask & SNODE_COMMON_EXT) && node->ext_size) {
213 yang_print_open(out, flag);
214 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
215 }
216
217 /* if-features */
218 if (mask & SNODE_COMMON_IFF) {
219 for (i = 0; i < node->iffeature_size; ++i) {
220 yang_print_open(out, flag);
221 yang_print_iffeature(out, level, module, &node->iffeature[i]);
222 }
223 }
224
225 /* config */
226 if (mask & SNODE_COMMON_CONFIG) {
227 /* get info if there is an extension for the config statement */
Radek Krejcibf285832017-01-26 16:05:41 +0100228 i = lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_CONFIG);
Radek Krejci5dd25122017-01-11 17:28:13 +0100229
230 if (lys_parent(node)) {
231 if ((node->flags & LYS_CONFIG_SET) || i != -1) {
232 /* print config when it differs from the parent or if it has an extension instance ... */
233 if (node->flags & LYS_CONFIG_W) {
234 yang_print_open(out, flag);
235 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
236 module, node->ext, node->ext_size);
237 } else if (node->flags & LYS_CONFIG_R) {
238 yang_print_open(out, flag);
239 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
240 module, node->ext, node->ext_size);
241 }
242 }
243 } else if (node->flags & LYS_CONFIG_R) {
244 /* ... or it's a top-level state node */
245 yang_print_open(out, flag);
246 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
247 module, node->ext, node->ext_size);
248 } else if (i != -1) {
249 /* the config has an extension, so we have to print it */
250 yang_print_open(out, flag);
251 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
252 module, node->ext, node->ext_size);
253 }
254 }
255
256 /* mandatory */
257 if ((mask & SNODE_COMMON_MAND) && (node->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
258 if (node->flags & LYS_MAND_TRUE) {
259 yang_print_open(out, flag);
260 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true",
261 module, node->ext, node->ext_size);
262 } else if (node->flags & LYS_MAND_FALSE) {
263 yang_print_open(out, flag);
264 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false",
265 module, node->ext, node->ext_size);
266 }
267 }
268
269 /* status */
270 if (mask & SNODE_COMMON_STATUS) {
271 if (node->flags & LYS_STATUS_CURR) {
272 yang_print_open(out, flag);
273 status = "current";
274 } else if (node->flags & LYS_STATUS_DEPRC) {
275 yang_print_open(out, flag);
276 status = "deprecated";
277 } else if (node->flags & LYS_STATUS_OBSLT) {
278 yang_print_open(out, flag);
279 status = "obsolete";
280 }
281 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, status, module, node->ext, node->ext_size);
282 }
283
284 /* description */
285 if ((mask & SNODE_COMMON_DSC) && node->dsc) {
286 yang_print_open(out, flag);
287 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, node->dsc,
288 module, node->ext, node->ext_size);
289 }
290
291 /* reference */
292 if ((mask & SNODE_COMMON_REF) && node->ref) {
293 yang_print_open(out, flag);
294 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, node->ref,
295 module, node->ext, node->ext_size);
296 }
297}
298
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200299static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100300yang_print_feature(struct lyout *out, int level, const struct lys_feature *feat)
Michal Vasko4773b762015-07-07 12:15:10 +0200301{
Radek Krejci5dd25122017-01-11 17:28:13 +0100302 int flag = 0;
Michal Vasko30f6e912015-07-07 12:24:27 +0200303
Radek Krejci32cce7c2015-12-09 16:44:13 +0100304 ly_print(out, "%*sfeature %s", LEVEL, INDENT, feat->name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100305 yang_print_snode_common(out, level + 1, (struct lys_node *)feat, feat->module, &flag, SNODE_COMMON_EXT |
306 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100307 yang_print_close(out, level, flag);
Michal Vasko4773b762015-07-07 12:15:10 +0200308}
309
310static void
Radek Krejcia1a6b762016-11-14 09:53:38 +0900311yang_print_extension(struct lyout *out, int level, const struct lys_ext *ext)
312{
Radek Krejcicfce0292017-01-13 12:37:57 +0100313 int flag = 0, flag2 = 0, i;
Radek Krejcia1a6b762016-11-14 09:53:38 +0900314
315 ly_print(out, "%*sextension %s", LEVEL, INDENT, ext->name);
316 level++;
317
Radek Krejci5dd25122017-01-11 17:28:13 +0100318 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
319 SNODE_COMMON_EXT);
320
Radek Krejcia1a6b762016-11-14 09:53:38 +0900321 if (ext->argument) {
322 yang_print_open(out, &flag);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900323
Radek Krejcicfce0292017-01-13 12:37:57 +0100324 ly_print(out, "%*sargument %s", LEVEL, INDENT, ext->argument);
325 i = -1;
Radek Krejcibf285832017-01-26 16:05:41 +0100326 while ((i = lys_ext_iter(ext->ext, ext->ext_size, i + 1, LYEXT_SUBSTMT_ARGUMENT)) != -1) {
Radek Krejcicfce0292017-01-13 12:37:57 +0100327 yang_print_open(out, &flag2);
328 yang_print_extension_instances(out, level + 1, ext->module, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->ext[i], 1);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900329 }
Radek Krejcibf285832017-01-26 16:05:41 +0100330 if ((ext->flags & LYS_YINELEM) || lys_ext_iter(ext->ext, ext->ext_size, 0, LYEXT_SUBSTMT_YINELEM) != -1) {
Radek Krejcicfce0292017-01-13 12:37:57 +0100331 yang_print_open(out, &flag2);
Radek Krejci87f90572017-01-24 11:19:42 +0100332 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, 0,
333 (ext->flags & LYS_YINELEM) ? "true" : "false", ext->module, ext->ext, ext->ext_size);
Radek Krejcicfce0292017-01-13 12:37:57 +0100334 }
335 yang_print_close(out, level, flag2);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900336 }
337
Radek Krejci5dd25122017-01-11 17:28:13 +0100338 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
339 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
340
Radek Krejcia1a6b762016-11-14 09:53:38 +0900341 level--;
342 yang_print_close(out, level, flag);
343}
344
345static void
Radek Krejciaa9c5202017-02-15 16:10:14 +0100346yang_print_restr(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *restr,
347 const char *name, const char *value)
Radek Krejci41726f92015-06-19 13:11:05 +0200348{
Radek Krejciaa9c5202017-02-15 16:10:14 +0100349 int flag = 0;
350
351 ly_print(out, "%*s%s \"", LEVEL, INDENT, name);
352 yang_encode(out, value, -1);
353 ly_print(out, "\"");
354
355 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100356 if (restr->ext_size) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100357 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100358 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, restr->ext, restr->ext_size);
359 }
Radek Krejcidaa95c42017-01-16 10:25:29 +0100360 if (restr->expr[0] == 0x15) {
361 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
Radek Krejciaa9c5202017-02-15 16:10:14 +0100362 yang_print_open(out, &flag);
Radek Krejcidaa95c42017-01-16 10:25:29 +0100363 yang_print_substmt(out, level, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match",
364 module, restr->ext, restr->ext_size);
365 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100366 if (restr->emsg != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100367 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100368 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg,
369 module, restr->ext, restr->ext_size);
370 }
371 if (restr->eapptag != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100372 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100373 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag,
374 module, restr->ext, restr->ext_size);
375 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200376 if (restr->dsc != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100377 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100378 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, restr->dsc,
379 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200380 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200381 if (restr->ref != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100382 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100383 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, restr->ref,
384 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200385 }
Radek Krejciaa9c5202017-02-15 16:10:14 +0100386 level--;
387 yang_print_close(out, level, flag);
Radek Krejci41726f92015-06-19 13:11:05 +0200388}
389
390static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100391yang_print_when(struct lyout *out, int level, const struct lys_module *module, const struct lys_when *when)
Michal Vasko1f0428a2015-07-07 14:55:04 +0200392{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100393 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100394 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200395
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100396 str = transform_json2schema(module, when->cond);
397 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200398 ly_print(out, "(!error!)");
399 return;
400 }
401
Michal Vasko25cb6c62016-02-12 14:36:21 +0100402 ly_print(out, "%*swhen \"", LEVEL, INDENT);
403 yang_encode(out, str, -1);
404 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100405 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200406
Michal Vasko1f0428a2015-07-07 14:55:04 +0200407 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100408
Radek Krejci43e3c312017-01-11 11:34:44 +0100409 if (when->ext_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100410 /* extension is stored in lys_when incompatible with lys_node, so we cannot use yang_print_snode_common() */
Radek Krejci43e3c312017-01-11 11:34:44 +0100411 yang_print_open(out, &flag);
412 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, when->ext, when->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200413 }
Radek Krejci11e88fd2017-01-16 15:34:37 +0100414 if (when->dsc != NULL) {
415 yang_print_open(out, &flag);
416 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, when->dsc,
417 module, when->ext, when->ext_size);
418 }
419 if (when->ref != NULL) {
420 yang_print_open(out, &flag);
421 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, when->ref,
422 module, when->ext, when->ext_size);
423 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100424
Michal Vasko1f0428a2015-07-07 14:55:04 +0200425 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100426 yang_print_close(out, level, flag);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200427}
428
429static void
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100430yang_print_unsigned(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
431 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size,
432 unsigned int attr_value)
433{
434 char *str;
435
Michal Vasko87e29a82018-05-21 13:50:43 +0200436 if (asprintf(&str, "%u", attr_value) == -1) {
437 LOGMEM(module->ctx);
438 return;
439 }
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100440 yang_print_substmt(out, level, substmt, substmt_index, str, module, ext, ext_size);
441 free(str);
442}
443
444static void
PavolVican2ed9f4e2017-02-16 00:08:45 +0100445yang_print_signed(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
446 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size,
447 signed int attr_value)
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100448{
449 char *str;
450
Michal Vasko87e29a82018-05-21 13:50:43 +0200451 if (asprintf(&str, "%d", attr_value) == -1) {
452 LOGMEM(module->ctx);
453 return;
454 }
PavolVican2ed9f4e2017-02-16 00:08:45 +0100455 yang_print_substmt(out, level, substmt, substmt_index, str, module, ext, ext_size);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100456 free(str);
457}
458
459static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100460yang_print_type(struct lyout *out, int level, const struct lys_module *module, const struct lys_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200461{
Radek Krejcidce5f972017-09-12 15:47:49 +0200462 unsigned int i;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100463 int flag = 0, flag2;
Michal Vasko0fb82c62015-10-20 13:41:53 +0200464 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100465 char *s;
Radek Krejcic071c542016-01-27 14:57:51 +0100466 struct lys_module *mod;
Radek Krejci25d782a2015-05-22 15:03:23 +0200467
Michal Vasko568b1952018-01-30 15:53:30 +0100468 if (!lys_type_is_local(type)) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100469 ly_print(out, "%*stype %s:%s", LEVEL, INDENT,
aweasta59b6b32018-05-14 16:04:54 -0500470 transform_module_name2import_prefix(module, lys_main_module(type->der->module)->name), type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200471 } else {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100472 ly_print(out, "%*stype %s", LEVEL, INDENT, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200473 }
474 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100475
476 /* extensions */
477 if (type->ext_size) {
478 yang_print_open(out, &flag);
479 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, type->ext, type->ext_size);
480 }
481
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200482 switch (type->base) {
483 case LY_TYPE_BINARY:
Michal Vasko4634cda2016-02-16 09:22:09 +0100484 if (type->info.binary.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100485 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100486 yang_print_restr(out, level, module, type->info.binary.length, "length", type->info.binary.length->expr);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200487 }
488 break;
489 case LY_TYPE_BITS:
490 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100491 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100492 ly_print(out, "%*sbit %s", LEVEL, INDENT, type->info.bits.bit[i].name);
493 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200494 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100495 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
496 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100497 if (!(type->info.bits.bit[i].flags & LYS_AUTOASSIGNED)) {
498 yang_print_open(out, &flag2);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100499 yang_print_unsigned(out, level, LYEXT_SUBSTMT_POSITION, 0, module,
500 type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
501 type->info.bits.bit[i].pos);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100502 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100503 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
504 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200505 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100506 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200507 }
508 break;
509 case LY_TYPE_DEC64:
Radek Krejcib51d5932016-09-08 14:02:52 +0200510 if (!type->der->type.der) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100511 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100512 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, 0, module,
513 type->ext, type->ext_size, type->info.dec64.dig);
Michal Vasko4634cda2016-02-16 09:22:09 +0100514 }
Michal Vaskoea505ee2015-07-07 14:01:00 +0200515 if (type->info.dec64.range != NULL) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100516 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100517 yang_print_restr(out, level, module, type->info.dec64.range, "range", type->info.dec64.range->expr);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200518 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200519 break;
520 case LY_TYPE_ENUM:
521 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100522 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100523 ly_print(out, "%*senum \"%s\"", LEVEL, INDENT, type->info.enums.enm[i].name);
524 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200525 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100526 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
527 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100528 if (!(type->info.enums.enm[i].flags & LYS_AUTOASSIGNED)) {
529 yang_print_open(out, &flag2);
PavolVican2ed9f4e2017-02-16 00:08:45 +0100530 yang_print_signed(out, level, LYEXT_SUBSTMT_VALUE, 0, module,
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100531 type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
532 type->info.enums.enm[i].value);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100533 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100534 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
535 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200536 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100537 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200538 }
539 break;
540 case LY_TYPE_IDENT:
Michal Vaskof2d43962016-09-02 11:10:16 +0200541 if (type->info.ident.count) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100542 yang_print_open(out, &flag);
Michal Vaskof2d43962016-09-02 11:10:16 +0200543 for (i = 0; i < type->info.ident.count; ++i) {
544 mod = lys_main_module(type->info.ident.ref[i]->module);
545 if (lys_main_module(module) == mod) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100546 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, type->info.ident.ref[i]->name,
547 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
Michal Vaskof2d43962016-09-02 11:10:16 +0200548 } else {
Michal Vasko87e29a82018-05-21 13:50:43 +0200549 if (asprintf(&s, "%s:%s", transform_module_name2import_prefix(module, mod->name),
550 type->info.ident.ref[i]->name) == -1) {
551 LOGMEM(module->ctx);
552 return;
553 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100554 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, s,
555 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
556 free(s);
Michal Vaskof2d43962016-09-02 11:10:16 +0200557 }
Michal Vasko4634cda2016-02-16 09:22:09 +0100558 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200559 }
560 break;
561 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200562 if (type->info.inst.req == 1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100563 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100564 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "true", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200565 } else if (type->info.inst.req == -1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100566 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100567 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "false", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200568 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200569 break;
570 case LY_TYPE_INT8:
571 case LY_TYPE_INT16:
572 case LY_TYPE_INT32:
573 case LY_TYPE_INT64:
574 case LY_TYPE_UINT8:
575 case LY_TYPE_UINT16:
576 case LY_TYPE_UINT32:
577 case LY_TYPE_UINT64:
Michal Vasko4634cda2016-02-16 09:22:09 +0100578 if (type->info.num.range) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100579 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100580 yang_print_restr(out, level, module, type->info.num.range, "range", type->info.num.range->expr);
Radek Krejcif2860132015-06-20 12:37:20 +0200581 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200582 break;
583 case LY_TYPE_LEAFREF:
Radek Krejci0dbff6a2016-07-17 12:40:18 +0200584 if (ly_strequal(type->der->name, "leafref", 0)) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100585 yang_print_open(out, &flag);
586 str = transform_json2schema(module, type->info.lref.path);
Radek Krejci43e3c312017-01-11 11:34:44 +0100587 yang_print_substmt(out, level, LYEXT_SUBSTMT_PATH, 0, str, module, type->ext, type->ext_size);
Michal Vasko4634cda2016-02-16 09:22:09 +0100588 lydict_remove(module->ctx, str);
589 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100590 if (type->info.lref.req == 1) {
591 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100592 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "true", module, type->ext, type->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100593 } else if (type->info.lref.req == -1) {
594 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100595 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "false", module, type->ext, type->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100596 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200597 break;
598 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200599 if (type->info.str.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100600 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100601 yang_print_restr(out, level, module, type->info.str.length, "length", type->info.str.length->expr);
Radek Krejci061bd522015-06-19 13:45:16 +0200602 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200603 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100604 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100605 yang_print_restr(out, level, module, &type->info.str.patterns[i],
606 "pattern", &type->info.str.patterns[i].expr[1]);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200607 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200608 break;
609 case LY_TYPE_UNION:
610 for (i = 0; i < type->info.uni.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100611 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200612 yang_print_type(out, level, module, &type->info.uni.types[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200613 }
614 break;
615 default:
616 /* other types do not have substatements */
617 break;
618 }
Radek Krejcie534c132016-11-23 13:32:31 +0100619
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200620 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100621 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200622}
623
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200624static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100625yang_print_must(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200626{
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100627 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200628
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100629 str = transform_json2schema(module, must->expr);
630 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200631 ly_print(out, "(!error!)");
632 return;
633 }
Radek Krejciaa9c5202017-02-15 16:10:14 +0100634 yang_print_restr(out, level, module, must, "must", str);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100635 lydict_remove(module->ctx, str);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200636}
637
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200638static void
Michal Vasko1a3f80b2018-03-23 11:35:53 +0100639yang_print_unique(struct lyout *out, int level, const struct lys_module *module, const struct lys_unique *uniq)
Michal Vasko1ef07972015-07-07 14:01:35 +0200640{
641 int i;
Michal Vasko1a3f80b2018-03-23 11:35:53 +0100642 const char *str;
Michal Vasko1ef07972015-07-07 14:01:35 +0200643
Radek Krejci76b07902015-10-09 09:11:25 +0200644 ly_print(out, "%*sunique \"", LEVEL, INDENT);
Radek Krejci581ce772015-11-10 17:22:40 +0100645 for (i = 0; i < uniq->expr_size; i++) {
Michal Vasko1a3f80b2018-03-23 11:35:53 +0100646 str = transform_json2schema(module, uniq->expr[i]);
647 ly_print(out, "%s%s", str, i + 1 < uniq->expr_size ? " " : "");
648 lydict_remove(module->ctx, str);
Michal Vasko1ef07972015-07-07 14:01:35 +0200649 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100650 ly_print(out, "\"");
Michal Vasko1ef07972015-07-07 14:01:35 +0200651}
652
653static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100654yang_print_refine(struct lyout *out, int level, const struct lys_module *module, const struct lys_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200655{
Radek Krejci5dd25122017-01-11 17:28:13 +0100656 int i, flag = 0;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200657 const char *str;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200658
Michal Vasko5d112852016-02-12 16:47:13 +0100659 str = transform_json2schema(module, refine->target_name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100660 ly_print(out, "%*srefine \"%s\"", LEVEL, INDENT, str);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200661 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200662 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200663
Radek Krejci5dd25122017-01-11 17:28:13 +0100664 yang_print_snode_common(out, level, (struct lys_node *)refine, module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200665 for (i = 0; i < refine->must_size; ++i) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100666 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200667 yang_print_must(out, level, module, &refine->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200668 }
Pavol Vican3e7c73a2016-08-17 10:24:11 +0200669 if (refine->target_type == LYS_CONTAINER) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100670 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100671 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, refine->mod.presence,
672 module, refine->ext, refine->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100673 }
674 for (i = 0; i < refine->dflt_size; ++i) {
675 yang_print_open(out, &flag);
676 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, refine->dflt[i], module, refine->ext, refine->ext_size);
677 }
678 if (refine->flags & LYS_CONFIG_W) {
679 yang_print_open(out, &flag);
680 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module, refine->ext, refine->ext_size);
681 } else if (refine->flags & LYS_CONFIG_R) {
682 yang_print_open(out, &flag);
683 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module, refine->ext, refine->ext_size);
684 }
685 if (refine->flags & LYS_MAND_TRUE) {
686 yang_print_open(out, &flag);
687 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module, refine->ext, refine->ext_size);
688 } else if (refine->flags & LYS_MAND_FALSE) {
689 yang_print_open(out, &flag);
690 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module, refine->ext, refine->ext_size);
691 }
692 if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200693 if (refine->flags & LYS_RFN_MINSET) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100694 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100695 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, module, refine->ext, refine->ext_size,
696 refine->mod.list.min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200697 }
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200698 if (refine->flags & LYS_RFN_MAXSET) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100699 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100700 if (refine->mod.list.max) {
701 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, module, refine->ext, refine->ext_size,
702 refine->mod.list.max);
703 } else {
704 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, "unbounded", module, refine->ext, refine->ext_size);
705 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200706 }
707 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100708 yang_print_snode_common(out, level, (struct lys_node *)refine, module, &flag, SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200709
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200710 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +0100711 yang_print_close(out, level, flag);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200712}
713
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200714static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100715yang_print_deviation(struct lyout *out, int level, const struct lys_module *module,
716 const struct lys_deviation *deviation)
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200717{
Radek Krejci033983b2017-01-13 12:43:20 +0100718 int i, j, p;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200719 const char *str;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200720
Michal Vasko5d112852016-02-12 16:47:13 +0100721 str = transform_json2schema(module, deviation->target_name);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200722 ly_print(out, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, str);
723 lydict_remove(module->ctx, str);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200724 level++;
725
Radek Krejci5dd25122017-01-11 17:28:13 +0100726 if (deviation->ext_size) {
727 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, deviation->ext, deviation->ext_size);
728 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100729 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, deviation->dsc,
730 module, deviation->ext, deviation->ext_size);
731 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, deviation->ref,
732 module, deviation->ext, deviation->ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200733
734 for (i = 0; i < deviation->deviate_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200735 ly_print(out, "%*sdeviate ", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200736 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100737 if (deviation->deviate[i].ext_size) {
738 ly_print(out, "not-supported {\n");
739 } else {
740 ly_print(out, "not-supported;\n");
741 continue;
742 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200743 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
Radek Krejci76b07902015-10-09 09:11:25 +0200744 ly_print(out, "add {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200745 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200746 ly_print(out, "replace {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200747 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200748 ly_print(out, "delete {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200749 }
750 level++;
751
Radek Krejci5dd25122017-01-11 17:28:13 +0100752 /* extensions */
753 if (deviation->deviate[i].ext_size) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100754 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
Radek Krejci5dd25122017-01-11 17:28:13 +0100755 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200756 }
757
Radek Krejci5dd25122017-01-11 17:28:13 +0100758 /* type */
759 if (deviation->deviate[i].type) {
760 yang_print_type(out, level, module, deviation->deviate[i].type);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200761 }
762
Radek Krejci5dd25122017-01-11 17:28:13 +0100763 /* units */
764 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, deviation->deviate[i].units, module,
765 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200766
Radek Krejci5dd25122017-01-11 17:28:13 +0100767 /* must */
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200768 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
Michal Vaskof9893382015-10-09 14:03:04 +0200769 yang_print_must(out, level, module, &deviation->deviate[i].must[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200770 }
771
Radek Krejci5dd25122017-01-11 17:28:13 +0100772 /* unique */
773
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200774 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
Michal Vasko1a3f80b2018-03-23 11:35:53 +0100775 yang_print_unique(out, level, module, &deviation->deviate[i].unique[j]);
Radek Krejci43e3c312017-01-11 11:34:44 +0100776 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +0100777 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100778 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100779 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejcicfce0292017-01-13 12:37:57 +0100780 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100781 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100782 if (p != -1) {
783 ly_print(out, " {\n");
784 do {
785 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, j,
786 &deviation->deviate[i].ext[p], 1);
787 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100788 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejci43e3c312017-01-11 11:34:44 +0100789 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100790 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100791 } while (p != -1);
792 ly_print(out, "%*s}\n", LEVEL, INDENT);
793 } else {
794 ly_print(out, ";\n");
795 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200796 }
797
Radek Krejci5dd25122017-01-11 17:28:13 +0100798 /* default */
Radek Krejci033983b2017-01-13 12:43:20 +0100799 for (j = 0; j < deviation->deviate[i].dflt_size; ++j) {
800 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, j, deviation->deviate[i].dflt[j], module,
Radek Krejci5dd25122017-01-11 17:28:13 +0100801 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200802 }
803
Radek Krejci5dd25122017-01-11 17:28:13 +0100804 /* config */
805 if (deviation->deviate[i].flags & LYS_CONFIG_W) {
806 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module,
807 deviation->deviate->ext, deviation->deviate[i].ext_size);
808 } else if (deviation->deviate[i].flags & LYS_CONFIG_R) {
809 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module,
810 deviation->deviate->ext, deviation->deviate[i].ext_size);
811 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100812
Radek Krejci5dd25122017-01-11 17:28:13 +0100813 /* mandatory */
814 if (deviation->deviate[i].flags & LYS_MAND_TRUE) {
815 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module,
816 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
817 } else if (deviation->deviate[i].flags & LYS_MAND_FALSE) {
818 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module,
819 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
820 }
821
822 /* min-elements */
823 if (deviation->deviate[i].min_set) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100824 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, module,
825 deviation->deviate[i].ext, deviation->deviate[i].ext_size,
826 deviation->deviate[i].min);
Radek Krejci5dd25122017-01-11 17:28:13 +0100827 }
828
829 /* max-elements */
830 if (deviation->deviate[i].max_set) {
831 if (deviation->deviate[i].max) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100832 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, module,
833 deviation->deviate[i].ext, deviation->deviate[i].ext_size,
834 deviation->deviate[i].max);
Radek Krejci5dd25122017-01-11 17:28:13 +0100835 } else {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100836 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, "unbounded", module,
837 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100838 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200839 }
840
841 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200842 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200843 }
844
845 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200846 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200847}
848
849static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100850yang_print_augment(struct lyout *out, int level, const struct lys_node_augment *augment)
Michal Vasko6f25f212015-07-07 15:42:07 +0200851{
Radek Krejci76512572015-08-04 09:47:08 +0200852 struct lys_node *sub;
Michal Vasko488c19e2015-10-20 15:21:00 +0200853 const char *str;
Michal Vasko6f25f212015-07-07 15:42:07 +0200854
Radek Krejci43e3c312017-01-11 11:34:44 +0100855 str = transform_json2schema(augment->module, augment->target_name);
Michal Vasko488c19e2015-10-20 15:21:00 +0200856 ly_print(out, "%*saugment \"%s\" {\n", LEVEL, INDENT, str);
Radek Krejci43e3c312017-01-11 11:34:44 +0100857 lydict_remove(augment->module->ctx, str);
Michal Vasko6f25f212015-07-07 15:42:07 +0200858 level++;
859
Radek Krejci5dd25122017-01-11 17:28:13 +0100860 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL, SNODE_COMMON_EXT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200861 if (augment->when) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100862 yang_print_when(out, level, augment->module, augment->when);
Michal Vasko6f25f212015-07-07 15:42:07 +0200863 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100864 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL,
865 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200866
867 LY_TREE_FOR(augment->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100868 /* only our augment */
869 if (sub->parent != (struct lys_node *)augment) {
870 continue;
871 }
Radek Krejci76b07902015-10-09 09:11:25 +0200872 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200873 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +0100874 LYS_USES | LYS_ANYDATA | LYS_CASE | LYS_ACTION | LYS_NOTIF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200875 }
876
877 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200878 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200879}
880
881static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100882yang_print_typedef(struct lyout *out, int level, const struct lys_module *module, const struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200883{
Radek Krejci033983b2017-01-13 12:43:20 +0100884 const char *dflt;
885
Radek Krejci76b07902015-10-09 09:11:25 +0200886 ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200887 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200888
Radek Krejci5dd25122017-01-11 17:28:13 +0100889 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL, SNODE_COMMON_EXT);
Radek Krejci76b07902015-10-09 09:11:25 +0200890 yang_print_type(out, level, module, &tpdf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200891 if (tpdf->units != NULL) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100892 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, module, tpdf->ext, tpdf->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200893 }
894 if (tpdf->dflt != NULL) {
Radek Krejcibd117f02016-11-04 16:28:08 +0100895 if (tpdf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +0100896 assert(strchr(tpdf->dflt, ':'));
897 if (!strncmp(tpdf->dflt, module->name, strchr(tpdf->dflt, ':') - tpdf->dflt)) {
898 /* local module */
899 dflt = lydict_insert(module->ctx, strchr(tpdf->dflt, ':') + 1, 0);
900 } else {
901 dflt = transform_json2schema(module, tpdf->dflt);
902 }
Radek Krejcibd117f02016-11-04 16:28:08 +0100903 } else {
904 dflt = tpdf->dflt;
905 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100906 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt, module, tpdf->ext, tpdf->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +0100907 if (tpdf->flags & LYS_DFLTJSON) {
908 lydict_remove(module->ctx, dflt);
909 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200910 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100911 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL,
912 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200913
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200914 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200915 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200916}
917
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200918static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100919yang_print_identity(struct lyout *out, int level, const struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200920{
Radek Krejci018f1f52016-08-03 16:01:20 +0200921 int flag = 0, i;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100922 struct lys_module *mod;
Radek Krejci43e3c312017-01-11 11:34:44 +0100923 char *str;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100924
925 ly_print(out, "%*sidentity %s", LEVEL, INDENT, ident->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200926 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200927
Radek Krejci5dd25122017-01-11 17:28:13 +0100928 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
929 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
930
Radek Krejci018f1f52016-08-03 16:01:20 +0200931 for (i = 0; i < ident->base_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100932 yang_print_open(out, &flag);
Radek Krejci018f1f52016-08-03 16:01:20 +0200933 mod = lys_main_module(ident->base[i]->module);
Radek Krejci43e3c312017-01-11 11:34:44 +0100934 if (lys_main_module(ident->module) == mod) {
Radek Krejcib5e58d32017-01-23 13:45:59 +0100935 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, ident->base[i]->name,
Radek Krejci43e3c312017-01-11 11:34:44 +0100936 ident->module, ident->ext, ident->ext_size);
937 } else {
Michal Vasko87e29a82018-05-21 13:50:43 +0200938 if (asprintf(&str, "%s:%s", transform_module_name2import_prefix(ident->module, mod->name), ident->base[i]->name) == -1) {
939 LOGMEM(ident->module->ctx);
940 return;
941 }
Radek Krejcib5e58d32017-01-23 13:45:59 +0100942 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, str,
Radek Krejci43e3c312017-01-11 11:34:44 +0100943 ident->module, ident->ext, ident->ext_size);
944 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200945 }
946 }
Radek Krejci6793db02015-05-22 17:49:54 +0200947
Radek Krejci5dd25122017-01-11 17:28:13 +0100948 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
949 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
950
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200951 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100952 yang_print_close(out, level, flag);
Radek Krejci6793db02015-05-22 17:49:54 +0200953}
954
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200955static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100956yang_print_container(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200957{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100958 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +0200959 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200960 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200961
Radek Krejci32cce7c2015-12-09 16:44:13 +0100962 ly_print(out, "%*scontainer %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200963 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200964
Radek Krejci5dd25122017-01-11 17:28:13 +0100965 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +0100966 if (cont->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100967 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +0100968 yang_print_when(out, level, node->module, cont->when);
969 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200970 for (i = 0; i < cont->iffeature_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +0100971 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +0200972 yang_print_iffeature(out, level, node->module, &cont->iffeature[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200973 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200974 for (i = 0; i < cont->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100975 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200976 yang_print_must(out, level, node->module, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200977 }
Radek Krejci8d81e002015-12-10 11:18:59 +0100978 if (cont->presence != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100979 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100980 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence,
981 node->module, node->ext, node->ext_size);
Michal Vasko4773b762015-07-07 12:15:10 +0200982 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100983 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG |
984 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200985 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100986 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200987 yang_print_typedef(out, level, node->module, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200988 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200989 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100990 /* augments */
991 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200992 continue;
993 }
Radek Krejci32cce7c2015-12-09 16:44:13 +0100994 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100995 yang_print_snode(out, level, sub, LYS_GROUPING);
996 }
997 LY_TREE_FOR(node->child, sub) {
998 /* augments */
999 if (sub->parent != node) {
1000 continue;
1001 }
1002 yang_print_open(out, &flag);
1003 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1004 LYS_USES | LYS_ANYDATA );
1005 }
1006 LY_TREE_FOR(node->child, sub) {
1007 /* augments */
1008 if (sub->parent != node) {
1009 continue;
1010 }
1011 yang_print_open(out, &flag);
1012 yang_print_snode(out, level, sub, LYS_ACTION);
1013 }
1014 LY_TREE_FOR(node->child, sub) {
1015 /* augments */
1016 if (sub->parent != node) {
1017 continue;
1018 }
1019 yang_print_open(out, &flag);
Radek Krejci033983b2017-01-13 12:43:20 +01001020 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001021 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001022
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001023 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001024 yang_print_close(out, level, flag);
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001025}
1026
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001027static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001028yang_print_case(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001029{
Radek Krejci5dd25122017-01-11 17:28:13 +01001030 int flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001031 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001032 struct lys_node_case *cas = (struct lys_node_case *)node;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001033
Radek Krejci744c2d42017-03-26 13:30:00 -05001034 if (!(node->flags & LYS_IMPLICIT)) {
1035 ly_print(out, "%*scase %s", LEVEL, INDENT, cas->name);
1036 level++;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001037
Radek Krejci744c2d42017-03-26 13:30:00 -05001038 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1039 if (cas->when) {
1040 yang_print_open(out, &flag);
1041 yang_print_when(out, level, node->module, cas->when);
1042 }
1043 yang_print_snode_common(out, level, node, node->module, &flag,
1044 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
1045 } else {
1046 flag = 1;
Michal Vasko1f0428a2015-07-07 14:55:04 +02001047 }
1048
Radek Krejci744c2d42017-03-26 13:30:00 -05001049 /* print children */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001050 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001051 /* augments */
1052 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001053 continue;
1054 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001055 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001056 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001057 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejcibf2abff2016-08-23 15:51:52 +02001058 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001059 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001060
Radek Krejci744c2d42017-03-26 13:30:00 -05001061 if (node->flags & LYS_IMPLICIT) {
1062 /* do not print anything about the case, it was implicitely added by libyang */
1063 return;
1064 }
1065
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001066 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001067 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001068}
1069
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001070static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001071yang_print_choice(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001072{
Radek Krejci5dd25122017-01-11 17:28:13 +01001073 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001074 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001075 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001076
Radek Krejci5dd25122017-01-11 17:28:13 +01001077 ly_print(out, "%*schoice %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001078 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001079
1080 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1081 if (choice->when) {
1082 yang_print_open(out, &flag);
1083 yang_print_when(out, level, node->module, choice->when);
1084 }
1085 for (i = 0; i < choice->iffeature_size; i++) {
1086 yang_print_open(out, &flag);
1087 yang_print_iffeature(out, level, node->module, &choice->iffeature[i]);
1088 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001089 if (choice->dflt != NULL) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001090 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001091 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt->name,
1092 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001093 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001094 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1095 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001096
Radek Krejci1d82ef62015-08-07 14:44:40 +02001097 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001098 /* augments */
1099 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001100 continue;
1101 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001102 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001103 yang_print_snode(out, level, sub,
Radek Krejci5dd25122017-01-11 17:28:13 +01001104 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_CASE);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001105 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001106
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001107 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001108 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001109}
1110
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001111static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001112yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001113{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001114 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001115 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001116 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001117
Radek Krejci76b07902015-10-09 09:11:25 +02001118 ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001119 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001120
1121 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001122 if (leaf->when) {
1123 yang_print_when(out, level, node->module, leaf->when);
1124 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001125 for (i = 0; i < leaf->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001126 yang_print_iffeature(out, level, node->module, &leaf->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001127 }
Radek Krejci76b07902015-10-09 09:11:25 +02001128 yang_print_type(out, level, node->module, &leaf->type);
Radek Krejci43e3c312017-01-11 11:34:44 +01001129 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, leaf->units,
1130 node->module, node->ext, node->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +01001131 for (i = 0; i < leaf->must_size; i++) {
1132 yang_print_must(out, level, node->module, &leaf->must[i]);
1133 }
Michal Vaskod875e882016-05-19 10:57:30 +02001134 if (leaf->dflt) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001135 if (leaf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001136 assert(strchr(leaf->dflt, ':'));
1137 if (!strncmp(leaf->dflt, lys_node_module(node)->name, strchr(leaf->dflt, ':') - leaf->dflt)) {
1138 /* local module */
1139 dflt = lydict_insert(node->module->ctx, strchr(leaf->dflt, ':') + 1, 0);
1140 } else {
1141 dflt = transform_json2schema(node->module, leaf->dflt);
1142 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001143 } else {
1144 dflt = leaf->dflt;
1145 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001146 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt,
1147 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001148 if (leaf->flags & LYS_DFLTJSON) {
1149 lydict_remove(node->module->ctx, dflt);
1150 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001151 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001152 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1153 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001154 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001155 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +02001156}
1157
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001158static void
Radek Krejcibf2abff2016-08-23 15:51:52 +02001159yang_print_anydata(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko16083662015-06-09 14:00:45 +02001160{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001161 int i, flag = 0;
Radek Krejcibf2abff2016-08-23 15:51:52 +02001162 struct lys_node_anydata *any = (struct lys_node_anydata *)node;
Michal Vasko16083662015-06-09 14:00:45 +02001163
Michal Vaskob3d6d192018-11-05 10:02:10 +01001164 if (!lys_parent(node) && !strcmp(node->name, "config") && !strcmp(node->module->name, "ietf-netconf")) {
1165 /* node added by libyang, not actually in the model */
1166 return;
1167 }
1168
Radek Krejcibf2abff2016-08-23 15:51:52 +02001169 ly_print(out, "%*s%s %s", LEVEL, INDENT, any->nodetype == LYS_ANYXML ? "anyxml" : "anydata", any->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001170 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001171
1172 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1173 if (any->when) {
1174 yang_print_open(out, &flag);
1175 yang_print_when(out, level, node->module, any->when);
1176 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001177 for (i = 0; i < any->iffeature_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001178 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001179 yang_print_iffeature(out, level, node->module, &any->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001180 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001181 for (i = 0; i < any->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001182 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001183 yang_print_must(out, level, node->module, &any->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001184 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001185 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1186 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001187 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001188 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001189}
1190
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001191static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001192yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001193{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001194 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001195 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001196 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001197
Radek Krejci76b07902015-10-09 09:11:25 +02001198 ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001199 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001200 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001201 if (llist->when) {
1202 yang_print_when(out, level, llist->module, llist->when);
1203 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001204 for (i = 0; i < llist->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001205 yang_print_iffeature(out, level, node->module, &llist->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001206 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001207 yang_print_type(out, level, node->module, &llist->type);
1208 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, llist->units,
1209 node->module, node->ext, node->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001210 for (i = 0; i < llist->must_size; i++) {
1211 yang_print_must(out, level, node->module, &llist->must[i]);
1212 }
Pavol Vican38321d02016-08-16 14:56:02 +02001213 for (i = 0; i < llist->dflt_size; ++i) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001214 if (llist->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001215 assert(strchr(llist->dflt[i], ':'));
1216 if (!strncmp(llist->dflt[i], lys_node_module(node)->name, strchr(llist->dflt[i], ':') - llist->dflt[i])) {
1217 /* local module */
1218 dflt = lydict_insert(node->module->ctx, strchr(llist->dflt[i], ':') + 1, 0);
1219 } else {
1220 dflt = transform_json2schema(node->module, llist->dflt[i]);
1221 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001222 } else {
1223 dflt = llist->dflt[i];
1224 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001225 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, dflt,
1226 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001227 if (llist->flags & LYS_DFLTJSON) {
1228 lydict_remove(node->module->ctx, dflt);
1229 }
Pavol Vican38321d02016-08-16 14:56:02 +02001230 }
Radek Krejci178a0942017-01-16 15:36:35 +01001231 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001232 if (llist->min > 0) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001233 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, node->module, node->ext, node->ext_size, llist->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001234 }
1235 if (llist->max > 0) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001236 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, node->module, node->ext, node->ext_size, llist->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001237 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001238 if (llist->flags & LYS_USERORDERED) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001239 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1240 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001241 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001242 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1243 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001244 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001245 yang_print_snode_common(out, level, node, node->module, NULL,
1246 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001247 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001248 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001249}
1250
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001251static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001252yang_print_list(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001253{
Radek Krejci5dd25122017-01-11 17:28:13 +01001254 int i, p, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001255 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001256 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001257
Radek Krejci5dd25122017-01-11 17:28:13 +01001258 ly_print(out, "%*slist %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001259 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001260 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001261 if (list->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001262 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001263 yang_print_when(out, level, list->module, list->when);
1264 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001265 for (i = 0; i < list->iffeature_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001266 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001267 yang_print_iffeature(out, level, node->module, &list->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001268 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001269 for (i = 0; i < list->must_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001270 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001271 yang_print_must(out, level, list->module, &list->must[i]);
1272 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001273 if (list->keys_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001274 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001275 yang_print_substmt(out, level, LYEXT_SUBSTMT_KEY, 0, list->keys_str,
1276 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001277 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001278 for (i = 0; i < list->unique_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001279 yang_print_open(out, &flag);
Michal Vasko1a3f80b2018-03-23 11:35:53 +01001280 yang_print_unique(out, level, node->module, &list->unique[i]);
Radek Krejci43e3c312017-01-11 11:34:44 +01001281 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +01001282 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +01001283 do {
Radek Krejcibf285832017-01-26 16:05:41 +01001284 p = lys_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +01001285 } while (p != -1 && list->ext[p]->insubstmt_index != i);
Radek Krejci43e3c312017-01-11 11:34:44 +01001286 if (p != -1) {
1287 ly_print(out, " {\n");
1288 do {
1289 yang_print_extension_instances(out, level + 1, list->module, LYEXT_SUBSTMT_UNIQUE, i, &list->ext[p], 1);
1290 do {
Radek Krejcibf285832017-01-26 16:05:41 +01001291 p = lys_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +01001292 } while (p != -1 && list->ext[p]->insubstmt_index != i);
Radek Krejci43e3c312017-01-11 11:34:44 +01001293 } while (p != -1);
1294 ly_print(out, "%*s}\n", LEVEL, INDENT);
1295 } else {
1296 ly_print(out, ";\n");
1297 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001298 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001299 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001300 if (list->min > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001301 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001302 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, node->module, node->ext, node->ext_size, list->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001303 }
1304 if (list->max > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001305 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001306 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, node->module, node->ext, node->ext_size, list->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001307 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001308 if (list->flags & LYS_USERORDERED) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001309 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001310 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1311 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001312 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001313 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001314 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1315 node->module, node->ext, node->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001316 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001317 yang_print_snode_common(out, level, node, node->module, &flag,
1318 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001319 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001320 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001321 yang_print_typedef(out, level, list->module, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001322 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001323
Radek Krejci1d82ef62015-08-07 14:44:40 +02001324 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001325 /* augments */
1326 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001327 continue;
1328 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001329 yang_print_open(out, &flag);
1330 yang_print_snode(out, level, sub, LYS_GROUPING);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001331 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001332
1333 LY_TREE_FOR(node->child, sub) {
1334 /* augments */
1335 if (sub->parent != node) {
1336 continue;
1337 }
1338 yang_print_open(out, &flag);
1339 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Michal Vaskobe291132017-05-25 11:26:32 +02001340 LYS_USES | LYS_ANYDATA);
Radek Krejci5dd25122017-01-11 17:28:13 +01001341 }
1342
1343 LY_TREE_FOR(node->child, sub) {
1344 /* augments */
1345 if (sub->parent != node) {
1346 continue;
1347 }
1348 yang_print_open(out, &flag);
1349 yang_print_snode(out, level, sub, LYS_ACTION);
1350 }
1351
1352 LY_TREE_FOR(node->child, sub) {
1353 /* augments */
1354 if (sub->parent != node) {
1355 continue;
1356 }
1357 yang_print_open(out, &flag);
1358 yang_print_snode(out, level, sub, LYS_NOTIF);
1359 }
1360
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001361 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001362 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001363}
1364
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001365static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001366yang_print_grouping(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001367{
Radek Krejci5dd25122017-01-11 17:28:13 +01001368 int i, flag = 0;
Michal Vasko0c5e9282016-02-15 13:11:57 +01001369 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001370 struct lys_node_grp *grp = (struct lys_node_grp *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001371
Radek Krejci5dd25122017-01-11 17:28:13 +01001372 ly_print(out, "%*sgrouping %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001373 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001374
Radek Krejci5dd25122017-01-11 17:28:13 +01001375 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_STATUS |
1376 SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001377
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001378 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001379 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001380 yang_print_typedef(out, level, node->module, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001381 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001382
Michal Vasko0c5e9282016-02-15 13:11:57 +01001383 LY_TREE_FOR(node->child, sub) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001384 yang_print_open(out, &flag);
1385 yang_print_snode(out, level, sub, LYS_GROUPING);
1386 }
1387
1388 LY_TREE_FOR(node->child, sub) {
1389 yang_print_open(out, &flag);
1390 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1391 LYS_USES | LYS_ANYDATA);
1392 }
1393
1394 LY_TREE_FOR(node->child, sub) {
1395 yang_print_open(out, &flag);
1396 yang_print_snode(out, level, sub, LYS_ACTION);
1397 }
1398
1399 LY_TREE_FOR(node->child, sub) {
1400 yang_print_open(out, &flag);
1401 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001402 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001403
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001404 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001405 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001406}
1407
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001408static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001409yang_print_uses(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001410{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001411 int i, flag = 0;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001412 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001413 struct lys_module *mod;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001414
Radek Krejci76b07902015-10-09 09:11:25 +02001415 ly_print(out, "%*suses ", LEVEL, INDENT);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001416 if (node->child) {
Michal Vasko6c629ac2016-02-15 14:08:23 +01001417 mod = lys_node_module(node->child);
Michal Vasko1dae8ec2016-02-15 14:49:01 +01001418 if (lys_node_module(node) != mod) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001419 ly_print(out, "%s:", transform_module_name2import_prefix(node->module, mod->name));
1420 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +02001421 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001422 ly_print(out, "%s", uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001423 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001424
Radek Krejci5dd25122017-01-11 17:28:13 +01001425 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001426 if (uses->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001427 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001428 yang_print_when(out, level, node->module, uses->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001429 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001430 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_IFF |
1431 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001432 for (i = 0; i < uses->refine_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001433 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001434 yang_print_refine(out, level, node->module, &uses->refine[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001435 }
Michal Vasko6f25f212015-07-07 15:42:07 +02001436 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001437 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001438 yang_print_augment(out, level, &uses->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001439 }
1440
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001441 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001442 yang_print_close(out, level, flag);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001443}
1444
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001445static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001446yang_print_input_output(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko5bbae102015-06-16 12:16:44 +02001447{
Michal Vaskof4d3d742015-06-16 11:51:09 +02001448 int i;
Radek Krejci76512572015-08-04 09:47:08 +02001449 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001450 struct lys_node_inout *inout = (struct lys_node_inout *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001451
Radek Krejci76b07902015-10-09 09:11:25 +02001452 ly_print(out, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LYS_INPUT ? "input" : "output"));
Michal Vaskof4d3d742015-06-16 11:51:09 +02001453 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001454
Radek Krejcie534c132016-11-23 13:32:31 +01001455 if (node->ext_size) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001456 yang_print_extension_instances(out, level, node->module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001457 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001458 for (i = 0; i < inout->must_size; i++) {
1459 yang_print_must(out, level, node->module, &inout->must[i]);
1460 }
Radek Krejcie534c132016-11-23 13:32:31 +01001461 for (i = 0; i < inout->tpdf_size; i++) {
1462 yang_print_typedef(out, level, node->module, &inout->tpdf[i]);
1463 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001464 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001465 /* augments */
1466 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001467 continue;
1468 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001469 yang_print_snode(out, level, sub, LYS_GROUPING);
1470 }
1471 LY_TREE_FOR(node->child, sub) {
1472 /* augments */
1473 if (sub->parent != node) {
1474 continue;
1475 }
1476 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1477 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001478 }
1479
1480 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001481 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001482}
1483
1484static void
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001485yang_print_rpc_action(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskof4d3d742015-06-16 11:51:09 +02001486{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001487 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001488 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001489 struct lys_node_rpc_action *rpc = (struct lys_node_rpc_action *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001490
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001491 ly_print(out, "%*s%s %s", LEVEL, INDENT, (node->nodetype == LYS_RPC ? "rpc" : "action"), node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001492
1493 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001494 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF |
1495 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko4773b762015-07-07 12:15:10 +02001496
Michal Vaskof4d3d742015-06-16 11:51:09 +02001497 for (i = 0; i < rpc->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001498 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001499 yang_print_typedef(out, level, node->module, &rpc->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001500 }
1501
Radek Krejci1d82ef62015-08-07 14:44:40 +02001502 LY_TREE_FOR(node->child, sub) {
Michal Vasko8b942f02017-01-24 13:12:59 +01001503 /* augments and implicit nodes */
1504 if ((sub->parent != node) || ((sub->nodetype & (LYS_INPUT | LYS_OUTPUT) && (sub->flags & LYS_IMPLICIT)))) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001505 continue;
1506 }
1507 yang_print_open(out, &flag);
PavolVican8f5959b2017-02-21 15:39:02 +01001508 yang_print_snode(out, level, sub, LYS_INPUT | LYS_OUTPUT | LYS_GROUPING);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001509 }
1510
1511 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001512 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001513}
1514
1515static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001516yang_print_notif(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko7690bc12015-06-16 12:26:05 +02001517{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001518 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001519 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001520 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001521
Radek Krejci32cce7c2015-12-09 16:44:13 +01001522 ly_print(out, "%*snotification %s", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001523
1524 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001525 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Radek Krejci12032a52016-07-29 15:42:56 +02001526 for (i = 0; i < notif->must_size; i++) {
1527 yang_print_open(out, &flag);
1528 yang_print_must(out, level, node->module, &notif->must[i]);
1529 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001530 yang_print_snode_common(out, level, node, node->module, &flag,
1531 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
1532 for (i = 0; i < notif->tpdf_size; i++) {
1533 yang_print_open(out, &flag);
1534 yang_print_typedef(out, level, node->module, &notif->tpdf[i]);
1535 }
1536 LY_TREE_FOR(node->child, sub) {
1537 /* augments */
1538 if (sub->parent != node) {
1539 continue;
1540 }
1541 yang_print_open(out, &flag);
1542 yang_print_snode(out, level, sub, LYS_GROUPING);
1543 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001544 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001545 /* augments */
1546 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001547 continue;
1548 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001549 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001550 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001551 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +01001552 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001553 }
1554
1555 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001556 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001557}
1558
1559static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001560yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001561{
Radek Krejci2c99a622017-01-12 10:11:13 +01001562 if (node->nodetype & mask) {
1563 if ((node->nodetype & (LYS_INPUT | LYS_OUTPUT)) && (node->flags & LYS_IMPLICIT)) {
1564 /* implicit input/output node is not supposed to be printed */
1565 return;
1566 } else if (!node->parent ||
1567 (node->parent->nodetype == LYS_AUGMENT && node != node->parent->child) ||
1568 (node->parent->nodetype != LYS_AUGMENT && node->prev->next)) {
1569 /* do not print the blank line before the first data-def node */
1570 ly_print(out, "\n");
1571 }
1572 }
1573
Radek Krejci1d82ef62015-08-07 14:44:40 +02001574 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +02001575 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +02001576 yang_print_container(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001577 break;
Radek Krejci76512572015-08-04 09:47:08 +02001578 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +02001579 yang_print_choice(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001580 break;
Radek Krejci76512572015-08-04 09:47:08 +02001581 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +02001582 yang_print_leaf(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001583 break;
Radek Krejci76512572015-08-04 09:47:08 +02001584 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001585 yang_print_leaflist(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001586 break;
Radek Krejci76512572015-08-04 09:47:08 +02001587 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001588 yang_print_list(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001589 break;
Radek Krejci76512572015-08-04 09:47:08 +02001590 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +02001591 yang_print_uses(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001592 break;
Radek Krejci76512572015-08-04 09:47:08 +02001593 case LYS_GROUPING:
Radek Krejci76b07902015-10-09 09:11:25 +02001594 yang_print_grouping(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001595 break;
Radek Krejci76512572015-08-04 09:47:08 +02001596 case LYS_ANYXML:
Radek Krejcibf2abff2016-08-23 15:51:52 +02001597 case LYS_ANYDATA:
1598 yang_print_anydata(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001599 break;
Radek Krejci76512572015-08-04 09:47:08 +02001600 case LYS_CASE:
Radek Krejci76b07902015-10-09 09:11:25 +02001601 yang_print_case(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001602 break;
Radek Krejci5dd25122017-01-11 17:28:13 +01001603 case LYS_RPC:
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001604 case LYS_ACTION:
1605 yang_print_rpc_action(out, level, node);
1606 break;
Radek Krejci76512572015-08-04 09:47:08 +02001607 case LYS_INPUT:
1608 case LYS_OUTPUT:
Radek Krejci2c99a622017-01-12 10:11:13 +01001609 yang_print_input_output(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001610 break;
Michal Vaskob15cae22016-09-15 09:40:56 +02001611 case LYS_NOTIF:
1612 yang_print_notif(out, level, node);
1613 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001614 default:
1615 break;
1616 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001617}
1618
Radek Krejci7417a082017-02-16 11:07:59 +01001619static void
1620yang_print_revision(struct lyout *out, int level, const struct lys_module *module, const struct lys_revision *rev)
1621{
1622 if (rev->dsc || rev->ref || rev->ext_size) {
Radek Krejci5fb50502017-02-20 13:58:08 +01001623 ly_print(out, "%*srevision %s {\n", LEVEL, INDENT, rev->date);
Radek Krejci7417a082017-02-16 11:07:59 +01001624 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0, rev->ext, rev->ext_size);
1625 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_DESCRIPTION, 0, rev->dsc, module, rev->ext, rev->ext_size);
1626 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_REFERENCE, 0, rev->ref, module, rev->ext, rev->ext_size);
1627 ly_print(out, "%*s}\n", LEVEL, INDENT);
1628 } else {
1629 ly_print(out, "%*srevision %s;\n", LEVEL, INDENT, rev->date);
1630 }
1631}
1632
Radek Krejci37f9ba32017-02-10 16:50:35 +01001633static int
1634yang_print_model_(struct lyout *out, int level, const struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001635{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001636 unsigned int i;
Radek Krejci37f9ba32017-02-10 16:50:35 +01001637 int p;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001638
Radek Krejci1d82ef62015-08-07 14:44:40 +02001639 struct lys_node *node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001640
Radek Krejci8d81e002015-12-10 11:18:59 +01001641 /* (sub)module-header-stmts */
Michal Vasko116172e2015-07-07 11:54:37 +02001642 if (module->type) {
Radek Krejci37f9ba32017-02-10 16:50:35 +01001643 ly_print(out, "%*ssubmodule %s {%s\n", LEVEL, INDENT, module->name,
1644 (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001645 level++;
Radek Krejci13fde922018-05-16 10:45:58 +02001646 if (module->version || lys_ext_iter(module->ext, module->ext_size, 0, LYEXT_SUBSTMT_VERSION) != -1) {
1647 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == LYS_VERSION_1_1 ? "1.1" : "1",
Radek Krejci43e3c312017-01-11 11:34:44 +01001648 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001649 }
Radek Krejci76b07902015-10-09 09:11:25 +02001650 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Radek Krejcicfce0292017-01-13 12:37:57 +01001651 p = -1;
Radek Krejcibf285832017-01-26 16:05:41 +01001652 while ((p = lys_ext_iter(module->ext, module->ext_size, p + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001653 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0, &module->ext[p], 1);
1654 }
1655 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1656 module, module->ext, module->ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001657 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001658 } else {
Radek Krejci37f9ba32017-02-10 16:50:35 +01001659 ly_print(out, "%*smodule %s {%s\n", LEVEL, INDENT, module->name,
1660 (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001661 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001662 if (module->version) {
Radek Krejci13fde922018-05-16 10:45:58 +02001663 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == LYS_VERSION_1_1 ? "1.1" : "1",
Radek Krejci43e3c312017-01-11 11:34:44 +01001664 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001665 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001666 yang_print_substmt(out, level, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns,
1667 module, module->ext, module->ext_size);
1668 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1669 module, module->ext, module->ext_size);
Michal Vasko116172e2015-07-07 11:54:37 +02001670 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001671
Radek Krejci8d81e002015-12-10 11:18:59 +01001672 /* linkage-stmts */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001673 for (i = 0; i < module->imp_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001674 ly_print(out, "\n%*simport %s {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001675 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001676 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1677 module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci39228d22017-01-13 12:43:55 +01001678 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->imp[i].prefix,
1679 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001680 if (module->imp[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001681 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->imp[i].rev,
1682 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001683 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001684 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->imp[i].dsc,
1685 module, module->imp[i].ext, module->imp[i].ext_size);
1686 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->imp[i].ref,
1687 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001688 level--;
Michal Vaskoc8e3ce02016-02-12 14:28:35 +01001689 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001690 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001691 for (i = 0; i < module->inc_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001692 if (module->inc[i].rev[0] || module->inc[i].dsc || module->inc[i].ref || module->inc[i].ext_size) {
1693 ly_print(out, "\n%*sinclude %s {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci8d81e002015-12-10 11:18:59 +01001694 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001695 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1696 module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001697 if (module->inc[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001698 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->inc[i].rev,
1699 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001700 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001701 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->inc[i].dsc,
1702 module, module->inc[i].ext, module->inc[i].ext_size);
1703 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->inc[i].ref,
1704 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001705 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001706 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001707 } else {
Radek Krejcie534c132016-11-23 13:32:31 +01001708 ly_print(out, "\n%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001709 }
1710 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001711
Radek Krejci8d81e002015-12-10 11:18:59 +01001712 /* meta-stmts */
1713 if (module->org || module->contact || module->dsc || module->ref) {
1714 ly_print(out, "\n");
1715 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001716 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org,
1717 module, module->ext, module->ext_size);
1718 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONTACT, 0, module->contact,
1719 module, module->ext, module->ext_size);
1720 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc,
1721 module, module->ext, module->ext_size);
1722 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->ref,
1723 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001724
1725 /* revision-stmts */
1726 if (module->rev_size) {
1727 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001728 }
1729 for (i = 0; i < module->rev_size; i++) {
Radek Krejci7417a082017-02-16 11:07:59 +01001730 yang_print_revision(out, level, module, &module->rev[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001731 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001732
Radek Krejci8d81e002015-12-10 11:18:59 +01001733 /* body-stmts */
Radek Krejcie534c132016-11-23 13:32:31 +01001734 for (i = 0; i < module->extensions_size; i++) {
1735 ly_print(out, "\n");
1736 yang_print_extension(out, level, &module->extensions[i]);
1737 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001738 if (module->ext_size) {
1739 ly_print(out, "\n");
1740 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, module->ext, module->ext_size);
1741 }
Radek Krejcie534c132016-11-23 13:32:31 +01001742
Michal Vasko30f6e912015-07-07 12:24:27 +02001743 for (i = 0; i < module->features_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001744 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001745 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001746 }
1747
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001748 for (i = 0; i < module->ident_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001749 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001750 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001751 }
Radek Krejci6793db02015-05-22 17:49:54 +02001752
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001753 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001754 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001755 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001756 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001757
Radek Krejci5dd25122017-01-11 17:28:13 +01001758 LY_TREE_FOR(lys_main_module(module)->data, node) {
1759 if (node->module != module) {
1760 /* data from submodules */
1761 continue;
1762 }
1763 yang_print_snode(out, level, node, LYS_GROUPING);
Radek Krejci8d81e002015-12-10 11:18:59 +01001764 }
1765
Radek Krejcic4283442016-04-22 09:19:27 +02001766 LY_TREE_FOR(lys_main_module(module)->data, node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001767 if (node->module != module) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001768 /* data from submodules */
Radek Krejcic071c542016-01-27 14:57:51 +01001769 continue;
1770 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001771 yang_print_snode(out, level, node, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1772 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001773 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001774
Michal Vasko6f25f212015-07-07 15:42:07 +02001775 for (i = 0; i < module->augment_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001776 ly_print(out, "\n");
Radek Krejci43e3c312017-01-11 11:34:44 +01001777 yang_print_augment(out, level, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001778 }
1779
Radek Krejci5dd25122017-01-11 17:28:13 +01001780 LY_TREE_FOR(lys_main_module(module)->data, node) {
1781 if (node->module != module) {
1782 /* data from submodules */
1783 continue;
1784 }
1785 yang_print_snode(out, level, node, LYS_RPC | LYS_ACTION);
1786 }
1787
1788 LY_TREE_FOR(lys_main_module(module)->data, node) {
1789 if (node->module != module) {
1790 /* data from submodules */
1791 continue;
1792 }
1793 yang_print_snode(out, level, node, LYS_NOTIF);
1794 }
1795
1796 for (i = 0; i < module->deviation_size; ++i) {
1797 ly_print(out, "\n");
1798 yang_print_deviation(out, level, module, &module->deviation[i]);
1799 }
1800
Radek Krejci37f9ba32017-02-10 16:50:35 +01001801 level--;
1802 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko95068c42016-03-24 14:58:11 +01001803 ly_print_flush(out);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001804
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001805 return EXIT_SUCCESS;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001806}
1807
Radek Krejci37f9ba32017-02-10 16:50:35 +01001808int
1809yang_print_model(struct lyout *out, const struct lys_module *module)
1810{
1811 return yang_print_model_(out, 0, module);
1812}
1813
Radek Krejci8d6b7422017-02-03 14:42:13 +01001814static void
Radek Krejcic1885952017-02-07 09:37:51 +01001815yang_print_extcomplex_bool(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001816 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001817 const char *true_val, const char *false_val, int *content)
1818{
1819 struct lyext_substmt *info;
1820 uint8_t *val;
1821
1822 val = lys_ext_complex_get_substmt(stmt, ext, &info);
1823 if (!val || !(*val)) {
1824 return;
1825 }
1826
1827 yang_print_open(out, content);
1828 if (*val == 1) {
Radek Krejcidb35f172017-02-27 11:03:01 +01001829 yang_print_substmt(out, level, (LYEXT_SUBSTMT)stmt, 0, true_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001830 } else if (*val == 2) {
Radek Krejcidb35f172017-02-27 11:03:01 +01001831 yang_print_substmt(out, level, (LYEXT_SUBSTMT)stmt, 0, false_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001832 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001833 LOGINT(module->ctx);
Radek Krejcic1885952017-02-07 09:37:51 +01001834 }
1835}
1836
1837static void
Radek Krejci8d6b7422017-02-03 14:42:13 +01001838yang_print_extcomplex_str(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001839 struct lys_ext_instance_complex *ext, LY_STMT stmt, int *content)
Radek Krejci8d6b7422017-02-03 14:42:13 +01001840{
1841 struct lyext_substmt *info;
1842 const char **str;
1843 int c;
1844
1845 str = lys_ext_complex_get_substmt(stmt, ext, &info);
1846 if (!str || !(*str)) {
1847 return;
1848 }
1849 if (info->cardinality >= LY_STMT_CARD_SOME) {
1850 /* we have array */
1851 for (str = (const char **)(*str), c = 0; *str; str++, c++) {
1852 yang_print_open(out, content);
Radek Krejcidb35f172017-02-27 11:03:01 +01001853 yang_print_substmt(out, level, (LYEXT_SUBSTMT)stmt, c, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001854 }
1855 } else {
1856 yang_print_open(out, content);
Radek Krejcidb35f172017-02-27 11:03:01 +01001857 yang_print_substmt(out, level, (LYEXT_SUBSTMT)stmt, 0, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001858 }
1859}
1860
Radek Krejcic1885952017-02-07 09:37:51 +01001861/* val1 is supposed to be the default value */
1862static void
1863yang_print_extcomplex_flags(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001864 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001865 const char *val1_str, const char *val2_str, uint16_t val1, uint16_t val2,
1866 int *content)
1867{
1868 const char *str;
1869 uint16_t *flags;
1870
1871 flags = lys_ext_complex_get_substmt(stmt, ext, NULL);
1872 if (!flags) {
1873 return;
1874 }
1875
1876 if (val1 & *flags) {
1877 str = val1_str;
1878 } else if (val2 & *flags) {
1879 str = val2_str;
Radek Krejcidb35f172017-02-27 11:03:01 +01001880 } else if (lys_ext_iter(ext->ext, ext->ext_size, 0, (LYEXT_SUBSTMT)stmt) != -1) {
Radek Krejcic1885952017-02-07 09:37:51 +01001881 /* flag not set, but since there are some extension, we are going to print the default value */
1882 str = val1_str;
1883 } else {
1884 return;
1885 }
1886
1887 yang_print_open(out, content);
Radek Krejcidb35f172017-02-27 11:03:01 +01001888 yang_print_substmt(out, level, (LYEXT_SUBSTMT)stmt, 0, str, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001889}
1890
Radek Krejci8d6b7422017-02-03 14:42:13 +01001891static void
1892yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
1893 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
1894 struct lys_ext_instance **ext, unsigned int count)
1895{
1896 unsigned int u, x;
1897 struct lys_module *mod;
1898 const char *prefix = NULL, *str;
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01001899 int content, content2, i, j, c;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001900 struct lyext_substmt *info;
1901 uint16_t *flags;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001902 void **pp, *p;
Radek Krejcif95b6292017-02-13 15:57:37 +01001903 struct lys_node *siter;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001904
Radek Krejcif95b6292017-02-13 15:57:37 +01001905#define YANG_PRINT_EXTCOMPLEX_SNODE(STMT) \
1906 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
1907 if (!pp || !(*pp)) { break; } \
1908 LY_TREE_FOR((struct lys_node*)(*pp), siter) { \
1909 if (lys_snode2stmt(siter->nodetype) == STMT) { \
1910 yang_print_open(out, &content); \
1911 yang_print_snode(out, level, siter, LYS_ANY); \
1912 } \
1913 }
Radek Krejci8d6b7422017-02-03 14:42:13 +01001914#define YANG_PRINT_EXTCOMPLEX_STRUCT(STMT, TYPE, FUNC) \
Radek Krejcifebdad72017-02-06 11:35:51 +01001915 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001916 if (!pp || !(*pp)) { break; } \
Radek Krejcifebdad72017-02-06 11:35:51 +01001917 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001918 for (pp = *pp; *pp; pp++) { \
1919 yang_print_open(out, &content); \
Radek Krejci37f9ba32017-02-10 16:50:35 +01001920 FUNC(out, level, (TYPE *)(*pp)); \
1921 } \
1922 } else { /* single item */ \
1923 yang_print_open(out, &content); \
1924 FUNC(out, level, (TYPE *)(*pp)); \
1925 }
Radek Krejciaa9c5202017-02-15 16:10:14 +01001926#define YANG_PRINT_EXTCOMPLEX_STRUCT_M(STMT, TYPE, FUNC, ARGS...) \
Radek Krejci37f9ba32017-02-10 16:50:35 +01001927 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
1928 if (!pp || !(*pp)) { break; } \
1929 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
1930 for (pp = *pp; *pp; pp++) { \
1931 yang_print_open(out, &content); \
Radek Krejciaa9c5202017-02-15 16:10:14 +01001932 FUNC(out, level, module, (TYPE *)(*pp), ##ARGS); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001933 } \
1934 } else { /* single item */ \
1935 yang_print_open(out, &content); \
Radek Krejciaa9c5202017-02-15 16:10:14 +01001936 FUNC(out, level, module, (TYPE *)(*pp), ##ARGS); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001937 }
PavolVican2ed9f4e2017-02-16 00:08:45 +01001938#define YANG_PRINT_EXTCOMPLEX_INT(STMT, TYPE, SIGN) \
Radek Krejci5496fae2017-02-10 13:26:48 +01001939 p = &((struct lys_ext_instance_complex*)ext[u])->content[info[i].offset]; \
Radek Krejci716cd7a2017-02-15 12:23:41 +01001940 if (!p || !*(TYPE**)p) { break; } \
Radek Krejci73250282017-02-17 10:48:00 +01001941 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* we have array */ \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001942 for (c = 0; (*(TYPE***)p)[c]; c++) { \
Radek Krejci5496fae2017-02-10 13:26:48 +01001943 yang_print_open(out, &content); \
PavolVican2ed9f4e2017-02-16 00:08:45 +01001944 yang_print_##SIGN(out, level, STMT, c, module, \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001945 ext[u]->ext, ext[u]->ext_size, *(*(TYPE***)p)[c]); \
Radek Krejci5496fae2017-02-10 13:26:48 +01001946 } \
Radek Krejci716cd7a2017-02-15 12:23:41 +01001947 } else { \
Radek Krejci5496fae2017-02-10 13:26:48 +01001948 yang_print_open(out, &content); \
PavolVican2ed9f4e2017-02-16 00:08:45 +01001949 yang_print_##SIGN(out, level, STMT, 0, module, \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001950 ext[u]->ext, ext[u]->ext_size, (**(TYPE**)p)); \
Radek Krejci5496fae2017-02-10 13:26:48 +01001951 }
Radek Krejci8d6b7422017-02-03 14:42:13 +01001952
1953 for (u = 0; u < count; u++) {
1954 if (ext[u]->flags & LYEXT_OPT_INHERIT) {
1955 /* ignore the inherited extensions which were not explicitely instantiated in the module */
1956 continue;
Radek Krejcifebdad72017-02-06 11:35:51 +01001957 } else if (ext[u]->insubstmt != substmt || ext[u]->insubstmt_index != substmt_index) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001958 /* do not print the other substatement than the required */
1959 continue;
Radek Krejcia68ddeb2017-02-24 12:49:44 +01001960 } else if (ext[u]->def->module == module->ctx->models.list[0] &&
1961 (!strcmp(ext[u]->arg_value, "operation") ||
1962 !strcmp(ext[u]->arg_value, "select") ||
1963 !strcmp(ext[u]->arg_value, "type"))) {
1964 /* hack for NETCONF's edit-config's operation and filter's attributes
1965 * - the annotation definition is only internal, do not print it */
1966 continue;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001967 }
1968
1969 mod = lys_main_module(ext[u]->def->module);
1970 if (mod == lys_main_module(module)) {
1971 prefix = module->prefix;
1972 } else {
1973 for (x = 0; x < module->imp_size; x++) {
1974 if (mod == module->imp[x].module) {
1975 prefix = module->imp[x].prefix;
1976 break;
1977 }
1978 }
1979 }
1980
1981 content = 0;
1982 ly_print(out, "%*s%s:%s", LEVEL, INDENT, prefix, ext[u]->def->name);
1983 /* extension - generic part */
1984 if (ext[u]->arg_value) {
1985 ly_print(out, " \"%s\"", ext[u]->arg_value);
1986 }
1987
1988 /* extensions in extension instance */
1989 if (ext[u]->ext_size) {
1990 yang_print_open(out, &content);
1991 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1992 ext[u]->ext, ext[u]->ext_size);
1993 }
1994
1995 /* extension - type-specific part */
Radek Krejci8de8f612017-02-16 15:03:32 +01001996 switch(ext[u]->ext_type) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001997 case LYEXT_FLAG:
1998 /* flag extension - nothing special */
1999 break;
2000 case LYEXT_COMPLEX:
Radek Krejcifebdad72017-02-06 11:35:51 +01002001 info = ((struct lys_ext_instance_complex*)ext[u])->substmt; /* shortcut */
2002 if (!info) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01002003 /* no content */
2004 break;
2005 }
2006 level++;
Radek Krejcifebdad72017-02-06 11:35:51 +01002007 for (i = 0; info[i].stmt; i++) {
2008 switch(info[i].stmt) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01002009 case LY_STMT_DESCRIPTION:
Radek Krejci8d6b7422017-02-03 14:42:13 +01002010 case LY_STMT_REFERENCE:
Radek Krejci8d6b7422017-02-03 14:42:13 +01002011 case LY_STMT_UNITS:
Radek Krejcibe336392017-02-07 10:54:24 +01002012 case LY_STMT_DEFAULT:
2013 case LY_STMT_ERRTAG:
2014 case LY_STMT_ERRMSG:
2015 case LY_STMT_PREFIX:
2016 case LY_STMT_NAMESPACE:
2017 case LY_STMT_PRESENCE:
2018 case LY_STMT_REVISIONDATE:
2019 case LY_STMT_KEY:
2020 case LY_STMT_BASE:
Radek Krejcibe336392017-02-07 10:54:24 +01002021 case LY_STMT_CONTACT:
2022 case LY_STMT_ORGANIZATION:
2023 case LY_STMT_PATH:
Radek Krejci8d6b7422017-02-03 14:42:13 +01002024 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002025 info[i].stmt, &content);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002026 break;
PavolVican99c70722017-02-18 17:25:52 +01002027 case LY_STMT_ARGUMENT:
2028 pp = lys_ext_complex_get_substmt(LY_STMT_ARGUMENT, (struct lys_ext_instance_complex*)ext[u], NULL);
2029 if (!pp || !(*pp)) {
2030 break;
2031 }
2032 yang_print_open(out, &content);
2033 if (info->cardinality >= LY_STMT_CARD_SOME) {
2034 /* we have array */
2035 for (c = 0; ((const char***)pp)[0][c]; c++) {
2036 content2 = 0;
2037 ly_print(out, "%*sargument %s", LEVEL, INDENT, ((const char ***)pp)[0][c]);
2038 j = -1;
2039 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_ARGUMENT)) != -1) {
PavolVicanbf388512017-03-01 15:16:16 +01002040 if (ext[u]->ext[j]->insubstmt_index != c) {
2041 continue;
2042 }
PavolVican99c70722017-02-18 17:25:52 +01002043 yang_print_open(out, &content2);
2044 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_ARGUMENT, c,
2045 &ext[u]->ext[j], 1);
2046 }
PavolVicanbf388512017-03-01 15:16:16 +01002047
2048 if (((uint8_t *)pp[1])[c] == 1) {
PavolVican99c70722017-02-18 17:25:52 +01002049 yang_print_open(out, &content2);
2050 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, c,
2051 (((uint8_t *)pp[1])[c] == 1) ? "true" : "false", module, ext[u]->ext, ext[u]->ext_size);
PavolVicanbf388512017-03-01 15:16:16 +01002052 } else {
2053 j = -1;
2054 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_YINELEM)) != -1) {
2055 if (ext[u]->ext[j]->insubstmt_index == c) {
2056 yang_print_open(out, &content2);
2057 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, c, (((uint8_t *)pp[1])[c] == 1) ? "true" : "false",
2058 module, ext[u]->ext + j, ext[u]->ext_size - j);
2059 break;
2060 }
2061 }
PavolVican99c70722017-02-18 17:25:52 +01002062 }
PavolVican50809742017-02-18 21:22:54 +01002063 yang_print_close(out, level, content2);
PavolVican99c70722017-02-18 17:25:52 +01002064 }
2065 } else {
2066 content2 = 0;
2067 ly_print(out, "%*sargument %s", LEVEL, INDENT, (const char *)pp[0]);
2068 j = -1;
2069 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_ARGUMENT)) != -1) {
2070 yang_print_open(out, &content2);
2071 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_ARGUMENT, 0,
2072 &ext[u]->ext[j], 1);
2073 }
2074 if (*(uint8_t*)(pp + 1) == 1 || lys_ext_iter(ext[u]->ext, ext[u]->ext_size, 0, LYEXT_SUBSTMT_YINELEM) != -1) {
2075 yang_print_open(out, &content2);
2076 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, 0,
2077 (*(uint8_t*)(pp + 1) == 1) ? "true" : "false", module, ext[u]->ext, ext[u]->ext_size);
2078 }
PavolVican50809742017-02-18 21:22:54 +01002079 yang_print_close(out, level, content2);
PavolVican99c70722017-02-18 17:25:52 +01002080 }
2081 break;
Radek Krejci897d6072017-02-09 16:00:01 +01002082 case LY_STMT_BELONGSTO:
2083 pp = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, (struct lys_ext_instance_complex*)ext[u], NULL);
2084 if (!pp || !(*pp)) {
2085 break;
2086 }
2087 if (info->cardinality >= LY_STMT_CARD_SOME) {
2088 /* we have array */
2089 for (c = 0; ((const char***)pp)[0][c]; c++) {
2090 yang_print_open(out, &content);
2091 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((const char ***)pp)[0][c]);
2092 j = -1;
2093 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2094 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, c,
2095 &ext[u]->ext[j], 1);
2096 }
2097 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, c, ((const char ***)pp)[1][c],
2098 module, ext[u]->ext, ext[u]->ext_size);
2099 ly_print(out, "%*s}\n", LEVEL, INDENT);
2100 }
2101 } else {
2102 yang_print_open(out, &content);
2103 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, (const char *)pp[0]);
2104 j = -1;
2105 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2106 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0,
2107 &ext[u]->ext[j], 1);
2108 }
2109 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, (const char *)pp[1],
2110 module, ext[u]->ext, ext[u]->ext_size);
2111 ly_print(out, "%*s}\n", LEVEL, INDENT);
2112 }
2113 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002114 case LY_STMT_TYPE:
Radek Krejci37f9ba32017-02-10 16:50:35 +01002115 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_TYPE, struct lys_type, yang_print_type);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002116 break;
Radek Krejci63fc0962017-02-15 13:20:18 +01002117 case LY_STMT_TYPEDEF:
2118 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_TYPEDEF, struct lys_tpdf, yang_print_typedef);
2119 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002120 case LY_STMT_IFFEATURE:
Radek Krejci37f9ba32017-02-10 16:50:35 +01002121 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_IFFEATURE, struct lys_iffeature, yang_print_iffeature);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002122 break;
2123 case LY_STMT_STATUS:
Radek Krejcifebdad72017-02-06 11:35:51 +01002124 flags = lys_ext_complex_get_substmt(LY_STMT_STATUS, (struct lys_ext_instance_complex *)ext[u], NULL);
Radek Krejci2fd2a1f2017-02-13 11:06:04 +01002125 if (!flags || !(*flags)) {
2126 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002127 }
2128
2129 if (*flags & LYS_STATUS_CURR) {
2130 yang_print_open(out, &content);
2131 str = "current";
2132 } else if (*flags & LYS_STATUS_DEPRC) {
2133 yang_print_open(out, &content);
2134 str = "deprecated";
2135 } else if (*flags & LYS_STATUS_OBSLT) {
2136 yang_print_open(out, &content);
2137 str = "obsolete";
PavolVican366440b2017-02-20 11:14:24 +01002138 } else {
2139 /* no status flag */
2140 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002141 }
2142 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, str, module, ext[u]->ext, ext[u]->ext_size);
Radek Krejcic3e36542017-02-08 16:19:23 +01002143 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002144 case LY_STMT_CONFIG:
2145 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002146 LY_STMT_CONFIG, "true", "false",
Radek Krejcic1885952017-02-07 09:37:51 +01002147 LYS_CONFIG_W | LYS_CONFIG_SET, LYS_CONFIG_R | LYS_CONFIG_SET, &content);
2148 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002149 case LY_STMT_MANDATORY:
2150 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002151 LY_STMT_MANDATORY, "false", "true", LYS_MAND_FALSE, LYS_MAND_TRUE,
2152 &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002153 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002154 case LY_STMT_ORDEREDBY:
2155 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002156 LY_STMT_ORDEREDBY, "system", "user", 0, LYS_USERORDERED, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002157 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002158 case LY_STMT_REQINSTANCE:
2159 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002160 info[i].stmt, "true", "false", &content);
Radek Krejcic1885952017-02-07 09:37:51 +01002161 break;
2162 case LY_STMT_MODIFIER:
2163 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002164 LY_STMT_MODIFIER, "invert-match", NULL, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002165 break;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002166 case LY_STMT_DIGITS:
Radek Krejcif8d05c22017-02-10 15:33:35 +01002167 p = &((struct lys_ext_instance_complex*)ext[u])->content[info[i].offset];
2168 if (!p) {
2169 break;
2170 }
Radek Krejci716cd7a2017-02-15 12:23:41 +01002171 if (info->cardinality >= LY_STMT_CARD_SOME && *(uint8_t**)p) { /* we have array */
Radek Krejcif8d05c22017-02-10 15:33:35 +01002172 for (c = 0; (*(uint8_t**)p)[c]; c++) {
2173 yang_print_open(out, &content);
2174 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, c, module,
2175 ext[u]->ext, ext[u]->ext_size, (*(uint8_t**)p)[c]);
2176 }
2177 } else if ((*(uint8_t*)p)) {
2178 yang_print_open(out, &content);
2179 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, 0, module,
2180 ext[u]->ext, ext[u]->ext_size, (*(uint8_t*)p));
2181 }
Radek Krejci5496fae2017-02-10 13:26:48 +01002182 break;
2183 case LY_STMT_MAX:
PavolVican2ed9f4e2017-02-16 00:08:45 +01002184 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MAX, uint32_t, unsigned);
Radek Krejci5496fae2017-02-10 13:26:48 +01002185 break;
2186 case LY_STMT_MIN:
PavolVican2ed9f4e2017-02-16 00:08:45 +01002187 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MIN, uint32_t, unsigned);
Radek Krejci5496fae2017-02-10 13:26:48 +01002188 break;
2189 case LY_STMT_POSITION:
PavolVican2ed9f4e2017-02-16 00:08:45 +01002190 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_POSITION, uint32_t, unsigned);
2191 break;
2192 case LY_STMT_VALUE:
2193 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_VALUE, int32_t, signed);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002194 break;
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01002195 case LY_STMT_UNIQUE:
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01002196 pp = lys_ext_complex_get_substmt(LY_STMT_UNIQUE, (struct lys_ext_instance_complex *)ext[u], NULL);
2197 if (!pp || !(*pp)) {
2198 break;
2199 }
2200 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */
2201 for (pp = *pp, c = 0; *pp; pp++, c++) {
2202 yang_print_open(out, &content);
Michal Vasko1a3f80b2018-03-23 11:35:53 +01002203 yang_print_unique(out, level, module, (struct lys_unique*)(*pp));
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01002204 /* unique's extensions */
2205 j = -1; content2 = 0;
2206 do {
2207 j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE);
2208 } while (j != -1 && ext[u]->ext[j]->insubstmt_index != c);
2209 if (j != -1) {
PavolVicane13cdb22017-02-20 11:03:47 +01002210 yang_print_open(out, &content2);
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01002211 do {
2212 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, c,
2213 &ext[u]->ext[j], 1);
2214 do {
2215 j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE);
2216 } while (j != -1 && ext[u]->ext[j]->insubstmt_index != c);
2217 } while (j != -1);
2218 }
2219 yang_print_close(out, level, content2);
2220 }
2221 } else { /* single item */
2222 yang_print_open(out, &content);
Michal Vasko1a3f80b2018-03-23 11:35:53 +01002223 yang_print_unique(out, level, module, (struct lys_unique*)(*pp));
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01002224 /* unique's extensions */
2225 j = -1; content2 = 0;
2226 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
PavolVicane13cdb22017-02-20 11:03:47 +01002227 yang_print_open(out, &content2);
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01002228 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, 0,
2229 &ext[u]->ext[j], 1);
2230 }
2231 yang_print_close(out, level, content2);
2232 }
2233 break;
Radek Krejci37f9ba32017-02-10 16:50:35 +01002234 case LY_STMT_MODULE:
PavolVicand197fb12017-02-15 17:59:45 +01002235 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_MODULE, struct lys_module, yang_print_model_);
Radek Krejci37f9ba32017-02-10 16:50:35 +01002236 break;
Radek Krejcif95b6292017-02-13 15:57:37 +01002237 case LY_STMT_ACTION:
2238 case LY_STMT_ANYDATA:
2239 case LY_STMT_ANYXML:
2240 case LY_STMT_CASE:
2241 case LY_STMT_CHOICE:
2242 case LY_STMT_CONTAINER:
2243 case LY_STMT_GROUPING:
2244 case LY_STMT_INPUT:
2245 case LY_STMT_OUTPUT:
2246 case LY_STMT_LEAF:
2247 case LY_STMT_LEAFLIST:
2248 case LY_STMT_LIST:
2249 case LY_STMT_NOTIFICATION:
2250 case LY_STMT_USES:
2251 YANG_PRINT_EXTCOMPLEX_SNODE(info[i].stmt);
2252 break;
Radek Krejciaa9c5202017-02-15 16:10:14 +01002253 case LY_STMT_LENGTH:
2254 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_LENGTH, struct lys_restr, yang_print_restr,
2255 "length", ((struct lys_restr *)(*pp))->expr);
2256 break;
2257 case LY_STMT_MUST:
2258 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_MUST, struct lys_restr, yang_print_must);
2259 break;
2260 case LY_STMT_PATTERN:
2261 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_PATTERN, struct lys_restr, yang_print_restr,
2262 "pattern", &((struct lys_restr *)(*pp))->expr[1]);
2263 break;
2264 case LY_STMT_RANGE:
2265 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_RANGE, struct lys_restr, yang_print_restr,
2266 "range", ((struct lys_restr *)(*pp))->expr);
2267 break;
Radek Krejcic5cc5302017-02-16 10:07:46 +01002268 case LY_STMT_WHEN:
2269 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_WHEN, struct lys_when, yang_print_when);
2270 break;
Radek Krejci7417a082017-02-16 11:07:59 +01002271 case LY_STMT_REVISION:
2272 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_REVISION, struct lys_revision, yang_print_revision);
2273 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002274 default:
2275 /* TODO */
2276 break;
2277 }
2278 }
2279 level--;
2280 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002281 }
2282
2283 /* close extension */
2284 yang_print_close(out, level, content);
2285 }
2286#undef YANG_PRINT_EXTCOMPLEX_STRUCT
Radek Krejci37f9ba32017-02-10 16:50:35 +01002287#undef YANG_PRINT_EXTCOMPLEX_STRUCT_M
2288#undef YANG_PRINT_EXTCOMPLEX_INT
Radek Krejcida04f4a2015-05-21 12:54:09 +02002289}