blob: 4870ba60e81b31a36c46c1870f251f9531c89a67 [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 Krejci76b07902015-10-09 09:11:25 +020022#include "printer.h"
Michal Vasko2d162e12015-09-24 14:33:29 +020023#include "tree_schema.h"
Radek Krejcida04f4a2015-05-21 12:54:09 +020024
25#define INDENT ""
26#define LEVEL (level*2)
27
Michal Vasko1e62a092015-12-01 12:27:20 +010028static void yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask);
Radek Krejcida04f4a2015-05-21 12:54:09 +020029
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020030static void
Michal Vasko25cb6c62016-02-12 14:36:21 +010031yang_encode(struct lyout *out, const char *text, int len)
32{
33 int i, start_len;
34 const char *start;
35 char special = 0;
36
37 if (!len) {
38 return;
39 }
40
41 if (len < 0) {
42 len = strlen(text);
43 }
44
45 start = text;
46 start_len = 0;
47 for (i = 0; i < len; ++i) {
48 switch (text[i]) {
49 case '\n':
50 case '\t':
51 case '\"':
52 case '\\':
53 special = text[i];
54 break;
55 default:
56 ++start_len;
57 break;
58 }
59
60 if (special) {
61 ly_write(out, start, start_len);
62 switch (special) {
63 case '\n':
64 ly_write(out, "\\n", 2);
65 break;
66 case '\t':
67 ly_write(out, "\\t", 2);
68 break;
69 case '\"':
70 ly_write(out, "\\\"", 2);
71 break;
72 case '\\':
73 ly_write(out, "\\\\", 2);
74 break;
75 }
76
77 start += start_len + 1;
78 start_len = 0;
79
80 special = 0;
81 }
82 }
83
84 ly_write(out, start, start_len);
85}
86
87static void
Radek Krejci32cce7c2015-12-09 16:44:13 +010088yang_print_open(struct lyout *out, int *flag)
89{
90 if (flag && !*flag) {
91 *flag = 1;
92 ly_print(out, " {\n");
93 }
94}
95
96static void
97yang_print_close(struct lyout *out, int level, int flag)
98{
99 if (flag) {
100 ly_print(out, "%*s}\n", LEVEL, INDENT);
101 } else {
102 ly_print(out, ";\n");
103 }
104}
105
106static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100107yang_print_text(struct lyout *out, int level, const char *name, const char *text, int singleline, int closed)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200108{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200109 const char *s, *t;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200110
Radek Krejci8d81e002015-12-10 11:18:59 +0100111 if (singleline) {
112 ly_print(out, "%*s%s \"", LEVEL, INDENT, name);
113 } else {
114 ly_print(out, "%*s%s\n", LEVEL, INDENT, name);
115 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200116
Radek Krejci8d81e002015-12-10 11:18:59 +0100117 ly_print(out, "%*s\"", LEVEL, INDENT);
118 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200119 t = text;
120 while ((s = strchr(t, '\n'))) {
Michal Vasko25cb6c62016-02-12 14:36:21 +0100121 yang_encode(out, t, s - t);
122 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200123 t = s + 1;
Michal Vasko25cb6c62016-02-12 14:36:21 +0100124 ly_print(out, "%*s ", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200125 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200126
范昌虎1006995277de5fc2016-10-08 07:33:29 -0400127 yang_encode(out, t, strlen(t));
Radek Krejci43e3c312017-01-11 11:34:44 +0100128 if (closed) {
129 ly_print(out, "\";\n");
130 } else {
131 ly_print(out, "\"");
132 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200133 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200134
135}
136
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200137static void
Radek Krejcie534c132016-11-23 13:32:31 +0100138yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
Radek Krejci43e3c312017-01-11 11:34:44 +0100139 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
Radek Krejcie534c132016-11-23 13:32:31 +0100140 struct lys_ext_instance **ext, unsigned int count)
141{
142 unsigned int u, x;
143 struct lys_module *mod;
144 const char *prefix = NULL;
145 int flag;
146
147 for (u = 0; u < count; u++) {
Radek Krejci80056d52017-01-05 13:13:33 +0100148 if (ext[u]->flags & LYEXT_OPT_INHERIT) {
149 /* ignore the inherited extensions which were not explicitely instantiated in the module */
150 continue;
Radek Krejci43e3c312017-01-11 11:34:44 +0100151 } else if (ext[u]->substmt != substmt || ext[u]->substmt_index != substmt_index) {
152 /* do not print the other substatement than the required */
153 continue;
Radek Krejci80056d52017-01-05 13:13:33 +0100154 }
155
Radek Krejcie534c132016-11-23 13:32:31 +0100156 mod = lys_main_module(ext[u]->def->module);
Radek Krejci91602182017-01-13 12:41:33 +0100157 if (mod == lys_main_module(module)) {
Radek Krejcie534c132016-11-23 13:32:31 +0100158 prefix = module->prefix;
159 } else {
160 for (x = 0; x < module->imp_size; x++) {
161 if (mod == module->imp[x].module) {
162 prefix = module->imp[x].prefix;
163 break;
164 }
165 }
166 }
167
168 flag = 0;
169 ly_print(out, "%*s%s:%s", LEVEL, INDENT, prefix, ext[u]->def->name);
Radek Krejci0aa821a2016-12-08 11:21:35 +0100170 /* extension - generic part */
171 if (ext[u]->arg_value) {
172 ly_print(out, " \"%s\"", ext[u]->arg_value);
Radek Krejcie534c132016-11-23 13:32:31 +0100173 }
174
Radek Krejci0aa821a2016-12-08 11:21:35 +0100175 /* extension - type-specific part */
176 switch(lys_ext_instance_type(ext[u])) {
177 case LYEXT_FLAG:
178 /* flag extension - nothing special */
Radek Krejci17000ac2017-01-04 16:16:13 +0100179 break;
Radek Krejci0aa821a2016-12-08 11:21:35 +0100180 case LYEXT_ERR:
181 LOGINT;
182 break;
183 }
184
185 /* extensions in extension instance */
Radek Krejcie534c132016-11-23 13:32:31 +0100186 if (ext[u]->ext_size) {
187 yang_print_open(out, &flag);
Radek Krejcic65474c2017-01-16 10:38:35 +0100188 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
189 ext[u]->ext, ext[u]->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +0100190 }
191
192 /* close extension */
193 yang_print_close(out, level, flag);
194 }
195}
196
Radek Krejci43e3c312017-01-11 11:34:44 +0100197static void
198yang_print_substmt(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text,
199 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size)
200{
Radek Krejcicfce0292017-01-13 12:37:57 +0100201 int i = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100202
203 if (!text) {
204 /* nothing to print */
205 return;
206 }
207
Radek Krejcicfce0292017-01-13 12:37:57 +0100208 do {
209 i = ly_print_ext_iter(ext, ext_size, i + 1, substmt);
210 } while (i != -1 && ext[i]->substmt_index != substmt_index);
211
Radek Krejci43e3c312017-01-11 11:34:44 +0100212 if (ext_substmt_info[substmt].flags & SUBST_FLAG_ID) {
213 ly_print(out, "%*s%s %s%s", LEVEL, INDENT, ext_substmt_info[substmt].name, text, i == -1 ? ";\n" : "");
214 } else {
215 yang_print_text(out, level, ext_substmt_info[substmt].name, text,
216 (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) ? 0 : 1, i == -1 ? 1 : 0);
217 }
218
219 if (i != -1) {
220 ly_print(out, " {\n");
221 do {
222 yang_print_extension_instances(out, level + 1, module, substmt, substmt_index, &ext[i], 1);
223 do {
224 i = ly_print_ext_iter(ext, ext_size, i + 1, substmt);
225 } while (i != -1 && ext[i]->substmt_index != substmt_index);
226 } while (i != -1);
227 ly_print(out, "%*s}\n", LEVEL, INDENT);
228 }
229}
230
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200231static void
Radek Krejci9ff0a922016-07-14 13:08:05 +0200232yang_print_iffeature(struct lyout *out, int level, const struct lys_module *module, struct lys_iffeature *iffeature)
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200233{
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200234 ly_print(out, "%*sif-feature \"", LEVEL, INDENT);
Radek Krejci9ff0a922016-07-14 13:08:05 +0200235 ly_print_iffeature(out, module, iffeature);
Radek Krejci43e3c312017-01-11 11:34:44 +0100236
237 /* extensions */
238 if (iffeature->ext_size) {
239 ly_print(out, "\" {\n");
240 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0, iffeature->ext, iffeature->ext_size);
241 ly_print(out, "%*s}\n", LEVEL, INDENT);
242 } else {
243 ly_print(out, "\";\n");
244 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200245}
246
Radek Krejci5dd25122017-01-11 17:28:13 +0100247/*
248 * Covers:
249 * extension (instances), if-features, config, mandatory, status, description, reference
250 */
251#define SNODE_COMMON_EXT 0x01
252#define SNODE_COMMON_IFF 0x02
253#define SNODE_COMMON_CONFIG 0x04
254#define SNODE_COMMON_MAND 0x08
255#define SNODE_COMMON_STATUS 0x10
256#define SNODE_COMMON_DSC 0x20
257#define SNODE_COMMON_REF 0x40
258static void
259yang_print_snode_common(struct lyout *out, int level, const struct lys_node *node, const struct lys_module *module,
260 int *flag, int mask)
261{
262 int i;
263 const char *status = NULL;
264
265 /* extensions */
266 if ((mask & SNODE_COMMON_EXT) && node->ext_size) {
267 yang_print_open(out, flag);
268 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
269 }
270
271 /* if-features */
272 if (mask & SNODE_COMMON_IFF) {
273 for (i = 0; i < node->iffeature_size; ++i) {
274 yang_print_open(out, flag);
275 yang_print_iffeature(out, level, module, &node->iffeature[i]);
276 }
277 }
278
279 /* config */
280 if (mask & SNODE_COMMON_CONFIG) {
281 /* get info if there is an extension for the config statement */
282 i = ly_print_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_CONFIG);
283
284 if (lys_parent(node)) {
285 if ((node->flags & LYS_CONFIG_SET) || i != -1) {
286 /* print config when it differs from the parent or if it has an extension instance ... */
287 if (node->flags & LYS_CONFIG_W) {
288 yang_print_open(out, flag);
289 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
290 module, node->ext, node->ext_size);
291 } else if (node->flags & LYS_CONFIG_R) {
292 yang_print_open(out, flag);
293 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
294 module, node->ext, node->ext_size);
295 }
296 }
297 } else if (node->flags & LYS_CONFIG_R) {
298 /* ... or it's a top-level state node */
299 yang_print_open(out, flag);
300 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
301 module, node->ext, node->ext_size);
302 } else if (i != -1) {
303 /* the config has an extension, so we have to print it */
304 yang_print_open(out, flag);
305 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
306 module, node->ext, node->ext_size);
307 }
308 }
309
310 /* mandatory */
311 if ((mask & SNODE_COMMON_MAND) && (node->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
312 if (node->flags & LYS_MAND_TRUE) {
313 yang_print_open(out, flag);
314 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true",
315 module, node->ext, node->ext_size);
316 } else if (node->flags & LYS_MAND_FALSE) {
317 yang_print_open(out, flag);
318 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false",
319 module, node->ext, node->ext_size);
320 }
321 }
322
323 /* status */
324 if (mask & SNODE_COMMON_STATUS) {
325 if (node->flags & LYS_STATUS_CURR) {
326 yang_print_open(out, flag);
327 status = "current";
328 } else if (node->flags & LYS_STATUS_DEPRC) {
329 yang_print_open(out, flag);
330 status = "deprecated";
331 } else if (node->flags & LYS_STATUS_OBSLT) {
332 yang_print_open(out, flag);
333 status = "obsolete";
334 }
335 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, status, module, node->ext, node->ext_size);
336 }
337
338 /* description */
339 if ((mask & SNODE_COMMON_DSC) && node->dsc) {
340 yang_print_open(out, flag);
341 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, node->dsc,
342 module, node->ext, node->ext_size);
343 }
344
345 /* reference */
346 if ((mask & SNODE_COMMON_REF) && node->ref) {
347 yang_print_open(out, flag);
348 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, node->ref,
349 module, node->ext, node->ext_size);
350 }
351}
352
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200353static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100354yang_print_feature(struct lyout *out, int level, const struct lys_feature *feat)
Michal Vasko4773b762015-07-07 12:15:10 +0200355{
Radek Krejci5dd25122017-01-11 17:28:13 +0100356 int flag = 0;
Michal Vasko30f6e912015-07-07 12:24:27 +0200357
Radek Krejci32cce7c2015-12-09 16:44:13 +0100358 ly_print(out, "%*sfeature %s", LEVEL, INDENT, feat->name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100359 yang_print_snode_common(out, level + 1, (struct lys_node *)feat, feat->module, &flag, SNODE_COMMON_EXT |
360 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100361 yang_print_close(out, level, flag);
Michal Vasko4773b762015-07-07 12:15:10 +0200362}
363
364static void
Radek Krejcia1a6b762016-11-14 09:53:38 +0900365yang_print_extension(struct lyout *out, int level, const struct lys_ext *ext)
366{
Radek Krejcicfce0292017-01-13 12:37:57 +0100367 int flag = 0, flag2 = 0, i;
Radek Krejcia1a6b762016-11-14 09:53:38 +0900368
369 ly_print(out, "%*sextension %s", LEVEL, INDENT, ext->name);
370 level++;
371
Radek Krejci5dd25122017-01-11 17:28:13 +0100372 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
373 SNODE_COMMON_EXT);
374
Radek Krejcia1a6b762016-11-14 09:53:38 +0900375 if (ext->argument) {
376 yang_print_open(out, &flag);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900377
Radek Krejcicfce0292017-01-13 12:37:57 +0100378 ly_print(out, "%*sargument %s", LEVEL, INDENT, ext->argument);
379 i = -1;
380 while ((i = ly_print_ext_iter(ext->ext, ext->ext_size, i + 1, LYEXT_SUBSTMT_ARGUMENT)) != -1) {
381 yang_print_open(out, &flag2);
382 yang_print_extension_instances(out, level + 1, ext->module, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->ext[i], 1);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900383 }
Radek Krejci87f90572017-01-24 11:19:42 +0100384 if ((ext->flags & LYS_YINELEM) || ly_print_ext_iter(ext->ext, ext->ext_size, 0, LYEXT_SUBSTMT_YINELEM) != -1) {
Radek Krejcicfce0292017-01-13 12:37:57 +0100385 yang_print_open(out, &flag2);
Radek Krejci87f90572017-01-24 11:19:42 +0100386 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, 0,
387 (ext->flags & LYS_YINELEM) ? "true" : "false", ext->module, ext->ext, ext->ext_size);
Radek Krejcicfce0292017-01-13 12:37:57 +0100388 }
389 yang_print_close(out, level, flag2);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900390 }
391
Radek Krejci5dd25122017-01-11 17:28:13 +0100392 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
393 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
394
Radek Krejcia1a6b762016-11-14 09:53:38 +0900395 level--;
396 yang_print_close(out, level, flag);
397}
398
399static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100400yang_print_restr(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *restr, int *flag)
Radek Krejci41726f92015-06-19 13:11:05 +0200401{
Radek Krejci5dd25122017-01-11 17:28:13 +0100402 if (restr->ext_size) {
403 yang_print_open(out, flag);
404 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, restr->ext, restr->ext_size);
405 }
Radek Krejcidaa95c42017-01-16 10:25:29 +0100406 if (restr->expr[0] == 0x15) {
407 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
408 yang_print_open(out, flag);
409 yang_print_substmt(out, level, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match",
410 module, restr->ext, restr->ext_size);
411 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100412 if (restr->emsg != NULL) {
413 yang_print_open(out, flag);
414 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg,
415 module, restr->ext, restr->ext_size);
416 }
417 if (restr->eapptag != NULL) {
418 yang_print_open(out, flag);
419 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag,
420 module, restr->ext, restr->ext_size);
421 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200422 if (restr->dsc != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100423 yang_print_open(out, flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100424 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, restr->dsc,
425 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200426 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200427 if (restr->ref != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100428 yang_print_open(out, flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100429 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, restr->ref,
430 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200431 }
Radek Krejci41726f92015-06-19 13:11:05 +0200432}
433
434static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100435yang_print_when(struct lyout *out, int level, const struct lys_module *module, const struct lys_when *when)
Michal Vasko1f0428a2015-07-07 14:55:04 +0200436{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100437 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100438 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200439
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100440 str = transform_json2schema(module, when->cond);
441 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200442 ly_print(out, "(!error!)");
443 return;
444 }
445
Michal Vasko25cb6c62016-02-12 14:36:21 +0100446 ly_print(out, "%*swhen \"", LEVEL, INDENT);
447 yang_encode(out, str, -1);
448 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100449 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200450
Michal Vasko1f0428a2015-07-07 14:55:04 +0200451 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100452
Radek Krejci43e3c312017-01-11 11:34:44 +0100453 if (when->ext_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100454 /* 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 +0100455 yang_print_open(out, &flag);
456 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, when->ext, when->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200457 }
Radek Krejci11e88fd2017-01-16 15:34:37 +0100458 if (when->dsc != NULL) {
459 yang_print_open(out, &flag);
460 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, when->dsc,
461 module, when->ext, when->ext_size);
462 }
463 if (when->ref != NULL) {
464 yang_print_open(out, &flag);
465 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, when->ref,
466 module, when->ext, when->ext_size);
467 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100468
Michal Vasko1f0428a2015-07-07 14:55:04 +0200469 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100470 yang_print_close(out, level, flag);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200471}
472
473static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100474yang_print_type(struct lyout *out, int level, const struct lys_module *module, const struct lys_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200475{
Radek Krejci5dd25122017-01-11 17:28:13 +0100476 int i;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100477 int flag = 0, flag2;
Michal Vasko0fb82c62015-10-20 13:41:53 +0200478 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100479 char *s;
Radek Krejcic071c542016-01-27 14:57:51 +0100480 struct lys_module *mod;
Radek Krejci25d782a2015-05-22 15:03:23 +0200481
Michal Vasko0fb82c62015-10-20 13:41:53 +0200482 if (type->module_name) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100483 ly_print(out, "%*stype %s:%s", LEVEL, INDENT,
484 transform_module_name2import_prefix(module, type->module_name), type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200485 } else {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100486 ly_print(out, "%*stype %s", LEVEL, INDENT, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200487 }
488 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100489
490 /* extensions */
491 if (type->ext_size) {
492 yang_print_open(out, &flag);
493 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, type->ext, type->ext_size);
494 }
495
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200496 switch (type->base) {
497 case LY_TYPE_BINARY:
Michal Vasko4634cda2016-02-16 09:22:09 +0100498 if (type->info.binary.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100499 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100500 ly_print(out, "%*slength \"", LEVEL, INDENT);
501 yang_encode(out, type->info.binary.length->expr, -1);
502 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100503 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100504 yang_print_restr(out, level + 1, module, type->info.binary.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100505 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200506 }
507 break;
508 case LY_TYPE_BITS:
509 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100510 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100511 ly_print(out, "%*sbit %s", LEVEL, INDENT, type->info.bits.bit[i].name);
512 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200513 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100514 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
515 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100516 if (!(type->info.bits.bit[i].flags & LYS_AUTOASSIGNED)) {
517 yang_print_open(out, &flag2);
Radek Krejci43e3c312017-01-11 11:34:44 +0100518 asprintf(&s, "%u", type->info.bits.bit[i].pos);
519 yang_print_substmt(out, level, LYEXT_SUBSTMT_POSITION, 0, s,
520 module, type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size);
521 free(s);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100522 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100523 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
524 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200525 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100526 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200527 }
528 break;
529 case LY_TYPE_DEC64:
Radek Krejcib51d5932016-09-08 14:02:52 +0200530 if (!type->der->type.der) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100531 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100532 asprintf(&s, "%d", type->info.dec64.dig);
533 yang_print_substmt(out, level, LYEXT_SUBSTMT_DIGITS, 0, s, module, type->ext, type->ext_size);
534 free(s);
Michal Vasko4634cda2016-02-16 09:22:09 +0100535 }
Michal Vaskoea505ee2015-07-07 14:01:00 +0200536 if (type->info.dec64.range != NULL) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100537 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100538 ly_print(out, "%*srange \"", LEVEL, INDENT);
539 yang_encode(out, type->info.dec64.range->expr, -1);
540 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100541 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100542 yang_print_restr(out, level + 1, module, type->info.dec64.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100543 yang_print_close(out, level, flag2);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200544 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200545 break;
546 case LY_TYPE_ENUM:
547 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100548 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100549 ly_print(out, "%*senum \"%s\"", LEVEL, INDENT, type->info.enums.enm[i].name);
550 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200551 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100552 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
553 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100554 if (!(type->info.enums.enm[i].flags & LYS_AUTOASSIGNED)) {
555 yang_print_open(out, &flag2);
Radek Krejci43e3c312017-01-11 11:34:44 +0100556 asprintf(&s, "%d", type->info.enums.enm[i].value);
557 yang_print_substmt(out, level, LYEXT_SUBSTMT_VALUE, 0, s,
558 module, type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size);
559 free(s);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100560 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100561 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
562 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200563 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100564 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200565 }
566 break;
567 case LY_TYPE_IDENT:
Michal Vaskof2d43962016-09-02 11:10:16 +0200568 if (type->info.ident.count) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100569 yang_print_open(out, &flag);
Michal Vaskof2d43962016-09-02 11:10:16 +0200570 for (i = 0; i < type->info.ident.count; ++i) {
571 mod = lys_main_module(type->info.ident.ref[i]->module);
572 if (lys_main_module(module) == mod) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100573 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, type->info.ident.ref[i]->name,
574 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
Michal Vaskof2d43962016-09-02 11:10:16 +0200575 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100576 asprintf(&s, "%s:%s", transform_module_name2import_prefix(module, mod->name),
577 type->info.ident.ref[i]->name);
578 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, s,
579 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
580 free(s);
Michal Vaskof2d43962016-09-02 11:10:16 +0200581 }
Michal Vasko4634cda2016-02-16 09:22:09 +0100582 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200583 }
584 break;
585 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200586 if (type->info.inst.req == 1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100587 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100588 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "true", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200589 } else if (type->info.inst.req == -1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100590 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100591 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "false", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200592 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200593 break;
594 case LY_TYPE_INT8:
595 case LY_TYPE_INT16:
596 case LY_TYPE_INT32:
597 case LY_TYPE_INT64:
598 case LY_TYPE_UINT8:
599 case LY_TYPE_UINT16:
600 case LY_TYPE_UINT32:
601 case LY_TYPE_UINT64:
Michal Vasko4634cda2016-02-16 09:22:09 +0100602 if (type->info.num.range) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100603 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100604 ly_print(out, "%*srange \"", LEVEL, INDENT);
605 yang_encode(out, type->info.num.range->expr, -1);
606 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100607 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100608 yang_print_restr(out, level + 1, module, type->info.num.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100609 yang_print_close(out, level, flag2);
Radek Krejcif2860132015-06-20 12:37:20 +0200610 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200611 break;
612 case LY_TYPE_LEAFREF:
Radek Krejci0dbff6a2016-07-17 12:40:18 +0200613 if (ly_strequal(type->der->name, "leafref", 0)) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100614 yang_print_open(out, &flag);
615 str = transform_json2schema(module, type->info.lref.path);
Radek Krejci43e3c312017-01-11 11:34:44 +0100616 yang_print_substmt(out, level, LYEXT_SUBSTMT_PATH, 0, str, module, type->ext, type->ext_size);
Michal Vasko4634cda2016-02-16 09:22:09 +0100617 lydict_remove(module->ctx, str);
618 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100619 if (type->info.lref.req == 1) {
620 yang_print_open(out, &flag);
621 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "true", module, type->ext, type->ext_size);
622 } else if (type->info.lref.req == -1) {
623 yang_print_open(out, &flag);
624 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "false", module, type->ext, type->ext_size);
625 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200626 break;
627 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200628 if (type->info.str.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100629 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100630 ly_print(out, "%*slength \"", LEVEL, INDENT);
631 yang_encode(out, type->info.str.length->expr, -1);
632 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100633 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100634 yang_print_restr(out, level + 1, module, type->info.str.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100635 yang_print_close(out, level, flag2);
Radek Krejci061bd522015-06-19 13:45:16 +0200636 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200637 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100638 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100639 ly_print(out, "%*spattern \"", LEVEL, INDENT);
Radek Krejci0d23e7a2016-08-04 12:46:17 +0200640 yang_encode(out, &type->info.str.patterns[i].expr[1], -1);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100641 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100642 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100643 yang_print_restr(out, level + 1, module, &type->info.str.patterns[i], &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100644 yang_print_close(out, level, flag2);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200645 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200646 break;
647 case LY_TYPE_UNION:
648 for (i = 0; i < type->info.uni.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100649 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200650 yang_print_type(out, level, module, &type->info.uni.types[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200651 }
652 break;
653 default:
654 /* other types do not have substatements */
655 break;
656 }
Radek Krejcie534c132016-11-23 13:32:31 +0100657
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200658 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100659 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200660}
661
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200662static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100663yang_print_must(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200664{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100665 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100666 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200667
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100668 str = transform_json2schema(module, must->expr);
669 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200670 ly_print(out, "(!error!)");
671 return;
672 }
673
Michal Vasko25cb6c62016-02-12 14:36:21 +0100674 ly_print(out, "%*smust \"", LEVEL, INDENT);
675 yang_encode(out, str, -1);
676 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100677 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200678
Radek Krejci43e3c312017-01-11 11:34:44 +0100679 yang_print_restr(out, level + 1, module, must, &flag);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100680 yang_print_close(out, level, flag);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200681}
682
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200683static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100684yang_print_unique(struct lyout *out, int level, const struct lys_unique *uniq)
Michal Vasko1ef07972015-07-07 14:01:35 +0200685{
686 int i;
687
Radek Krejci76b07902015-10-09 09:11:25 +0200688 ly_print(out, "%*sunique \"", LEVEL, INDENT);
Radek Krejci581ce772015-11-10 17:22:40 +0100689 for (i = 0; i < uniq->expr_size; i++) {
690 ly_print(out, "%s%s", uniq->expr[i], i + 1 < uniq->expr_size ? " " : "");
Michal Vasko1ef07972015-07-07 14:01:35 +0200691 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100692 ly_print(out, "\"");
Michal Vasko1ef07972015-07-07 14:01:35 +0200693}
694
695static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100696yang_print_refine(struct lyout *out, int level, const struct lys_module *module, const struct lys_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200697{
Radek Krejci5dd25122017-01-11 17:28:13 +0100698 int i, flag = 0;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200699 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100700 char *s;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200701
Michal Vasko5d112852016-02-12 16:47:13 +0100702 str = transform_json2schema(module, refine->target_name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100703 ly_print(out, "%*srefine \"%s\"", LEVEL, INDENT, str);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200704 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200705 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200706
Radek Krejci5dd25122017-01-11 17:28:13 +0100707 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 +0200708 for (i = 0; i < refine->must_size; ++i) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100709 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200710 yang_print_must(out, level, module, &refine->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200711 }
Pavol Vican3e7c73a2016-08-17 10:24:11 +0200712 if (refine->target_type == LYS_CONTAINER) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100713 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100714 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, refine->mod.presence,
715 module, refine->ext, refine->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100716 }
717 for (i = 0; i < refine->dflt_size; ++i) {
718 yang_print_open(out, &flag);
719 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, refine->dflt[i], module, refine->ext, refine->ext_size);
720 }
721 if (refine->flags & LYS_CONFIG_W) {
722 yang_print_open(out, &flag);
723 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module, refine->ext, refine->ext_size);
724 } else if (refine->flags & LYS_CONFIG_R) {
725 yang_print_open(out, &flag);
726 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module, refine->ext, refine->ext_size);
727 }
728 if (refine->flags & LYS_MAND_TRUE) {
729 yang_print_open(out, &flag);
730 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module, refine->ext, refine->ext_size);
731 } else if (refine->flags & LYS_MAND_FALSE) {
732 yang_print_open(out, &flag);
733 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module, refine->ext, refine->ext_size);
734 }
735 if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200736 if (refine->flags & LYS_RFN_MINSET) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100737 asprintf(&s, "%u", refine->mod.list.min);
Radek Krejci5dd25122017-01-11 17:28:13 +0100738 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100739 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, s, module, refine->ext, refine->ext_size);
740 free(s);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200741 }
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200742 if (refine->flags & LYS_RFN_MAXSET) {
Radek Krejci0d7b2472016-02-12 11:11:03 +0100743 if (refine->mod.list.max) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100744 asprintf(&s, "%u", refine->mod.list.max);
Radek Krejci0d7b2472016-02-12 11:11:03 +0100745 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100746 s = NULL;
Radek Krejci0d7b2472016-02-12 11:11:03 +0100747 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100748 yang_print_open(out, &flag);
Radek Krejci803c2fd2017-01-23 15:54:46 +0100749 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, s ? s : "unbounded", module, refine->ext, refine->ext_size);
Radek Krejci43e3c312017-01-11 11:34:44 +0100750 free(s);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200751 }
752 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100753 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 +0200754
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200755 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +0100756 yang_print_close(out, level, flag);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200757}
758
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200759static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100760yang_print_deviation(struct lyout *out, int level, const struct lys_module *module,
761 const struct lys_deviation *deviation)
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200762{
Radek Krejci033983b2017-01-13 12:43:20 +0100763 int i, j, p;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200764 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100765 char *s;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200766
Michal Vasko5d112852016-02-12 16:47:13 +0100767 str = transform_json2schema(module, deviation->target_name);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200768 ly_print(out, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, str);
769 lydict_remove(module->ctx, str);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200770 level++;
771
Radek Krejci5dd25122017-01-11 17:28:13 +0100772 if (deviation->ext_size) {
773 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, deviation->ext, deviation->ext_size);
774 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100775 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, deviation->dsc,
776 module, deviation->ext, deviation->ext_size);
777 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, deviation->ref,
778 module, deviation->ext, deviation->ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200779
780 for (i = 0; i < deviation->deviate_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200781 ly_print(out, "%*sdeviate ", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200782 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100783 if (deviation->deviate[i].ext_size) {
784 ly_print(out, "not-supported {\n");
785 } else {
786 ly_print(out, "not-supported;\n");
787 continue;
788 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200789 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
Radek Krejci76b07902015-10-09 09:11:25 +0200790 ly_print(out, "add {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200791 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200792 ly_print(out, "replace {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200793 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200794 ly_print(out, "delete {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200795 }
796 level++;
797
Radek Krejci5dd25122017-01-11 17:28:13 +0100798 /* extensions */
799 if (deviation->deviate[i].ext_size) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100800 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
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 /* type */
805 if (deviation->deviate[i].type) {
806 yang_print_type(out, level, module, deviation->deviate[i].type);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200807 }
808
Radek Krejci5dd25122017-01-11 17:28:13 +0100809 /* units */
810 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, deviation->deviate[i].units, module,
811 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200812
Radek Krejci5dd25122017-01-11 17:28:13 +0100813 /* must */
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200814 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
Michal Vaskof9893382015-10-09 14:03:04 +0200815 yang_print_must(out, level, module, &deviation->deviate[i].must[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200816 }
817
Radek Krejci5dd25122017-01-11 17:28:13 +0100818 /* unique */
819
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200820 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
Radek Krejci76b07902015-10-09 09:11:25 +0200821 yang_print_unique(out, level, &deviation->deviate[i].unique[j]);
Radek Krejci43e3c312017-01-11 11:34:44 +0100822 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +0100823 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100824 do {
Radek Krejcicfce0292017-01-13 12:37:57 +0100825 p = ly_print_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
826 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejci43e3c312017-01-11 11:34:44 +0100827 } while (p != -1 && deviation->deviate[i].ext[p]->substmt_index != j);
828 if (p != -1) {
829 ly_print(out, " {\n");
830 do {
831 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, j,
832 &deviation->deviate[i].ext[p], 1);
833 do {
834 p = ly_print_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
835 p + 1, LYEXT_SUBSTMT_UNIQUE);
836 } while (p != -1 && deviation->deviate[i].ext[p]->substmt_index != j);
837 } while (p != -1);
838 ly_print(out, "%*s}\n", LEVEL, INDENT);
839 } else {
840 ly_print(out, ";\n");
841 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200842 }
843
Radek Krejci5dd25122017-01-11 17:28:13 +0100844 /* default */
Radek Krejci033983b2017-01-13 12:43:20 +0100845 for (j = 0; j < deviation->deviate[i].dflt_size; ++j) {
846 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, j, deviation->deviate[i].dflt[j], module,
Radek Krejci5dd25122017-01-11 17:28:13 +0100847 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200848 }
849
Radek Krejci5dd25122017-01-11 17:28:13 +0100850 /* config */
851 if (deviation->deviate[i].flags & LYS_CONFIG_W) {
852 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module,
853 deviation->deviate->ext, deviation->deviate[i].ext_size);
854 } else if (deviation->deviate[i].flags & LYS_CONFIG_R) {
855 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module,
856 deviation->deviate->ext, deviation->deviate[i].ext_size);
857 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100858
Radek Krejci5dd25122017-01-11 17:28:13 +0100859 /* mandatory */
860 if (deviation->deviate[i].flags & LYS_MAND_TRUE) {
861 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module,
862 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
863 } else if (deviation->deviate[i].flags & LYS_MAND_FALSE) {
864 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module,
865 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
866 }
867
868 /* min-elements */
869 if (deviation->deviate[i].min_set) {
870 asprintf(&s, "%u", deviation->deviate[i].min);
871 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, s, module,
872 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
873 free(s);
874 }
875
876 /* max-elements */
877 if (deviation->deviate[i].max_set) {
878 if (deviation->deviate[i].max) {
879 asprintf(&s, "%u", deviation->deviate[i].max);
880 } else {
881 s = NULL;
882 }
883 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, s ? s : "unbounded", module,
884 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
885 free(s);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200886 }
887
888 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200889 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200890 }
891
892 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200893 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200894}
895
896static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100897yang_print_augment(struct lyout *out, int level, const struct lys_node_augment *augment)
Michal Vasko6f25f212015-07-07 15:42:07 +0200898{
Radek Krejci76512572015-08-04 09:47:08 +0200899 struct lys_node *sub;
Michal Vasko488c19e2015-10-20 15:21:00 +0200900 const char *str;
Michal Vasko6f25f212015-07-07 15:42:07 +0200901
Radek Krejci43e3c312017-01-11 11:34:44 +0100902 str = transform_json2schema(augment->module, augment->target_name);
Michal Vasko488c19e2015-10-20 15:21:00 +0200903 ly_print(out, "%*saugment \"%s\" {\n", LEVEL, INDENT, str);
Radek Krejci43e3c312017-01-11 11:34:44 +0100904 lydict_remove(augment->module->ctx, str);
Michal Vasko6f25f212015-07-07 15:42:07 +0200905 level++;
906
Radek Krejci5dd25122017-01-11 17:28:13 +0100907 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL, SNODE_COMMON_EXT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200908 if (augment->when) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100909 yang_print_when(out, level, augment->module, augment->when);
Michal Vasko6f25f212015-07-07 15:42:07 +0200910 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100911 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL,
912 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200913
914 LY_TREE_FOR(augment->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100915 /* only our augment */
916 if (sub->parent != (struct lys_node *)augment) {
917 continue;
918 }
Radek Krejci76b07902015-10-09 09:11:25 +0200919 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200920 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +0100921 LYS_USES | LYS_ANYDATA | LYS_CASE | LYS_ACTION | LYS_NOTIF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200922 }
923
924 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200925 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200926}
927
928static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100929yang_print_typedef(struct lyout *out, int level, const struct lys_module *module, const struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200930{
Radek Krejci033983b2017-01-13 12:43:20 +0100931 const char *dflt;
932
Radek Krejci76b07902015-10-09 09:11:25 +0200933 ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200934 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200935
Radek Krejci5dd25122017-01-11 17:28:13 +0100936 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL, SNODE_COMMON_EXT);
Radek Krejci76b07902015-10-09 09:11:25 +0200937 yang_print_type(out, level, module, &tpdf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200938 if (tpdf->units != NULL) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100939 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, module, tpdf->ext, tpdf->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200940 }
941 if (tpdf->dflt != NULL) {
Radek Krejcibd117f02016-11-04 16:28:08 +0100942 if (tpdf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +0100943 assert(strchr(tpdf->dflt, ':'));
944 if (!strncmp(tpdf->dflt, module->name, strchr(tpdf->dflt, ':') - tpdf->dflt)) {
945 /* local module */
946 dflt = lydict_insert(module->ctx, strchr(tpdf->dflt, ':') + 1, 0);
947 } else {
948 dflt = transform_json2schema(module, tpdf->dflt);
949 }
Radek Krejcibd117f02016-11-04 16:28:08 +0100950 } else {
951 dflt = tpdf->dflt;
952 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100953 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt, module, tpdf->ext, tpdf->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +0100954 if (tpdf->flags & LYS_DFLTJSON) {
955 lydict_remove(module->ctx, dflt);
956 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200957 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100958 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL,
959 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200960
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200961 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200962 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200963}
964
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200965static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100966yang_print_identity(struct lyout *out, int level, const struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200967{
Radek Krejci018f1f52016-08-03 16:01:20 +0200968 int flag = 0, i;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100969 struct lys_module *mod;
Radek Krejci43e3c312017-01-11 11:34:44 +0100970 char *str;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100971
972 ly_print(out, "%*sidentity %s", LEVEL, INDENT, ident->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200973 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200974
Radek Krejci5dd25122017-01-11 17:28:13 +0100975 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
976 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
977
Radek Krejci018f1f52016-08-03 16:01:20 +0200978 for (i = 0; i < ident->base_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100979 yang_print_open(out, &flag);
Radek Krejci018f1f52016-08-03 16:01:20 +0200980 mod = lys_main_module(ident->base[i]->module);
Radek Krejci43e3c312017-01-11 11:34:44 +0100981 if (lys_main_module(ident->module) == mod) {
Radek Krejcib5e58d32017-01-23 13:45:59 +0100982 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, ident->base[i]->name,
Radek Krejci43e3c312017-01-11 11:34:44 +0100983 ident->module, ident->ext, ident->ext_size);
984 } else {
985 asprintf(&str, "%s:%s", transform_module_name2import_prefix(ident->module, mod->name), ident->base[i]->name);
Radek Krejcib5e58d32017-01-23 13:45:59 +0100986 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, str,
Radek Krejci43e3c312017-01-11 11:34:44 +0100987 ident->module, ident->ext, ident->ext_size);
988 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200989 }
990 }
Radek Krejci6793db02015-05-22 17:49:54 +0200991
Radek Krejci5dd25122017-01-11 17:28:13 +0100992 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
993 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
994
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200995 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100996 yang_print_close(out, level, flag);
Radek Krejci6793db02015-05-22 17:49:54 +0200997}
998
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200999static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001000yang_print_container(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001001{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001002 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001003 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001004 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001005
Radek Krejci32cce7c2015-12-09 16:44:13 +01001006 ly_print(out, "%*scontainer %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001007 level++;
Radek Krejci6a113852015-07-03 16:04:20 +02001008
Radek Krejci5dd25122017-01-11 17:28:13 +01001009 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001010 if (cont->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001011 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001012 yang_print_when(out, level, node->module, cont->when);
1013 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001014 for (i = 0; i < cont->iffeature_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001015 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001016 yang_print_iffeature(out, level, node->module, &cont->iffeature[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001017 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001018 for (i = 0; i < cont->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001019 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001020 yang_print_must(out, level, node->module, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001021 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001022 if (cont->presence != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001023 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001024 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence,
1025 node->module, node->ext, node->ext_size);
Michal Vasko4773b762015-07-07 12:15:10 +02001026 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001027 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG |
1028 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001029 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001030 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001031 yang_print_typedef(out, level, node->module, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001032 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001033 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001034 /* augments */
1035 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001036 continue;
1037 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001038 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +01001039 yang_print_snode(out, level, sub, LYS_GROUPING);
1040 }
1041 LY_TREE_FOR(node->child, sub) {
1042 /* augments */
1043 if (sub->parent != node) {
1044 continue;
1045 }
1046 yang_print_open(out, &flag);
1047 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1048 LYS_USES | LYS_ANYDATA );
1049 }
1050 LY_TREE_FOR(node->child, sub) {
1051 /* augments */
1052 if (sub->parent != node) {
1053 continue;
1054 }
1055 yang_print_open(out, &flag);
1056 yang_print_snode(out, level, sub, LYS_ACTION);
1057 }
1058 LY_TREE_FOR(node->child, sub) {
1059 /* augments */
1060 if (sub->parent != node) {
1061 continue;
1062 }
1063 yang_print_open(out, &flag);
Radek Krejci033983b2017-01-13 12:43:20 +01001064 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001065 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001066
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001067 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001068 yang_print_close(out, level, flag);
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001069}
1070
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001071static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001072yang_print_case(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001073{
Radek Krejci5dd25122017-01-11 17:28:13 +01001074 int flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001075 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001076 struct lys_node_case *cas = (struct lys_node_case *)node;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001077
Radek Krejci5dd25122017-01-11 17:28:13 +01001078 ly_print(out, "%*scase %s", LEVEL, INDENT, cas->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001079 level++;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001080
Radek Krejci5dd25122017-01-11 17:28:13 +01001081 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001082 if (cas->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001083 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001084 yang_print_when(out, level, node->module, cas->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001085 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001086 yang_print_snode_common(out, level, node, node->module, &flag,
1087 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001088
Radek Krejci1d82ef62015-08-07 14:44:40 +02001089 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001090 /* augments */
1091 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001092 continue;
1093 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001094 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001095 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001096 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejcibf2abff2016-08-23 15:51:52 +02001097 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001098 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001099
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001100 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001101 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001102}
1103
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001104static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001105yang_print_choice(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001106{
Radek Krejci5dd25122017-01-11 17:28:13 +01001107 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001108 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001109 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001110
Radek Krejci5dd25122017-01-11 17:28:13 +01001111 ly_print(out, "%*schoice %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001112 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001113
1114 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1115 if (choice->when) {
1116 yang_print_open(out, &flag);
1117 yang_print_when(out, level, node->module, choice->when);
1118 }
1119 for (i = 0; i < choice->iffeature_size; i++) {
1120 yang_print_open(out, &flag);
1121 yang_print_iffeature(out, level, node->module, &choice->iffeature[i]);
1122 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001123 if (choice->dflt != NULL) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001124 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001125 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt->name,
1126 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001127 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001128 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1129 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001130
Radek Krejci1d82ef62015-08-07 14:44:40 +02001131 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001132 /* augments */
1133 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001134 continue;
1135 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001136 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001137 yang_print_snode(out, level, sub,
Radek Krejci5dd25122017-01-11 17:28:13 +01001138 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_CASE);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001139 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001140
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001141 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001142 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001143}
1144
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001145static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001146yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001147{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001148 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001149 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001150 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001151
Radek Krejci76b07902015-10-09 09:11:25 +02001152 ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001153 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001154
1155 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001156 if (leaf->when) {
1157 yang_print_when(out, level, node->module, leaf->when);
1158 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001159 for (i = 0; i < leaf->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001160 yang_print_iffeature(out, level, node->module, &leaf->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001161 }
Radek Krejci76b07902015-10-09 09:11:25 +02001162 yang_print_type(out, level, node->module, &leaf->type);
Radek Krejci43e3c312017-01-11 11:34:44 +01001163 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, leaf->units,
1164 node->module, node->ext, node->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +01001165 for (i = 0; i < leaf->must_size; i++) {
1166 yang_print_must(out, level, node->module, &leaf->must[i]);
1167 }
Michal Vaskod875e882016-05-19 10:57:30 +02001168 if (leaf->dflt) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001169 if (leaf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001170 assert(strchr(leaf->dflt, ':'));
1171 if (!strncmp(leaf->dflt, lys_node_module(node)->name, strchr(leaf->dflt, ':') - leaf->dflt)) {
1172 /* local module */
1173 dflt = lydict_insert(node->module->ctx, strchr(leaf->dflt, ':') + 1, 0);
1174 } else {
1175 dflt = transform_json2schema(node->module, leaf->dflt);
1176 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001177 } else {
1178 dflt = leaf->dflt;
1179 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001180 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt,
1181 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001182 if (leaf->flags & LYS_DFLTJSON) {
1183 lydict_remove(node->module->ctx, dflt);
1184 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001185 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001186 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1187 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001188 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001189 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +02001190}
1191
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001192static void
Radek Krejcibf2abff2016-08-23 15:51:52 +02001193yang_print_anydata(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko16083662015-06-09 14:00:45 +02001194{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001195 int i, flag = 0;
Radek Krejcibf2abff2016-08-23 15:51:52 +02001196 struct lys_node_anydata *any = (struct lys_node_anydata *)node;
Michal Vasko16083662015-06-09 14:00:45 +02001197
Radek Krejcibf2abff2016-08-23 15:51:52 +02001198 ly_print(out, "%*s%s %s", LEVEL, INDENT, any->nodetype == LYS_ANYXML ? "anyxml" : "anydata", any->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001199 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001200
1201 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1202 if (any->when) {
1203 yang_print_open(out, &flag);
1204 yang_print_when(out, level, node->module, any->when);
1205 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001206 for (i = 0; i < any->iffeature_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001207 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001208 yang_print_iffeature(out, level, node->module, &any->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001209 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001210 for (i = 0; i < any->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001211 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001212 yang_print_must(out, level, node->module, &any->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001213 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001214 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1215 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001216 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001217 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001218}
1219
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001220static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001221yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001222{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001223 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001224 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001225 const char *dflt;
Radek Krejci43e3c312017-01-11 11:34:44 +01001226 char *str;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001227
Radek Krejci76b07902015-10-09 09:11:25 +02001228 ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001229 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001230 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001231 if (llist->when) {
1232 yang_print_when(out, level, llist->module, llist->when);
1233 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001234 for (i = 0; i < llist->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001235 yang_print_iffeature(out, level, node->module, &llist->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001236 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001237 yang_print_type(out, level, node->module, &llist->type);
1238 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, llist->units,
1239 node->module, node->ext, node->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001240 for (i = 0; i < llist->must_size; i++) {
1241 yang_print_must(out, level, node->module, &llist->must[i]);
1242 }
Pavol Vican38321d02016-08-16 14:56:02 +02001243 for (i = 0; i < llist->dflt_size; ++i) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001244 if (llist->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001245 assert(strchr(llist->dflt[i], ':'));
1246 if (!strncmp(llist->dflt[i], lys_node_module(node)->name, strchr(llist->dflt[i], ':') - llist->dflt[i])) {
1247 /* local module */
1248 dflt = lydict_insert(node->module->ctx, strchr(llist->dflt[i], ':') + 1, 0);
1249 } else {
1250 dflt = transform_json2schema(node->module, llist->dflt[i]);
1251 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001252 } else {
1253 dflt = llist->dflt[i];
1254 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001255 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, dflt,
1256 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001257 if (llist->flags & LYS_DFLTJSON) {
1258 lydict_remove(node->module->ctx, dflt);
1259 }
Pavol Vican38321d02016-08-16 14:56:02 +02001260 }
Radek Krejci178a0942017-01-16 15:36:35 +01001261 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001262 if (llist->min > 0) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001263 asprintf(&str, "%u", llist->min);
1264 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, str,
1265 node->module, node->ext, node->ext_size);
1266 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001267 }
1268 if (llist->max > 0) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001269 asprintf(&str, "%u", llist->max);
1270 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, str,
1271 node->module, node->ext, node->ext_size);
1272 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001273 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001274 if (llist->flags & LYS_USERORDERED) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001275 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1276 node->module, node->ext, node->ext_size);
1277 } else if (ly_print_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
1278 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1279 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001280 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001281 yang_print_snode_common(out, level, node, node->module, NULL,
1282 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001283 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001284 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001285}
1286
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001287static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001288yang_print_list(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001289{
Radek Krejci5dd25122017-01-11 17:28:13 +01001290 int i, p, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001291 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001292 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejci43e3c312017-01-11 11:34:44 +01001293 char *str;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001294
Radek Krejci5dd25122017-01-11 17:28:13 +01001295 ly_print(out, "%*slist %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001296 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001297 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001298 if (list->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001299 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001300 yang_print_when(out, level, list->module, list->when);
1301 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001302 for (i = 0; i < list->iffeature_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001303 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001304 yang_print_iffeature(out, level, node->module, &list->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001305 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001306 for (i = 0; i < list->must_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001307 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001308 yang_print_must(out, level, list->module, &list->must[i]);
1309 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001310 if (list->keys_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001311 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001312 yang_print_substmt(out, level, LYEXT_SUBSTMT_KEY, 0, list->keys_str,
1313 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001314 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001315 for (i = 0; i < list->unique_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001316 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001317 yang_print_unique(out, level, &list->unique[i]);
Radek Krejci43e3c312017-01-11 11:34:44 +01001318 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +01001319 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +01001320 do {
Radek Krejcicfce0292017-01-13 12:37:57 +01001321 p = ly_print_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejci43e3c312017-01-11 11:34:44 +01001322 } while (p != -1 && list->ext[p]->substmt_index != i);
1323 if (p != -1) {
1324 ly_print(out, " {\n");
1325 do {
1326 yang_print_extension_instances(out, level + 1, list->module, LYEXT_SUBSTMT_UNIQUE, i, &list->ext[p], 1);
1327 do {
1328 p = ly_print_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
1329 } while (p != -1 && list->ext[p]->substmt_index != i);
1330 } while (p != -1);
1331 ly_print(out, "%*s}\n", LEVEL, INDENT);
1332 } else {
1333 ly_print(out, ";\n");
1334 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001335 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001336 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001337 if (list->min > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001338 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001339 asprintf(&str, "%u", list->min);
1340 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, str,
1341 node->module, node->ext, node->ext_size);
1342 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001343 }
1344 if (list->max > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001345 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001346 asprintf(&str, "%u", list->max);
1347 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, str,
1348 node->module, node->ext, node->ext_size);
1349 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001350 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001351 if (list->flags & LYS_USERORDERED) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001352 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001353 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1354 node->module, node->ext, node->ext_size);
1355 } else if (ly_print_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001356 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001357 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1358 node->module, node->ext, node->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001359 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001360 yang_print_snode_common(out, level, node, node->module, &flag,
1361 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001362 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001363 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001364 yang_print_typedef(out, level, list->module, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001365 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001366
Radek Krejci1d82ef62015-08-07 14:44:40 +02001367 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001368 /* augments */
1369 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001370 continue;
1371 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001372 yang_print_open(out, &flag);
1373 yang_print_snode(out, level, sub, LYS_GROUPING);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001374 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001375
1376 LY_TREE_FOR(node->child, sub) {
1377 /* augments */
1378 if (sub->parent != node) {
1379 continue;
1380 }
1381 yang_print_open(out, &flag);
1382 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1383 LYS_USES | LYS_GROUPING | LYS_ANYDATA);
1384 }
1385
1386 LY_TREE_FOR(node->child, sub) {
1387 /* augments */
1388 if (sub->parent != node) {
1389 continue;
1390 }
1391 yang_print_open(out, &flag);
1392 yang_print_snode(out, level, sub, LYS_ACTION);
1393 }
1394
1395 LY_TREE_FOR(node->child, sub) {
1396 /* augments */
1397 if (sub->parent != node) {
1398 continue;
1399 }
1400 yang_print_open(out, &flag);
1401 yang_print_snode(out, level, sub, LYS_NOTIF);
1402 }
1403
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_grouping(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001410{
Radek Krejci5dd25122017-01-11 17:28:13 +01001411 int i, flag = 0;
Michal Vasko0c5e9282016-02-15 13:11:57 +01001412 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001413 struct lys_node_grp *grp = (struct lys_node_grp *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001414
Radek Krejci5dd25122017-01-11 17:28:13 +01001415 ly_print(out, "%*sgrouping %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001416 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001417
Radek Krejci5dd25122017-01-11 17:28:13 +01001418 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_STATUS |
1419 SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001420
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001421 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001422 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001423 yang_print_typedef(out, level, node->module, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001424 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001425
Michal Vasko0c5e9282016-02-15 13:11:57 +01001426 LY_TREE_FOR(node->child, sub) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001427 yang_print_open(out, &flag);
1428 yang_print_snode(out, level, sub, LYS_GROUPING);
1429 }
1430
1431 LY_TREE_FOR(node->child, sub) {
1432 yang_print_open(out, &flag);
1433 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1434 LYS_USES | LYS_ANYDATA);
1435 }
1436
1437 LY_TREE_FOR(node->child, sub) {
1438 yang_print_open(out, &flag);
1439 yang_print_snode(out, level, sub, LYS_ACTION);
1440 }
1441
1442 LY_TREE_FOR(node->child, sub) {
1443 yang_print_open(out, &flag);
1444 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001445 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001446
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001447 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001448 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001449}
1450
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001451static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001452yang_print_uses(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001453{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001454 int i, flag = 0;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001455 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001456 struct lys_module *mod;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001457
Radek Krejci76b07902015-10-09 09:11:25 +02001458 ly_print(out, "%*suses ", LEVEL, INDENT);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001459 if (node->child) {
Michal Vasko6c629ac2016-02-15 14:08:23 +01001460 mod = lys_node_module(node->child);
Michal Vasko1dae8ec2016-02-15 14:49:01 +01001461 if (lys_node_module(node) != mod) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001462 ly_print(out, "%s:", transform_module_name2import_prefix(node->module, mod->name));
1463 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +02001464 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001465 ly_print(out, "%s", uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001466 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001467
Radek Krejci5dd25122017-01-11 17:28:13 +01001468 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001469 if (uses->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001470 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001471 yang_print_when(out, level, node->module, uses->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001472 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001473 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_IFF |
1474 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001475 for (i = 0; i < uses->refine_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001476 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001477 yang_print_refine(out, level, node->module, &uses->refine[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001478 }
Michal Vasko6f25f212015-07-07 15:42:07 +02001479 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001480 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001481 yang_print_augment(out, level, &uses->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001482 }
1483
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001484 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001485 yang_print_close(out, level, flag);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001486}
1487
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001488static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001489yang_print_input_output(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko5bbae102015-06-16 12:16:44 +02001490{
Michal Vaskof4d3d742015-06-16 11:51:09 +02001491 int i;
Radek Krejci76512572015-08-04 09:47:08 +02001492 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001493 struct lys_node_inout *inout = (struct lys_node_inout *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001494
Radek Krejci76b07902015-10-09 09:11:25 +02001495 ly_print(out, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LYS_INPUT ? "input" : "output"));
Michal Vaskof4d3d742015-06-16 11:51:09 +02001496 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001497
Radek Krejcie534c132016-11-23 13:32:31 +01001498 if (node->ext_size) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001499 yang_print_extension_instances(out, level, node->module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001500 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001501 for (i = 0; i < inout->must_size; i++) {
1502 yang_print_must(out, level, node->module, &inout->must[i]);
1503 }
Radek Krejcie534c132016-11-23 13:32:31 +01001504 for (i = 0; i < inout->tpdf_size; i++) {
1505 yang_print_typedef(out, level, node->module, &inout->tpdf[i]);
1506 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001507 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001508 /* augments */
1509 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001510 continue;
1511 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001512 yang_print_snode(out, level, sub, LYS_GROUPING);
1513 }
1514 LY_TREE_FOR(node->child, sub) {
1515 /* augments */
1516 if (sub->parent != node) {
1517 continue;
1518 }
1519 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1520 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001521 }
1522
1523 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001524 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001525}
1526
1527static void
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001528yang_print_rpc_action(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskof4d3d742015-06-16 11:51:09 +02001529{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001530 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001531 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001532 struct lys_node_rpc_action *rpc = (struct lys_node_rpc_action *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001533
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001534 ly_print(out, "%*s%s %s", LEVEL, INDENT, (node->nodetype == LYS_RPC ? "rpc" : "action"), node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001535
1536 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001537 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF |
1538 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko4773b762015-07-07 12:15:10 +02001539
Michal Vaskof4d3d742015-06-16 11:51:09 +02001540 for (i = 0; i < rpc->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001541 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001542 yang_print_typedef(out, level, node->module, &rpc->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001543 }
1544
Radek Krejci1d82ef62015-08-07 14:44:40 +02001545 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001546 /* augments */
1547 if (sub->parent != node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001548 continue;
1549 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001550 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +01001551 yang_print_snode(out, level, sub, LYS_GROUPING);
1552 }
1553
1554 LY_TREE_FOR(node->child, sub) {
1555 /* augments */
1556 if (sub->parent != node) {
1557 continue;
1558 }
1559 yang_print_open(out, &flag);
1560 yang_print_snode(out, level, sub, LYS_INPUT);
1561 }
1562
1563 LY_TREE_FOR(node->child, sub) {
Michal Vasko8b942f02017-01-24 13:12:59 +01001564 /* augments and implicit nodes */
1565 if ((sub->parent != node) || ((sub->nodetype & (LYS_INPUT | LYS_OUTPUT) && (sub->flags & LYS_IMPLICIT)))) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001566 continue;
1567 }
1568 yang_print_open(out, &flag);
1569 yang_print_snode(out, level, sub, LYS_OUTPUT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001570 }
1571
1572 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001573 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001574}
1575
1576static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001577yang_print_notif(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko7690bc12015-06-16 12:26:05 +02001578{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001579 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001580 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001581 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001582
Radek Krejci32cce7c2015-12-09 16:44:13 +01001583 ly_print(out, "%*snotification %s", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001584
1585 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001586 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Radek Krejci12032a52016-07-29 15:42:56 +02001587 for (i = 0; i < notif->must_size; i++) {
1588 yang_print_open(out, &flag);
1589 yang_print_must(out, level, node->module, &notif->must[i]);
1590 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001591 yang_print_snode_common(out, level, node, node->module, &flag,
1592 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
1593 for (i = 0; i < notif->tpdf_size; i++) {
1594 yang_print_open(out, &flag);
1595 yang_print_typedef(out, level, node->module, &notif->tpdf[i]);
1596 }
1597 LY_TREE_FOR(node->child, sub) {
1598 /* augments */
1599 if (sub->parent != node) {
1600 continue;
1601 }
1602 yang_print_open(out, &flag);
1603 yang_print_snode(out, level, sub, LYS_GROUPING);
1604 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001605 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001606 /* augments */
1607 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001608 continue;
1609 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001610 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001611 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001612 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +01001613 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001614 }
1615
1616 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001617 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001618}
1619
1620static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001621yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001622{
Radek Krejci2c99a622017-01-12 10:11:13 +01001623 if (node->nodetype & mask) {
1624 if ((node->nodetype & (LYS_INPUT | LYS_OUTPUT)) && (node->flags & LYS_IMPLICIT)) {
1625 /* implicit input/output node is not supposed to be printed */
1626 return;
1627 } else if (!node->parent ||
1628 (node->parent->nodetype == LYS_AUGMENT && node != node->parent->child) ||
1629 (node->parent->nodetype != LYS_AUGMENT && node->prev->next)) {
1630 /* do not print the blank line before the first data-def node */
1631 ly_print(out, "\n");
1632 }
1633 }
1634
Radek Krejci1d82ef62015-08-07 14:44:40 +02001635 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +02001636 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +02001637 yang_print_container(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001638 break;
Radek Krejci76512572015-08-04 09:47:08 +02001639 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +02001640 yang_print_choice(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001641 break;
Radek Krejci76512572015-08-04 09:47:08 +02001642 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +02001643 yang_print_leaf(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001644 break;
Radek Krejci76512572015-08-04 09:47:08 +02001645 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001646 yang_print_leaflist(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001647 break;
Radek Krejci76512572015-08-04 09:47:08 +02001648 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001649 yang_print_list(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001650 break;
Radek Krejci76512572015-08-04 09:47:08 +02001651 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +02001652 yang_print_uses(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001653 break;
Radek Krejci76512572015-08-04 09:47:08 +02001654 case LYS_GROUPING:
Radek Krejci76b07902015-10-09 09:11:25 +02001655 yang_print_grouping(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001656 break;
Radek Krejci76512572015-08-04 09:47:08 +02001657 case LYS_ANYXML:
Radek Krejcibf2abff2016-08-23 15:51:52 +02001658 case LYS_ANYDATA:
1659 yang_print_anydata(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001660 break;
Radek Krejci76512572015-08-04 09:47:08 +02001661 case LYS_CASE:
Radek Krejci76b07902015-10-09 09:11:25 +02001662 yang_print_case(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001663 break;
Radek Krejci5dd25122017-01-11 17:28:13 +01001664 case LYS_RPC:
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001665 case LYS_ACTION:
1666 yang_print_rpc_action(out, level, node);
1667 break;
Radek Krejci76512572015-08-04 09:47:08 +02001668 case LYS_INPUT:
1669 case LYS_OUTPUT:
Radek Krejci2c99a622017-01-12 10:11:13 +01001670 yang_print_input_output(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001671 break;
Michal Vaskob15cae22016-09-15 09:40:56 +02001672 case LYS_NOTIF:
1673 yang_print_notif(out, level, node);
1674 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001675 default:
1676 break;
1677 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001678}
1679
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001680int
Michal Vasko1e62a092015-12-01 12:27:20 +01001681yang_print_model(struct lyout *out, const struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001682{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001683 unsigned int i;
Radek Krejci43e3c312017-01-11 11:34:44 +01001684 int level = 0, p;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001685#define LEVEL (level*2)
1686
Radek Krejci1d82ef62015-08-07 14:44:40 +02001687 struct lys_node *node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001688
Radek Krejci8d81e002015-12-10 11:18:59 +01001689 /* (sub)module-header-stmts */
Michal Vasko116172e2015-07-07 11:54:37 +02001690 if (module->type) {
Michal Vasko89563fc2016-07-28 16:19:35 +02001691 ly_print(out, "submodule %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001692 level++;
Radek Krejci77424f72017-01-20 13:21:09 +01001693 if (lys_main_module(module)->version > 1 ||
1694 ly_print_ext_iter(module->ext, module->ext_size, 0, LYEXT_SUBSTMT_VERSION) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001695 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0,
1696 ((struct lys_submodule *)module)->belongsto->version == 2 ? "1.1" : "1",
1697 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001698 }
Radek Krejci76b07902015-10-09 09:11:25 +02001699 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Radek Krejcicfce0292017-01-13 12:37:57 +01001700 p = -1;
1701 while ((p = ly_print_ext_iter(module->ext, module->ext_size, p + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001702 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0, &module->ext[p], 1);
1703 }
1704 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1705 module, module->ext, module->ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001706 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001707 } else {
Michal Vasko89563fc2016-07-28 16:19:35 +02001708 ly_print(out, "module %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001709 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001710 if (module->version) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001711 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == 2 ? "1.1" : "1",
1712 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001713 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001714 yang_print_substmt(out, level, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns,
1715 module, module->ext, module->ext_size);
1716 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1717 module, module->ext, module->ext_size);
Michal Vasko116172e2015-07-07 11:54:37 +02001718 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001719
Radek Krejci8d81e002015-12-10 11:18:59 +01001720 /* linkage-stmts */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001721 for (i = 0; i < module->imp_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001722 ly_print(out, "\n%*simport %s {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001723 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001724 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1725 module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci39228d22017-01-13 12:43:55 +01001726 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->imp[i].prefix,
1727 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001728 if (module->imp[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001729 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->imp[i].rev,
1730 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001731 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001732 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->imp[i].dsc,
1733 module, module->imp[i].ext, module->imp[i].ext_size);
1734 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->imp[i].ref,
1735 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001736 level--;
Michal Vaskoc8e3ce02016-02-12 14:28:35 +01001737 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001738 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001739 for (i = 0; i < module->inc_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001740 if (module->inc[i].rev[0] || module->inc[i].dsc || module->inc[i].ref || module->inc[i].ext_size) {
1741 ly_print(out, "\n%*sinclude %s {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci8d81e002015-12-10 11:18:59 +01001742 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001743 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1744 module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001745 if (module->inc[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001746 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->inc[i].rev,
1747 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001748 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001749 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->inc[i].dsc,
1750 module, module->inc[i].ext, module->inc[i].ext_size);
1751 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->inc[i].ref,
1752 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001753 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001754 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001755 } else {
Radek Krejcie534c132016-11-23 13:32:31 +01001756 ly_print(out, "\n%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001757 }
1758 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001759
Radek Krejci8d81e002015-12-10 11:18:59 +01001760 /* meta-stmts */
1761 if (module->org || module->contact || module->dsc || module->ref) {
1762 ly_print(out, "\n");
1763 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001764 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org,
1765 module, module->ext, module->ext_size);
1766 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONTACT, 0, module->contact,
1767 module, module->ext, module->ext_size);
1768 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc,
1769 module, module->ext, module->ext_size);
1770 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->ref,
1771 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001772
1773 /* revision-stmts */
1774 if (module->rev_size) {
1775 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001776 }
1777 for (i = 0; i < module->rev_size; i++) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001778 if (module->rev[i].dsc || module->rev[i].ref || module->rev[i].ext_size) {
Radek Krejci76b07902015-10-09 09:11:25 +02001779 ly_print(out, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci5dd25122017-01-11 17:28:13 +01001780 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1781 module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci43e3c312017-01-11 11:34:44 +01001782 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_DESCRIPTION, 0, module->rev[i].dsc,
1783 module, module->rev[i].ext, module->rev[i].ext_size);
1784 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_REFERENCE, 0, module->rev[i].ref,
1785 module, module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001786 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001787 } else {
Michal Vasko86dfd262016-02-15 14:26:31 +01001788 ly_print(out, "%*srevision %s;\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001789 }
1790 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001791
Radek Krejci8d81e002015-12-10 11:18:59 +01001792 /* body-stmts */
Radek Krejcie534c132016-11-23 13:32:31 +01001793 for (i = 0; i < module->extensions_size; i++) {
1794 ly_print(out, "\n");
1795 yang_print_extension(out, level, &module->extensions[i]);
1796 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001797 if (module->ext_size) {
1798 ly_print(out, "\n");
1799 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, module->ext, module->ext_size);
1800 }
Radek Krejcie534c132016-11-23 13:32:31 +01001801
Michal Vasko30f6e912015-07-07 12:24:27 +02001802 for (i = 0; i < module->features_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001803 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001804 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001805 }
1806
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001807 for (i = 0; i < module->ident_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001808 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001809 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001810 }
Radek Krejci6793db02015-05-22 17:49:54 +02001811
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001812 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001813 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001814 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001815 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001816
Radek Krejci5dd25122017-01-11 17:28:13 +01001817 LY_TREE_FOR(lys_main_module(module)->data, node) {
1818 if (node->module != module) {
1819 /* data from submodules */
1820 continue;
1821 }
1822 yang_print_snode(out, level, node, LYS_GROUPING);
Radek Krejci8d81e002015-12-10 11:18:59 +01001823 }
1824
Radek Krejcic4283442016-04-22 09:19:27 +02001825 LY_TREE_FOR(lys_main_module(module)->data, node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001826 if (node->module != module) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001827 /* data from submodules */
Radek Krejcic071c542016-01-27 14:57:51 +01001828 continue;
1829 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001830 yang_print_snode(out, level, node, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1831 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001832 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001833
Michal Vasko6f25f212015-07-07 15:42:07 +02001834 for (i = 0; i < module->augment_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001835 ly_print(out, "\n");
Radek Krejci43e3c312017-01-11 11:34:44 +01001836 yang_print_augment(out, level, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001837 }
1838
Radek Krejci5dd25122017-01-11 17:28:13 +01001839 LY_TREE_FOR(lys_main_module(module)->data, node) {
1840 if (node->module != module) {
1841 /* data from submodules */
1842 continue;
1843 }
1844 yang_print_snode(out, level, node, LYS_RPC | LYS_ACTION);
1845 }
1846
1847 LY_TREE_FOR(lys_main_module(module)->data, node) {
1848 if (node->module != module) {
1849 /* data from submodules */
1850 continue;
1851 }
1852 yang_print_snode(out, level, node, LYS_NOTIF);
1853 }
1854
1855 for (i = 0; i < module->deviation_size; ++i) {
1856 ly_print(out, "\n");
1857 yang_print_deviation(out, level, module, &module->deviation[i]);
1858 }
1859
Radek Krejci76b07902015-10-09 09:11:25 +02001860 ly_print(out, "}\n");
Michal Vasko95068c42016-03-24 14:58:11 +01001861 ly_print_flush(out);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001862
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001863 return EXIT_SUCCESS;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001864#undef LEVEL
1865}