blob: 511b5e96be902b80dd5b5f63d927fe9a9e315602 [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 Krejci8d6b7422017-02-03 14:42:13 +010029static void yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
30 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
31 struct lys_ext_instance **ext, unsigned int count);
Radek Krejcida04f4a2015-05-21 12:54:09 +020032
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020033static void
Michal Vasko25cb6c62016-02-12 14:36:21 +010034yang_encode(struct lyout *out, const char *text, int len)
35{
36 int i, start_len;
37 const char *start;
38 char special = 0;
39
40 if (!len) {
41 return;
42 }
43
44 if (len < 0) {
45 len = strlen(text);
46 }
47
48 start = text;
49 start_len = 0;
50 for (i = 0; i < len; ++i) {
51 switch (text[i]) {
52 case '\n':
53 case '\t':
54 case '\"':
55 case '\\':
56 special = text[i];
57 break;
58 default:
59 ++start_len;
60 break;
61 }
62
63 if (special) {
64 ly_write(out, start, start_len);
65 switch (special) {
66 case '\n':
67 ly_write(out, "\\n", 2);
68 break;
69 case '\t':
70 ly_write(out, "\\t", 2);
71 break;
72 case '\"':
73 ly_write(out, "\\\"", 2);
74 break;
75 case '\\':
76 ly_write(out, "\\\\", 2);
77 break;
78 }
79
80 start += start_len + 1;
81 start_len = 0;
82
83 special = 0;
84 }
85 }
86
87 ly_write(out, start, start_len);
88}
89
90static void
Radek Krejci32cce7c2015-12-09 16:44:13 +010091yang_print_open(struct lyout *out, int *flag)
92{
93 if (flag && !*flag) {
94 *flag = 1;
95 ly_print(out, " {\n");
96 }
97}
98
99static void
100yang_print_close(struct lyout *out, int level, int flag)
101{
102 if (flag) {
103 ly_print(out, "%*s}\n", LEVEL, INDENT);
104 } else {
105 ly_print(out, ";\n");
106 }
107}
108
109static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100110yang_print_text(struct lyout *out, int level, const char *name, const char *text, int singleline, int closed)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200111{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200112 const char *s, *t;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200113
Radek Krejci8d81e002015-12-10 11:18:59 +0100114 if (singleline) {
115 ly_print(out, "%*s%s \"", LEVEL, INDENT, name);
116 } else {
117 ly_print(out, "%*s%s\n", LEVEL, INDENT, name);
118 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200119
Radek Krejci8d81e002015-12-10 11:18:59 +0100120 ly_print(out, "%*s\"", LEVEL, INDENT);
121 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200122 t = text;
123 while ((s = strchr(t, '\n'))) {
Michal Vasko25cb6c62016-02-12 14:36:21 +0100124 yang_encode(out, t, s - t);
125 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200126 t = s + 1;
Michal Vasko25cb6c62016-02-12 14:36:21 +0100127 ly_print(out, "%*s ", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200128 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200129
范昌虎1006995277de5fc2016-10-08 07:33:29 -0400130 yang_encode(out, t, strlen(t));
Radek Krejci43e3c312017-01-11 11:34:44 +0100131 if (closed) {
132 ly_print(out, "\";\n");
133 } else {
134 ly_print(out, "\"");
135 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200136 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200137
138}
139
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200140static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100141yang_print_substmt(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text,
142 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size)
143{
Radek Krejcicfce0292017-01-13 12:37:57 +0100144 int i = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100145
146 if (!text) {
147 /* nothing to print */
148 return;
149 }
150
Radek Krejcicfce0292017-01-13 12:37:57 +0100151 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100152 i = lys_ext_iter(ext, ext_size, i + 1, substmt);
Radek Krejcifebdad72017-02-06 11:35:51 +0100153 } while (i != -1 && ext[i]->insubstmt_index != substmt_index);
Radek Krejcicfce0292017-01-13 12:37:57 +0100154
Radek Krejci43e3c312017-01-11 11:34:44 +0100155 if (ext_substmt_info[substmt].flags & SUBST_FLAG_ID) {
156 ly_print(out, "%*s%s %s%s", LEVEL, INDENT, ext_substmt_info[substmt].name, text, i == -1 ? ";\n" : "");
157 } else {
158 yang_print_text(out, level, ext_substmt_info[substmt].name, text,
159 (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) ? 0 : 1, i == -1 ? 1 : 0);
160 }
161
162 if (i != -1) {
163 ly_print(out, " {\n");
164 do {
165 yang_print_extension_instances(out, level + 1, module, substmt, substmt_index, &ext[i], 1);
166 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100167 i = lys_ext_iter(ext, ext_size, i + 1, substmt);
Radek Krejcifebdad72017-02-06 11:35:51 +0100168 } while (i != -1 && ext[i]->insubstmt_index != substmt_index);
Radek Krejci43e3c312017-01-11 11:34:44 +0100169 } while (i != -1);
170 ly_print(out, "%*s}\n", LEVEL, INDENT);
171 }
172}
173
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200174static void
Radek Krejci9ff0a922016-07-14 13:08:05 +0200175yang_print_iffeature(struct lyout *out, int level, const struct lys_module *module, struct lys_iffeature *iffeature)
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200176{
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200177 ly_print(out, "%*sif-feature \"", LEVEL, INDENT);
Michal Vasko77e8a952017-02-03 15:10:08 +0100178 ly_print_iffeature(out, module, iffeature, 0);
Radek Krejci43e3c312017-01-11 11:34:44 +0100179
180 /* extensions */
181 if (iffeature->ext_size) {
182 ly_print(out, "\" {\n");
183 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0, iffeature->ext, iffeature->ext_size);
184 ly_print(out, "%*s}\n", LEVEL, INDENT);
185 } else {
186 ly_print(out, "\";\n");
187 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200188}
189
Radek Krejci5dd25122017-01-11 17:28:13 +0100190/*
191 * Covers:
192 * extension (instances), if-features, config, mandatory, status, description, reference
193 */
194#define SNODE_COMMON_EXT 0x01
195#define SNODE_COMMON_IFF 0x02
196#define SNODE_COMMON_CONFIG 0x04
197#define SNODE_COMMON_MAND 0x08
198#define SNODE_COMMON_STATUS 0x10
199#define SNODE_COMMON_DSC 0x20
200#define SNODE_COMMON_REF 0x40
201static void
202yang_print_snode_common(struct lyout *out, int level, const struct lys_node *node, const struct lys_module *module,
203 int *flag, int mask)
204{
205 int i;
206 const char *status = NULL;
207
208 /* extensions */
209 if ((mask & SNODE_COMMON_EXT) && node->ext_size) {
210 yang_print_open(out, flag);
211 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
212 }
213
214 /* if-features */
215 if (mask & SNODE_COMMON_IFF) {
216 for (i = 0; i < node->iffeature_size; ++i) {
217 yang_print_open(out, flag);
218 yang_print_iffeature(out, level, module, &node->iffeature[i]);
219 }
220 }
221
222 /* config */
223 if (mask & SNODE_COMMON_CONFIG) {
224 /* get info if there is an extension for the config statement */
Radek Krejcibf285832017-01-26 16:05:41 +0100225 i = lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_CONFIG);
Radek Krejci5dd25122017-01-11 17:28:13 +0100226
227 if (lys_parent(node)) {
228 if ((node->flags & LYS_CONFIG_SET) || i != -1) {
229 /* print config when it differs from the parent or if it has an extension instance ... */
230 if (node->flags & LYS_CONFIG_W) {
231 yang_print_open(out, flag);
232 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
233 module, node->ext, node->ext_size);
234 } else if (node->flags & LYS_CONFIG_R) {
235 yang_print_open(out, flag);
236 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
237 module, node->ext, node->ext_size);
238 }
239 }
240 } else if (node->flags & LYS_CONFIG_R) {
241 /* ... or it's a top-level state node */
242 yang_print_open(out, flag);
243 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
244 module, node->ext, node->ext_size);
245 } else if (i != -1) {
246 /* the config has an extension, so we have to print it */
247 yang_print_open(out, flag);
248 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
249 module, node->ext, node->ext_size);
250 }
251 }
252
253 /* mandatory */
254 if ((mask & SNODE_COMMON_MAND) && (node->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
255 if (node->flags & LYS_MAND_TRUE) {
256 yang_print_open(out, flag);
257 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true",
258 module, node->ext, node->ext_size);
259 } else if (node->flags & LYS_MAND_FALSE) {
260 yang_print_open(out, flag);
261 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false",
262 module, node->ext, node->ext_size);
263 }
264 }
265
266 /* status */
267 if (mask & SNODE_COMMON_STATUS) {
268 if (node->flags & LYS_STATUS_CURR) {
269 yang_print_open(out, flag);
270 status = "current";
271 } else if (node->flags & LYS_STATUS_DEPRC) {
272 yang_print_open(out, flag);
273 status = "deprecated";
274 } else if (node->flags & LYS_STATUS_OBSLT) {
275 yang_print_open(out, flag);
276 status = "obsolete";
277 }
278 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, status, module, node->ext, node->ext_size);
279 }
280
281 /* description */
282 if ((mask & SNODE_COMMON_DSC) && node->dsc) {
283 yang_print_open(out, flag);
284 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, node->dsc,
285 module, node->ext, node->ext_size);
286 }
287
288 /* reference */
289 if ((mask & SNODE_COMMON_REF) && node->ref) {
290 yang_print_open(out, flag);
291 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, node->ref,
292 module, node->ext, node->ext_size);
293 }
294}
295
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200296static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100297yang_print_feature(struct lyout *out, int level, const struct lys_feature *feat)
Michal Vasko4773b762015-07-07 12:15:10 +0200298{
Radek Krejci5dd25122017-01-11 17:28:13 +0100299 int flag = 0;
Michal Vasko30f6e912015-07-07 12:24:27 +0200300
Radek Krejci32cce7c2015-12-09 16:44:13 +0100301 ly_print(out, "%*sfeature %s", LEVEL, INDENT, feat->name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100302 yang_print_snode_common(out, level + 1, (struct lys_node *)feat, feat->module, &flag, SNODE_COMMON_EXT |
303 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100304 yang_print_close(out, level, flag);
Michal Vasko4773b762015-07-07 12:15:10 +0200305}
306
307static void
Radek Krejcia1a6b762016-11-14 09:53:38 +0900308yang_print_extension(struct lyout *out, int level, const struct lys_ext *ext)
309{
Radek Krejcicfce0292017-01-13 12:37:57 +0100310 int flag = 0, flag2 = 0, i;
Radek Krejcia1a6b762016-11-14 09:53:38 +0900311
312 ly_print(out, "%*sextension %s", LEVEL, INDENT, ext->name);
313 level++;
314
Radek Krejci5dd25122017-01-11 17:28:13 +0100315 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
316 SNODE_COMMON_EXT);
317
Radek Krejcia1a6b762016-11-14 09:53:38 +0900318 if (ext->argument) {
319 yang_print_open(out, &flag);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900320
Radek Krejcicfce0292017-01-13 12:37:57 +0100321 ly_print(out, "%*sargument %s", LEVEL, INDENT, ext->argument);
322 i = -1;
Radek Krejcibf285832017-01-26 16:05:41 +0100323 while ((i = lys_ext_iter(ext->ext, ext->ext_size, i + 1, LYEXT_SUBSTMT_ARGUMENT)) != -1) {
Radek Krejcicfce0292017-01-13 12:37:57 +0100324 yang_print_open(out, &flag2);
325 yang_print_extension_instances(out, level + 1, ext->module, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->ext[i], 1);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900326 }
Radek Krejcibf285832017-01-26 16:05:41 +0100327 if ((ext->flags & LYS_YINELEM) || lys_ext_iter(ext->ext, ext->ext_size, 0, LYEXT_SUBSTMT_YINELEM) != -1) {
Radek Krejcicfce0292017-01-13 12:37:57 +0100328 yang_print_open(out, &flag2);
Radek Krejci87f90572017-01-24 11:19:42 +0100329 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, 0,
330 (ext->flags & LYS_YINELEM) ? "true" : "false", ext->module, ext->ext, ext->ext_size);
Radek Krejcicfce0292017-01-13 12:37:57 +0100331 }
332 yang_print_close(out, level, flag2);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900333 }
334
Radek Krejci5dd25122017-01-11 17:28:13 +0100335 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
336 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
337
Radek Krejcia1a6b762016-11-14 09:53:38 +0900338 level--;
339 yang_print_close(out, level, flag);
340}
341
342static void
Radek Krejciaa9c5202017-02-15 16:10:14 +0100343yang_print_restr(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *restr,
344 const char *name, const char *value)
Radek Krejci41726f92015-06-19 13:11:05 +0200345{
Radek Krejciaa9c5202017-02-15 16:10:14 +0100346 int flag = 0;
347
348 ly_print(out, "%*s%s \"", LEVEL, INDENT, name);
349 yang_encode(out, value, -1);
350 ly_print(out, "\"");
351
352 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100353 if (restr->ext_size) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100354 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100355 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, restr->ext, restr->ext_size);
356 }
Radek Krejcidaa95c42017-01-16 10:25:29 +0100357 if (restr->expr[0] == 0x15) {
358 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
Radek Krejciaa9c5202017-02-15 16:10:14 +0100359 yang_print_open(out, &flag);
Radek Krejcidaa95c42017-01-16 10:25:29 +0100360 yang_print_substmt(out, level, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match",
361 module, restr->ext, restr->ext_size);
362 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100363 if (restr->emsg != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100364 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100365 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg,
366 module, restr->ext, restr->ext_size);
367 }
368 if (restr->eapptag != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100369 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100370 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag,
371 module, restr->ext, restr->ext_size);
372 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200373 if (restr->dsc != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100374 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100375 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, restr->dsc,
376 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200377 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200378 if (restr->ref != NULL) {
Radek Krejciaa9c5202017-02-15 16:10:14 +0100379 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100380 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, restr->ref,
381 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200382 }
Radek Krejciaa9c5202017-02-15 16:10:14 +0100383 level--;
384 yang_print_close(out, level, flag);
Radek Krejci41726f92015-06-19 13:11:05 +0200385}
386
387static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100388yang_print_when(struct lyout *out, int level, const struct lys_module *module, const struct lys_when *when)
Michal Vasko1f0428a2015-07-07 14:55:04 +0200389{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100390 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100391 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200392
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100393 str = transform_json2schema(module, when->cond);
394 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200395 ly_print(out, "(!error!)");
396 return;
397 }
398
Michal Vasko25cb6c62016-02-12 14:36:21 +0100399 ly_print(out, "%*swhen \"", LEVEL, INDENT);
400 yang_encode(out, str, -1);
401 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100402 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200403
Michal Vasko1f0428a2015-07-07 14:55:04 +0200404 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100405
Radek Krejci43e3c312017-01-11 11:34:44 +0100406 if (when->ext_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100407 /* 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 +0100408 yang_print_open(out, &flag);
409 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, when->ext, when->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200410 }
Radek Krejci11e88fd2017-01-16 15:34:37 +0100411 if (when->dsc != NULL) {
412 yang_print_open(out, &flag);
413 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, when->dsc,
414 module, when->ext, when->ext_size);
415 }
416 if (when->ref != NULL) {
417 yang_print_open(out, &flag);
418 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, when->ref,
419 module, when->ext, when->ext_size);
420 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100421
Michal Vasko1f0428a2015-07-07 14:55:04 +0200422 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100423 yang_print_close(out, level, flag);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200424}
425
426static void
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100427yang_print_unsigned(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
428 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size,
429 unsigned int attr_value)
430{
431 char *str;
432
433 asprintf(&str, "%u", attr_value);
434 yang_print_substmt(out, level, substmt, substmt_index, str, module, ext, ext_size);
435 free(str);
436}
437
438static void
PavolVican2ed9f4e2017-02-16 00:08:45 +0100439yang_print_signed(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
440 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size,
441 signed int attr_value)
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100442{
443 char *str;
444
445 asprintf(&str, "%d", attr_value);
PavolVican2ed9f4e2017-02-16 00:08:45 +0100446 yang_print_substmt(out, level, substmt, substmt_index, str, module, ext, ext_size);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100447 free(str);
448}
449
450static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100451yang_print_type(struct lyout *out, int level, const struct lys_module *module, const struct lys_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200452{
Radek Krejci5dd25122017-01-11 17:28:13 +0100453 int i;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100454 int flag = 0, flag2;
Michal Vasko0fb82c62015-10-20 13:41:53 +0200455 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100456 char *s;
Radek Krejcic071c542016-01-27 14:57:51 +0100457 struct lys_module *mod;
Radek Krejci25d782a2015-05-22 15:03:23 +0200458
Michal Vasko0fb82c62015-10-20 13:41:53 +0200459 if (type->module_name) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100460 ly_print(out, "%*stype %s:%s", LEVEL, INDENT,
461 transform_module_name2import_prefix(module, type->module_name), type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200462 } else {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100463 ly_print(out, "%*stype %s", LEVEL, INDENT, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200464 }
465 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100466
467 /* extensions */
468 if (type->ext_size) {
469 yang_print_open(out, &flag);
470 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, type->ext, type->ext_size);
471 }
472
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200473 switch (type->base) {
474 case LY_TYPE_BINARY:
Michal Vasko4634cda2016-02-16 09:22:09 +0100475 if (type->info.binary.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100476 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100477 yang_print_restr(out, level, module, type->info.binary.length, "length", type->info.binary.length->expr);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200478 }
479 break;
480 case LY_TYPE_BITS:
481 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100482 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100483 ly_print(out, "%*sbit %s", LEVEL, INDENT, type->info.bits.bit[i].name);
484 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200485 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100486 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
487 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100488 if (!(type->info.bits.bit[i].flags & LYS_AUTOASSIGNED)) {
489 yang_print_open(out, &flag2);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100490 yang_print_unsigned(out, level, LYEXT_SUBSTMT_POSITION, 0, module,
491 type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
492 type->info.bits.bit[i].pos);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100493 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100494 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
495 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200496 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100497 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200498 }
499 break;
500 case LY_TYPE_DEC64:
Radek Krejcib51d5932016-09-08 14:02:52 +0200501 if (!type->der->type.der) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100502 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100503 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, 0, module,
504 type->ext, type->ext_size, type->info.dec64.dig);
Michal Vasko4634cda2016-02-16 09:22:09 +0100505 }
Michal Vaskoea505ee2015-07-07 14:01:00 +0200506 if (type->info.dec64.range != NULL) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100507 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100508 yang_print_restr(out, level, module, type->info.dec64.range, "range", type->info.dec64.range->expr);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200509 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200510 break;
511 case LY_TYPE_ENUM:
512 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100513 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100514 ly_print(out, "%*senum \"%s\"", LEVEL, INDENT, type->info.enums.enm[i].name);
515 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200516 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100517 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
518 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100519 if (!(type->info.enums.enm[i].flags & LYS_AUTOASSIGNED)) {
520 yang_print_open(out, &flag2);
PavolVican2ed9f4e2017-02-16 00:08:45 +0100521 yang_print_signed(out, level, LYEXT_SUBSTMT_VALUE, 0, module,
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100522 type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
523 type->info.enums.enm[i].value);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100524 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100525 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
526 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200527 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100528 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200529 }
530 break;
531 case LY_TYPE_IDENT:
Michal Vaskof2d43962016-09-02 11:10:16 +0200532 if (type->info.ident.count) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100533 yang_print_open(out, &flag);
Michal Vaskof2d43962016-09-02 11:10:16 +0200534 for (i = 0; i < type->info.ident.count; ++i) {
535 mod = lys_main_module(type->info.ident.ref[i]->module);
536 if (lys_main_module(module) == mod) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100537 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, type->info.ident.ref[i]->name,
538 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
Michal Vaskof2d43962016-09-02 11:10:16 +0200539 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100540 asprintf(&s, "%s:%s", transform_module_name2import_prefix(module, mod->name),
541 type->info.ident.ref[i]->name);
542 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, s,
543 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
544 free(s);
Michal Vaskof2d43962016-09-02 11:10:16 +0200545 }
Michal Vasko4634cda2016-02-16 09:22:09 +0100546 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200547 }
548 break;
549 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200550 if (type->info.inst.req == 1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100551 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100552 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "true", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200553 } else if (type->info.inst.req == -1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100554 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100555 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "false", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200556 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200557 break;
558 case LY_TYPE_INT8:
559 case LY_TYPE_INT16:
560 case LY_TYPE_INT32:
561 case LY_TYPE_INT64:
562 case LY_TYPE_UINT8:
563 case LY_TYPE_UINT16:
564 case LY_TYPE_UINT32:
565 case LY_TYPE_UINT64:
Michal Vasko4634cda2016-02-16 09:22:09 +0100566 if (type->info.num.range) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100567 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100568 yang_print_restr(out, level, module, type->info.num.range, "range", type->info.num.range->expr);
Radek Krejcif2860132015-06-20 12:37:20 +0200569 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200570 break;
571 case LY_TYPE_LEAFREF:
Radek Krejci0dbff6a2016-07-17 12:40:18 +0200572 if (ly_strequal(type->der->name, "leafref", 0)) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100573 yang_print_open(out, &flag);
574 str = transform_json2schema(module, type->info.lref.path);
Radek Krejci43e3c312017-01-11 11:34:44 +0100575 yang_print_substmt(out, level, LYEXT_SUBSTMT_PATH, 0, str, module, type->ext, type->ext_size);
Michal Vasko4634cda2016-02-16 09:22:09 +0100576 lydict_remove(module->ctx, str);
577 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100578 if (type->info.lref.req == 1) {
579 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100580 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "true", module, type->ext, type->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100581 } else if (type->info.lref.req == -1) {
582 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100583 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "false", module, type->ext, type->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100584 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200585 break;
586 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200587 if (type->info.str.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100588 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100589 yang_print_restr(out, level, module, type->info.str.length, "length", type->info.str.length->expr);
Radek Krejci061bd522015-06-19 13:45:16 +0200590 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200591 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100592 yang_print_open(out, &flag);
Radek Krejciaa9c5202017-02-15 16:10:14 +0100593 yang_print_restr(out, level, module, &type->info.str.patterns[i],
594 "pattern", &type->info.str.patterns[i].expr[1]);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200595 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200596 break;
597 case LY_TYPE_UNION:
598 for (i = 0; i < type->info.uni.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100599 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200600 yang_print_type(out, level, module, &type->info.uni.types[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200601 }
602 break;
603 default:
604 /* other types do not have substatements */
605 break;
606 }
Radek Krejcie534c132016-11-23 13:32:31 +0100607
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200608 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100609 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200610}
611
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200612static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100613yang_print_must(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200614{
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100615 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200616
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100617 str = transform_json2schema(module, must->expr);
618 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200619 ly_print(out, "(!error!)");
620 return;
621 }
Radek Krejciaa9c5202017-02-15 16:10:14 +0100622 yang_print_restr(out, level, module, must, "must", str);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100623 lydict_remove(module->ctx, str);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200624}
625
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200626static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100627yang_print_unique(struct lyout *out, int level, const struct lys_unique *uniq)
Michal Vasko1ef07972015-07-07 14:01:35 +0200628{
629 int i;
630
Radek Krejci76b07902015-10-09 09:11:25 +0200631 ly_print(out, "%*sunique \"", LEVEL, INDENT);
Radek Krejci581ce772015-11-10 17:22:40 +0100632 for (i = 0; i < uniq->expr_size; i++) {
633 ly_print(out, "%s%s", uniq->expr[i], i + 1 < uniq->expr_size ? " " : "");
Michal Vasko1ef07972015-07-07 14:01:35 +0200634 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100635 ly_print(out, "\"");
Michal Vasko1ef07972015-07-07 14:01:35 +0200636}
637
638static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100639yang_print_refine(struct lyout *out, int level, const struct lys_module *module, const struct lys_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200640{
Radek Krejci5dd25122017-01-11 17:28:13 +0100641 int i, flag = 0;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200642 const char *str;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200643
Michal Vasko5d112852016-02-12 16:47:13 +0100644 str = transform_json2schema(module, refine->target_name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100645 ly_print(out, "%*srefine \"%s\"", LEVEL, INDENT, str);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200646 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200647 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200648
Radek Krejci5dd25122017-01-11 17:28:13 +0100649 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 +0200650 for (i = 0; i < refine->must_size; ++i) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100651 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200652 yang_print_must(out, level, module, &refine->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200653 }
Pavol Vican3e7c73a2016-08-17 10:24:11 +0200654 if (refine->target_type == LYS_CONTAINER) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100655 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100656 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, refine->mod.presence,
657 module, refine->ext, refine->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100658 }
659 for (i = 0; i < refine->dflt_size; ++i) {
660 yang_print_open(out, &flag);
661 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, refine->dflt[i], module, refine->ext, refine->ext_size);
662 }
663 if (refine->flags & LYS_CONFIG_W) {
664 yang_print_open(out, &flag);
665 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module, refine->ext, refine->ext_size);
666 } else if (refine->flags & LYS_CONFIG_R) {
667 yang_print_open(out, &flag);
668 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module, refine->ext, refine->ext_size);
669 }
670 if (refine->flags & LYS_MAND_TRUE) {
671 yang_print_open(out, &flag);
672 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module, refine->ext, refine->ext_size);
673 } else if (refine->flags & LYS_MAND_FALSE) {
674 yang_print_open(out, &flag);
675 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module, refine->ext, refine->ext_size);
676 }
677 if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200678 if (refine->flags & LYS_RFN_MINSET) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100679 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100680 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, module, refine->ext, refine->ext_size,
681 refine->mod.list.min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200682 }
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200683 if (refine->flags & LYS_RFN_MAXSET) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100684 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100685 if (refine->mod.list.max) {
686 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, module, refine->ext, refine->ext_size,
687 refine->mod.list.max);
688 } else {
689 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, "unbounded", module, refine->ext, refine->ext_size);
690 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200691 }
692 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100693 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 +0200694
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200695 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +0100696 yang_print_close(out, level, flag);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200697}
698
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200699static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100700yang_print_deviation(struct lyout *out, int level, const struct lys_module *module,
701 const struct lys_deviation *deviation)
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200702{
Radek Krejci033983b2017-01-13 12:43:20 +0100703 int i, j, p;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200704 const char *str;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200705
Michal Vasko5d112852016-02-12 16:47:13 +0100706 str = transform_json2schema(module, deviation->target_name);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200707 ly_print(out, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, str);
708 lydict_remove(module->ctx, str);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200709 level++;
710
Radek Krejci5dd25122017-01-11 17:28:13 +0100711 if (deviation->ext_size) {
712 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, deviation->ext, deviation->ext_size);
713 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100714 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, deviation->dsc,
715 module, deviation->ext, deviation->ext_size);
716 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, deviation->ref,
717 module, deviation->ext, deviation->ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200718
719 for (i = 0; i < deviation->deviate_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200720 ly_print(out, "%*sdeviate ", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200721 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100722 if (deviation->deviate[i].ext_size) {
723 ly_print(out, "not-supported {\n");
724 } else {
725 ly_print(out, "not-supported;\n");
726 continue;
727 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200728 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
Radek Krejci76b07902015-10-09 09:11:25 +0200729 ly_print(out, "add {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200730 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200731 ly_print(out, "replace {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200732 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200733 ly_print(out, "delete {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200734 }
735 level++;
736
Radek Krejci5dd25122017-01-11 17:28:13 +0100737 /* extensions */
738 if (deviation->deviate[i].ext_size) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100739 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
Radek Krejci5dd25122017-01-11 17:28:13 +0100740 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200741 }
742
Radek Krejci5dd25122017-01-11 17:28:13 +0100743 /* type */
744 if (deviation->deviate[i].type) {
745 yang_print_type(out, level, module, deviation->deviate[i].type);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200746 }
747
Radek Krejci5dd25122017-01-11 17:28:13 +0100748 /* units */
749 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, deviation->deviate[i].units, module,
750 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200751
Radek Krejci5dd25122017-01-11 17:28:13 +0100752 /* must */
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200753 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
Michal Vaskof9893382015-10-09 14:03:04 +0200754 yang_print_must(out, level, module, &deviation->deviate[i].must[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200755 }
756
Radek Krejci5dd25122017-01-11 17:28:13 +0100757 /* unique */
758
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200759 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
Radek Krejci76b07902015-10-09 09:11:25 +0200760 yang_print_unique(out, level, &deviation->deviate[i].unique[j]);
Radek Krejci43e3c312017-01-11 11:34:44 +0100761 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +0100762 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100763 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100764 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejcicfce0292017-01-13 12:37:57 +0100765 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100766 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100767 if (p != -1) {
768 ly_print(out, " {\n");
769 do {
770 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, j,
771 &deviation->deviate[i].ext[p], 1);
772 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100773 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejci43e3c312017-01-11 11:34:44 +0100774 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100775 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100776 } while (p != -1);
777 ly_print(out, "%*s}\n", LEVEL, INDENT);
778 } else {
779 ly_print(out, ";\n");
780 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200781 }
782
Radek Krejci5dd25122017-01-11 17:28:13 +0100783 /* default */
Radek Krejci033983b2017-01-13 12:43:20 +0100784 for (j = 0; j < deviation->deviate[i].dflt_size; ++j) {
785 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, j, deviation->deviate[i].dflt[j], module,
Radek Krejci5dd25122017-01-11 17:28:13 +0100786 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200787 }
788
Radek Krejci5dd25122017-01-11 17:28:13 +0100789 /* config */
790 if (deviation->deviate[i].flags & LYS_CONFIG_W) {
791 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module,
792 deviation->deviate->ext, deviation->deviate[i].ext_size);
793 } else if (deviation->deviate[i].flags & LYS_CONFIG_R) {
794 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module,
795 deviation->deviate->ext, deviation->deviate[i].ext_size);
796 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100797
Radek Krejci5dd25122017-01-11 17:28:13 +0100798 /* mandatory */
799 if (deviation->deviate[i].flags & LYS_MAND_TRUE) {
800 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module,
801 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
802 } else if (deviation->deviate[i].flags & LYS_MAND_FALSE) {
803 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module,
804 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
805 }
806
807 /* min-elements */
808 if (deviation->deviate[i].min_set) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100809 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, module,
810 deviation->deviate[i].ext, deviation->deviate[i].ext_size,
811 deviation->deviate[i].min);
Radek Krejci5dd25122017-01-11 17:28:13 +0100812 }
813
814 /* max-elements */
815 if (deviation->deviate[i].max_set) {
816 if (deviation->deviate[i].max) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100817 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, module,
818 deviation->deviate[i].ext, deviation->deviate[i].ext_size,
819 deviation->deviate[i].max);
Radek Krejci5dd25122017-01-11 17:28:13 +0100820 } else {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100821 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, "unbounded", module,
822 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100823 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200824 }
825
826 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200827 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200828 }
829
830 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200831 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200832}
833
834static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100835yang_print_augment(struct lyout *out, int level, const struct lys_node_augment *augment)
Michal Vasko6f25f212015-07-07 15:42:07 +0200836{
Radek Krejci76512572015-08-04 09:47:08 +0200837 struct lys_node *sub;
Michal Vasko488c19e2015-10-20 15:21:00 +0200838 const char *str;
Michal Vasko6f25f212015-07-07 15:42:07 +0200839
Radek Krejci43e3c312017-01-11 11:34:44 +0100840 str = transform_json2schema(augment->module, augment->target_name);
Michal Vasko488c19e2015-10-20 15:21:00 +0200841 ly_print(out, "%*saugment \"%s\" {\n", LEVEL, INDENT, str);
Radek Krejci43e3c312017-01-11 11:34:44 +0100842 lydict_remove(augment->module->ctx, str);
Michal Vasko6f25f212015-07-07 15:42:07 +0200843 level++;
844
Radek Krejci5dd25122017-01-11 17:28:13 +0100845 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL, SNODE_COMMON_EXT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200846 if (augment->when) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100847 yang_print_when(out, level, augment->module, augment->when);
Michal Vasko6f25f212015-07-07 15:42:07 +0200848 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100849 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL,
850 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200851
852 LY_TREE_FOR(augment->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100853 /* only our augment */
854 if (sub->parent != (struct lys_node *)augment) {
855 continue;
856 }
Radek Krejci76b07902015-10-09 09:11:25 +0200857 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200858 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +0100859 LYS_USES | LYS_ANYDATA | LYS_CASE | LYS_ACTION | LYS_NOTIF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200860 }
861
862 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200863 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200864}
865
866static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100867yang_print_typedef(struct lyout *out, int level, const struct lys_module *module, const struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200868{
Radek Krejci033983b2017-01-13 12:43:20 +0100869 const char *dflt;
870
Radek Krejci76b07902015-10-09 09:11:25 +0200871 ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200872 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200873
Radek Krejci5dd25122017-01-11 17:28:13 +0100874 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL, SNODE_COMMON_EXT);
Radek Krejci76b07902015-10-09 09:11:25 +0200875 yang_print_type(out, level, module, &tpdf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200876 if (tpdf->units != NULL) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100877 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, module, tpdf->ext, tpdf->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200878 }
879 if (tpdf->dflt != NULL) {
Radek Krejcibd117f02016-11-04 16:28:08 +0100880 if (tpdf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +0100881 assert(strchr(tpdf->dflt, ':'));
882 if (!strncmp(tpdf->dflt, module->name, strchr(tpdf->dflt, ':') - tpdf->dflt)) {
883 /* local module */
884 dflt = lydict_insert(module->ctx, strchr(tpdf->dflt, ':') + 1, 0);
885 } else {
886 dflt = transform_json2schema(module, tpdf->dflt);
887 }
Radek Krejcibd117f02016-11-04 16:28:08 +0100888 } else {
889 dflt = tpdf->dflt;
890 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100891 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt, module, tpdf->ext, tpdf->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +0100892 if (tpdf->flags & LYS_DFLTJSON) {
893 lydict_remove(module->ctx, dflt);
894 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200895 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100896 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL,
897 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200898
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200899 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200900 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200901}
902
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200903static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100904yang_print_identity(struct lyout *out, int level, const struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200905{
Radek Krejci018f1f52016-08-03 16:01:20 +0200906 int flag = 0, i;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100907 struct lys_module *mod;
Radek Krejci43e3c312017-01-11 11:34:44 +0100908 char *str;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100909
910 ly_print(out, "%*sidentity %s", LEVEL, INDENT, ident->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200911 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200912
Radek Krejci5dd25122017-01-11 17:28:13 +0100913 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
914 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
915
Radek Krejci018f1f52016-08-03 16:01:20 +0200916 for (i = 0; i < ident->base_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100917 yang_print_open(out, &flag);
Radek Krejci018f1f52016-08-03 16:01:20 +0200918 mod = lys_main_module(ident->base[i]->module);
Radek Krejci43e3c312017-01-11 11:34:44 +0100919 if (lys_main_module(ident->module) == mod) {
Radek Krejcib5e58d32017-01-23 13:45:59 +0100920 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, ident->base[i]->name,
Radek Krejci43e3c312017-01-11 11:34:44 +0100921 ident->module, ident->ext, ident->ext_size);
922 } else {
923 asprintf(&str, "%s:%s", transform_module_name2import_prefix(ident->module, mod->name), ident->base[i]->name);
Radek Krejcib5e58d32017-01-23 13:45:59 +0100924 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, str,
Radek Krejci43e3c312017-01-11 11:34:44 +0100925 ident->module, ident->ext, ident->ext_size);
926 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200927 }
928 }
Radek Krejci6793db02015-05-22 17:49:54 +0200929
Radek Krejci5dd25122017-01-11 17:28:13 +0100930 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
931 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
932
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200933 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100934 yang_print_close(out, level, flag);
Radek Krejci6793db02015-05-22 17:49:54 +0200935}
936
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200937static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100938yang_print_container(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200939{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100940 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +0200941 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200942 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200943
Radek Krejci32cce7c2015-12-09 16:44:13 +0100944 ly_print(out, "%*scontainer %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200945 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200946
Radek Krejci5dd25122017-01-11 17:28:13 +0100947 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +0100948 if (cont->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100949 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +0100950 yang_print_when(out, level, node->module, cont->when);
951 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200952 for (i = 0; i < cont->iffeature_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +0100953 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +0200954 yang_print_iffeature(out, level, node->module, &cont->iffeature[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200955 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200956 for (i = 0; i < cont->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100957 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200958 yang_print_must(out, level, node->module, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200959 }
Radek Krejci8d81e002015-12-10 11:18:59 +0100960 if (cont->presence != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100961 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100962 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence,
963 node->module, node->ext, node->ext_size);
Michal Vasko4773b762015-07-07 12:15:10 +0200964 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100965 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG |
966 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200967 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100968 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200969 yang_print_typedef(out, level, node->module, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200970 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200971 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100972 /* augments */
973 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200974 continue;
975 }
Radek Krejci32cce7c2015-12-09 16:44:13 +0100976 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100977 yang_print_snode(out, level, sub, LYS_GROUPING);
978 }
979 LY_TREE_FOR(node->child, sub) {
980 /* augments */
981 if (sub->parent != node) {
982 continue;
983 }
984 yang_print_open(out, &flag);
985 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
986 LYS_USES | LYS_ANYDATA );
987 }
988 LY_TREE_FOR(node->child, sub) {
989 /* augments */
990 if (sub->parent != node) {
991 continue;
992 }
993 yang_print_open(out, &flag);
994 yang_print_snode(out, level, sub, LYS_ACTION);
995 }
996 LY_TREE_FOR(node->child, sub) {
997 /* augments */
998 if (sub->parent != node) {
999 continue;
1000 }
1001 yang_print_open(out, &flag);
Radek Krejci033983b2017-01-13 12:43:20 +01001002 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001003 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001004
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001005 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001006 yang_print_close(out, level, flag);
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001007}
1008
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001009static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001010yang_print_case(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001011{
Radek Krejci5dd25122017-01-11 17:28:13 +01001012 int flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001013 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001014 struct lys_node_case *cas = (struct lys_node_case *)node;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001015
Radek Krejci5dd25122017-01-11 17:28:13 +01001016 ly_print(out, "%*scase %s", LEVEL, INDENT, cas->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001017 level++;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001018
Radek Krejci5dd25122017-01-11 17:28:13 +01001019 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001020 if (cas->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001021 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001022 yang_print_when(out, level, node->module, cas->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001023 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001024 yang_print_snode_common(out, level, node, node->module, &flag,
1025 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001026
Radek Krejci1d82ef62015-08-07 14:44:40 +02001027 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001028 /* augments */
1029 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001030 continue;
1031 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001032 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001033 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001034 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejcibf2abff2016-08-23 15:51:52 +02001035 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001036 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001037
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001038 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001039 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001040}
1041
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001042static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001043yang_print_choice(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001044{
Radek Krejci5dd25122017-01-11 17:28:13 +01001045 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001046 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001047 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001048
Radek Krejci5dd25122017-01-11 17:28:13 +01001049 ly_print(out, "%*schoice %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001050 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001051
1052 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1053 if (choice->when) {
1054 yang_print_open(out, &flag);
1055 yang_print_when(out, level, node->module, choice->when);
1056 }
1057 for (i = 0; i < choice->iffeature_size; i++) {
1058 yang_print_open(out, &flag);
1059 yang_print_iffeature(out, level, node->module, &choice->iffeature[i]);
1060 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001061 if (choice->dflt != NULL) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001062 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001063 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt->name,
1064 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001065 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001066 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1067 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001068
Radek Krejci1d82ef62015-08-07 14:44:40 +02001069 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001070 /* augments */
1071 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001072 continue;
1073 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001074 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001075 yang_print_snode(out, level, sub,
Radek Krejci5dd25122017-01-11 17:28:13 +01001076 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_CASE);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001077 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001078
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001079 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001080 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001081}
1082
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001083static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001084yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001085{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001086 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001087 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001088 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001089
Radek Krejci76b07902015-10-09 09:11:25 +02001090 ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001091 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001092
1093 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001094 if (leaf->when) {
1095 yang_print_when(out, level, node->module, leaf->when);
1096 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001097 for (i = 0; i < leaf->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001098 yang_print_iffeature(out, level, node->module, &leaf->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001099 }
Radek Krejci76b07902015-10-09 09:11:25 +02001100 yang_print_type(out, level, node->module, &leaf->type);
Radek Krejci43e3c312017-01-11 11:34:44 +01001101 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, leaf->units,
1102 node->module, node->ext, node->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +01001103 for (i = 0; i < leaf->must_size; i++) {
1104 yang_print_must(out, level, node->module, &leaf->must[i]);
1105 }
Michal Vaskod875e882016-05-19 10:57:30 +02001106 if (leaf->dflt) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001107 if (leaf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001108 assert(strchr(leaf->dflt, ':'));
1109 if (!strncmp(leaf->dflt, lys_node_module(node)->name, strchr(leaf->dflt, ':') - leaf->dflt)) {
1110 /* local module */
1111 dflt = lydict_insert(node->module->ctx, strchr(leaf->dflt, ':') + 1, 0);
1112 } else {
1113 dflt = transform_json2schema(node->module, leaf->dflt);
1114 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001115 } else {
1116 dflt = leaf->dflt;
1117 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001118 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt,
1119 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001120 if (leaf->flags & LYS_DFLTJSON) {
1121 lydict_remove(node->module->ctx, dflt);
1122 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001123 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001124 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1125 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001126 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001127 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +02001128}
1129
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001130static void
Radek Krejcibf2abff2016-08-23 15:51:52 +02001131yang_print_anydata(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko16083662015-06-09 14:00:45 +02001132{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001133 int i, flag = 0;
Radek Krejcibf2abff2016-08-23 15:51:52 +02001134 struct lys_node_anydata *any = (struct lys_node_anydata *)node;
Michal Vasko16083662015-06-09 14:00:45 +02001135
Radek Krejcibf2abff2016-08-23 15:51:52 +02001136 ly_print(out, "%*s%s %s", LEVEL, INDENT, any->nodetype == LYS_ANYXML ? "anyxml" : "anydata", any->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001137 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001138
1139 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1140 if (any->when) {
1141 yang_print_open(out, &flag);
1142 yang_print_when(out, level, node->module, any->when);
1143 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001144 for (i = 0; i < any->iffeature_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001145 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001146 yang_print_iffeature(out, level, node->module, &any->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001147 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001148 for (i = 0; i < any->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001149 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001150 yang_print_must(out, level, node->module, &any->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001151 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001152 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1153 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001154 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001155 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001156}
1157
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001158static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001159yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001160{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001161 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001162 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001163 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001164
Radek Krejci76b07902015-10-09 09:11:25 +02001165 ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001166 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001167 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001168 if (llist->when) {
1169 yang_print_when(out, level, llist->module, llist->when);
1170 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001171 for (i = 0; i < llist->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001172 yang_print_iffeature(out, level, node->module, &llist->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001173 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001174 yang_print_type(out, level, node->module, &llist->type);
1175 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, llist->units,
1176 node->module, node->ext, node->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001177 for (i = 0; i < llist->must_size; i++) {
1178 yang_print_must(out, level, node->module, &llist->must[i]);
1179 }
Pavol Vican38321d02016-08-16 14:56:02 +02001180 for (i = 0; i < llist->dflt_size; ++i) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001181 if (llist->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001182 assert(strchr(llist->dflt[i], ':'));
1183 if (!strncmp(llist->dflt[i], lys_node_module(node)->name, strchr(llist->dflt[i], ':') - llist->dflt[i])) {
1184 /* local module */
1185 dflt = lydict_insert(node->module->ctx, strchr(llist->dflt[i], ':') + 1, 0);
1186 } else {
1187 dflt = transform_json2schema(node->module, llist->dflt[i]);
1188 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001189 } else {
1190 dflt = llist->dflt[i];
1191 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001192 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, dflt,
1193 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001194 if (llist->flags & LYS_DFLTJSON) {
1195 lydict_remove(node->module->ctx, dflt);
1196 }
Pavol Vican38321d02016-08-16 14:56:02 +02001197 }
Radek Krejci178a0942017-01-16 15:36:35 +01001198 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001199 if (llist->min > 0) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001200 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, node->module, node->ext, node->ext_size, llist->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001201 }
1202 if (llist->max > 0) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001203 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, node->module, node->ext, node->ext_size, llist->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001204 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001205 if (llist->flags & LYS_USERORDERED) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001206 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1207 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001208 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001209 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1210 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001211 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001212 yang_print_snode_common(out, level, node, node->module, NULL,
1213 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001214 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001215 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001216}
1217
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001218static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001219yang_print_list(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001220{
Radek Krejci5dd25122017-01-11 17:28:13 +01001221 int i, p, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001222 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001223 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001224
Radek Krejci5dd25122017-01-11 17:28:13 +01001225 ly_print(out, "%*slist %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001226 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001227 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001228 if (list->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001229 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001230 yang_print_when(out, level, list->module, list->when);
1231 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001232 for (i = 0; i < list->iffeature_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001233 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001234 yang_print_iffeature(out, level, node->module, &list->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001235 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001236 for (i = 0; i < list->must_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001237 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001238 yang_print_must(out, level, list->module, &list->must[i]);
1239 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001240 if (list->keys_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001241 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001242 yang_print_substmt(out, level, LYEXT_SUBSTMT_KEY, 0, list->keys_str,
1243 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001244 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001245 for (i = 0; i < list->unique_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001246 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001247 yang_print_unique(out, level, &list->unique[i]);
Radek Krejci43e3c312017-01-11 11:34:44 +01001248 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +01001249 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +01001250 do {
Radek Krejcibf285832017-01-26 16:05:41 +01001251 p = lys_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +01001252 } while (p != -1 && list->ext[p]->insubstmt_index != i);
Radek Krejci43e3c312017-01-11 11:34:44 +01001253 if (p != -1) {
1254 ly_print(out, " {\n");
1255 do {
1256 yang_print_extension_instances(out, level + 1, list->module, LYEXT_SUBSTMT_UNIQUE, i, &list->ext[p], 1);
1257 do {
Radek Krejcibf285832017-01-26 16:05:41 +01001258 p = lys_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +01001259 } while (p != -1 && list->ext[p]->insubstmt_index != i);
Radek Krejci43e3c312017-01-11 11:34:44 +01001260 } while (p != -1);
1261 ly_print(out, "%*s}\n", LEVEL, INDENT);
1262 } else {
1263 ly_print(out, ";\n");
1264 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001265 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001266 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001267 if (list->min > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001268 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001269 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, node->module, node->ext, node->ext_size, list->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001270 }
1271 if (list->max > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001272 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001273 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, node->module, node->ext, node->ext_size, list->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001274 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001275 if (list->flags & LYS_USERORDERED) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001276 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001277 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1278 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001279 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001280 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001281 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1282 node->module, node->ext, node->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001283 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001284 yang_print_snode_common(out, level, node, node->module, &flag,
1285 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001286 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001287 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001288 yang_print_typedef(out, level, list->module, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001289 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001290
Radek Krejci1d82ef62015-08-07 14:44:40 +02001291 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001292 /* augments */
1293 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001294 continue;
1295 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001296 yang_print_open(out, &flag);
1297 yang_print_snode(out, level, sub, LYS_GROUPING);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001298 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001299
1300 LY_TREE_FOR(node->child, sub) {
1301 /* augments */
1302 if (sub->parent != node) {
1303 continue;
1304 }
1305 yang_print_open(out, &flag);
1306 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1307 LYS_USES | LYS_GROUPING | LYS_ANYDATA);
1308 }
1309
1310 LY_TREE_FOR(node->child, sub) {
1311 /* augments */
1312 if (sub->parent != node) {
1313 continue;
1314 }
1315 yang_print_open(out, &flag);
1316 yang_print_snode(out, level, sub, LYS_ACTION);
1317 }
1318
1319 LY_TREE_FOR(node->child, sub) {
1320 /* augments */
1321 if (sub->parent != node) {
1322 continue;
1323 }
1324 yang_print_open(out, &flag);
1325 yang_print_snode(out, level, sub, LYS_NOTIF);
1326 }
1327
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001328 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001329 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001330}
1331
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001332static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001333yang_print_grouping(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001334{
Radek Krejci5dd25122017-01-11 17:28:13 +01001335 int i, flag = 0;
Michal Vasko0c5e9282016-02-15 13:11:57 +01001336 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001337 struct lys_node_grp *grp = (struct lys_node_grp *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001338
Radek Krejci5dd25122017-01-11 17:28:13 +01001339 ly_print(out, "%*sgrouping %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001340 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001341
Radek Krejci5dd25122017-01-11 17:28:13 +01001342 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_STATUS |
1343 SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001344
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001345 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001346 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001347 yang_print_typedef(out, level, node->module, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001348 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001349
Michal Vasko0c5e9282016-02-15 13:11:57 +01001350 LY_TREE_FOR(node->child, sub) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001351 yang_print_open(out, &flag);
1352 yang_print_snode(out, level, sub, LYS_GROUPING);
1353 }
1354
1355 LY_TREE_FOR(node->child, sub) {
1356 yang_print_open(out, &flag);
1357 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1358 LYS_USES | LYS_ANYDATA);
1359 }
1360
1361 LY_TREE_FOR(node->child, sub) {
1362 yang_print_open(out, &flag);
1363 yang_print_snode(out, level, sub, LYS_ACTION);
1364 }
1365
1366 LY_TREE_FOR(node->child, sub) {
1367 yang_print_open(out, &flag);
1368 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001369 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001370
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001371 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001372 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001373}
1374
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001375static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001376yang_print_uses(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001377{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001378 int i, flag = 0;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001379 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001380 struct lys_module *mod;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001381
Radek Krejci76b07902015-10-09 09:11:25 +02001382 ly_print(out, "%*suses ", LEVEL, INDENT);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001383 if (node->child) {
Michal Vasko6c629ac2016-02-15 14:08:23 +01001384 mod = lys_node_module(node->child);
Michal Vasko1dae8ec2016-02-15 14:49:01 +01001385 if (lys_node_module(node) != mod) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001386 ly_print(out, "%s:", transform_module_name2import_prefix(node->module, mod->name));
1387 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +02001388 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001389 ly_print(out, "%s", uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001390 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001391
Radek Krejci5dd25122017-01-11 17:28:13 +01001392 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001393 if (uses->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001394 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001395 yang_print_when(out, level, node->module, uses->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001396 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001397 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_IFF |
1398 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001399 for (i = 0; i < uses->refine_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001400 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001401 yang_print_refine(out, level, node->module, &uses->refine[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001402 }
Michal Vasko6f25f212015-07-07 15:42:07 +02001403 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001404 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001405 yang_print_augment(out, level, &uses->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001406 }
1407
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001408 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001409 yang_print_close(out, level, flag);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001410}
1411
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001412static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001413yang_print_input_output(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko5bbae102015-06-16 12:16:44 +02001414{
Michal Vaskof4d3d742015-06-16 11:51:09 +02001415 int i;
Radek Krejci76512572015-08-04 09:47:08 +02001416 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001417 struct lys_node_inout *inout = (struct lys_node_inout *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001418
Radek Krejci76b07902015-10-09 09:11:25 +02001419 ly_print(out, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LYS_INPUT ? "input" : "output"));
Michal Vaskof4d3d742015-06-16 11:51:09 +02001420 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001421
Radek Krejcie534c132016-11-23 13:32:31 +01001422 if (node->ext_size) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001423 yang_print_extension_instances(out, level, node->module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001424 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001425 for (i = 0; i < inout->must_size; i++) {
1426 yang_print_must(out, level, node->module, &inout->must[i]);
1427 }
Radek Krejcie534c132016-11-23 13:32:31 +01001428 for (i = 0; i < inout->tpdf_size; i++) {
1429 yang_print_typedef(out, level, node->module, &inout->tpdf[i]);
1430 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001431 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001432 /* augments */
1433 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001434 continue;
1435 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001436 yang_print_snode(out, level, sub, LYS_GROUPING);
1437 }
1438 LY_TREE_FOR(node->child, sub) {
1439 /* augments */
1440 if (sub->parent != node) {
1441 continue;
1442 }
1443 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1444 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001445 }
1446
1447 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001448 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001449}
1450
1451static void
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001452yang_print_rpc_action(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskof4d3d742015-06-16 11:51:09 +02001453{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001454 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001455 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001456 struct lys_node_rpc_action *rpc = (struct lys_node_rpc_action *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001457
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001458 ly_print(out, "%*s%s %s", LEVEL, INDENT, (node->nodetype == LYS_RPC ? "rpc" : "action"), node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001459
1460 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001461 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF |
1462 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko4773b762015-07-07 12:15:10 +02001463
Michal Vaskof4d3d742015-06-16 11:51:09 +02001464 for (i = 0; i < rpc->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001465 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001466 yang_print_typedef(out, level, node->module, &rpc->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001467 }
1468
Radek Krejci1d82ef62015-08-07 14:44:40 +02001469 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001470 /* augments */
1471 if (sub->parent != node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001472 continue;
1473 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001474 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +01001475 yang_print_snode(out, level, sub, LYS_GROUPING);
1476 }
1477
1478 LY_TREE_FOR(node->child, sub) {
1479 /* augments */
1480 if (sub->parent != node) {
1481 continue;
1482 }
1483 yang_print_open(out, &flag);
1484 yang_print_snode(out, level, sub, LYS_INPUT);
1485 }
1486
1487 LY_TREE_FOR(node->child, sub) {
Michal Vasko8b942f02017-01-24 13:12:59 +01001488 /* augments and implicit nodes */
1489 if ((sub->parent != node) || ((sub->nodetype & (LYS_INPUT | LYS_OUTPUT) && (sub->flags & LYS_IMPLICIT)))) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001490 continue;
1491 }
1492 yang_print_open(out, &flag);
1493 yang_print_snode(out, level, sub, LYS_OUTPUT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001494 }
1495
1496 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001497 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001498}
1499
1500static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001501yang_print_notif(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko7690bc12015-06-16 12:26:05 +02001502{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001503 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001504 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001505 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001506
Radek Krejci32cce7c2015-12-09 16:44:13 +01001507 ly_print(out, "%*snotification %s", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001508
1509 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001510 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Radek Krejci12032a52016-07-29 15:42:56 +02001511 for (i = 0; i < notif->must_size; i++) {
1512 yang_print_open(out, &flag);
1513 yang_print_must(out, level, node->module, &notif->must[i]);
1514 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001515 yang_print_snode_common(out, level, node, node->module, &flag,
1516 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
1517 for (i = 0; i < notif->tpdf_size; i++) {
1518 yang_print_open(out, &flag);
1519 yang_print_typedef(out, level, node->module, &notif->tpdf[i]);
1520 }
1521 LY_TREE_FOR(node->child, sub) {
1522 /* augments */
1523 if (sub->parent != node) {
1524 continue;
1525 }
1526 yang_print_open(out, &flag);
1527 yang_print_snode(out, level, sub, LYS_GROUPING);
1528 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001529 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001530 /* augments */
1531 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001532 continue;
1533 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001534 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001535 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001536 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +01001537 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001538 }
1539
1540 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001541 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001542}
1543
1544static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001545yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001546{
Radek Krejci2c99a622017-01-12 10:11:13 +01001547 if (node->nodetype & mask) {
1548 if ((node->nodetype & (LYS_INPUT | LYS_OUTPUT)) && (node->flags & LYS_IMPLICIT)) {
1549 /* implicit input/output node is not supposed to be printed */
1550 return;
1551 } else if (!node->parent ||
1552 (node->parent->nodetype == LYS_AUGMENT && node != node->parent->child) ||
1553 (node->parent->nodetype != LYS_AUGMENT && node->prev->next)) {
1554 /* do not print the blank line before the first data-def node */
1555 ly_print(out, "\n");
1556 }
1557 }
1558
Radek Krejci1d82ef62015-08-07 14:44:40 +02001559 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +02001560 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +02001561 yang_print_container(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001562 break;
Radek Krejci76512572015-08-04 09:47:08 +02001563 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +02001564 yang_print_choice(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001565 break;
Radek Krejci76512572015-08-04 09:47:08 +02001566 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +02001567 yang_print_leaf(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001568 break;
Radek Krejci76512572015-08-04 09:47:08 +02001569 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001570 yang_print_leaflist(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001571 break;
Radek Krejci76512572015-08-04 09:47:08 +02001572 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001573 yang_print_list(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001574 break;
Radek Krejci76512572015-08-04 09:47:08 +02001575 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +02001576 yang_print_uses(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001577 break;
Radek Krejci76512572015-08-04 09:47:08 +02001578 case LYS_GROUPING:
Radek Krejci76b07902015-10-09 09:11:25 +02001579 yang_print_grouping(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001580 break;
Radek Krejci76512572015-08-04 09:47:08 +02001581 case LYS_ANYXML:
Radek Krejcibf2abff2016-08-23 15:51:52 +02001582 case LYS_ANYDATA:
1583 yang_print_anydata(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001584 break;
Radek Krejci76512572015-08-04 09:47:08 +02001585 case LYS_CASE:
Radek Krejci76b07902015-10-09 09:11:25 +02001586 yang_print_case(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001587 break;
Radek Krejci5dd25122017-01-11 17:28:13 +01001588 case LYS_RPC:
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001589 case LYS_ACTION:
1590 yang_print_rpc_action(out, level, node);
1591 break;
Radek Krejci76512572015-08-04 09:47:08 +02001592 case LYS_INPUT:
1593 case LYS_OUTPUT:
Radek Krejci2c99a622017-01-12 10:11:13 +01001594 yang_print_input_output(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001595 break;
Michal Vaskob15cae22016-09-15 09:40:56 +02001596 case LYS_NOTIF:
1597 yang_print_notif(out, level, node);
1598 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001599 default:
1600 break;
1601 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001602}
1603
Radek Krejci7417a082017-02-16 11:07:59 +01001604static void
1605yang_print_revision(struct lyout *out, int level, const struct lys_module *module, const struct lys_revision *rev)
1606{
1607 if (rev->dsc || rev->ref || rev->ext_size) {
1608 ly_print(out, "%*srevision \"%s\" {\n", LEVEL, INDENT, rev->date);
1609 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0, rev->ext, rev->ext_size);
1610 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_DESCRIPTION, 0, rev->dsc, module, rev->ext, rev->ext_size);
1611 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_REFERENCE, 0, rev->ref, module, rev->ext, rev->ext_size);
1612 ly_print(out, "%*s}\n", LEVEL, INDENT);
1613 } else {
1614 ly_print(out, "%*srevision %s;\n", LEVEL, INDENT, rev->date);
1615 }
1616}
1617
Radek Krejci37f9ba32017-02-10 16:50:35 +01001618static int
1619yang_print_model_(struct lyout *out, int level, const struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001620{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001621 unsigned int i;
Radek Krejci37f9ba32017-02-10 16:50:35 +01001622 int p;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001623
Radek Krejci1d82ef62015-08-07 14:44:40 +02001624 struct lys_node *node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001625
Radek Krejci8d81e002015-12-10 11:18:59 +01001626 /* (sub)module-header-stmts */
Michal Vasko116172e2015-07-07 11:54:37 +02001627 if (module->type) {
Radek Krejci37f9ba32017-02-10 16:50:35 +01001628 ly_print(out, "%*ssubmodule %s {%s\n", LEVEL, INDENT, module->name,
1629 (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001630 level++;
Radek Krejci77424f72017-01-20 13:21:09 +01001631 if (lys_main_module(module)->version > 1 ||
Radek Krejcibf285832017-01-26 16:05:41 +01001632 lys_ext_iter(module->ext, module->ext_size, 0, LYEXT_SUBSTMT_VERSION) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001633 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0,
1634 ((struct lys_submodule *)module)->belongsto->version == 2 ? "1.1" : "1",
1635 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001636 }
Radek Krejci76b07902015-10-09 09:11:25 +02001637 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Radek Krejcicfce0292017-01-13 12:37:57 +01001638 p = -1;
Radek Krejcibf285832017-01-26 16:05:41 +01001639 while ((p = lys_ext_iter(module->ext, module->ext_size, p + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001640 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0, &module->ext[p], 1);
1641 }
1642 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1643 module, module->ext, module->ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001644 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001645 } else {
Radek Krejci37f9ba32017-02-10 16:50:35 +01001646 ly_print(out, "%*smodule %s {%s\n", LEVEL, INDENT, module->name,
1647 (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001648 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001649 if (module->version) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001650 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == 2 ? "1.1" : "1",
1651 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001652 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001653 yang_print_substmt(out, level, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns,
1654 module, module->ext, module->ext_size);
1655 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1656 module, module->ext, module->ext_size);
Michal Vasko116172e2015-07-07 11:54:37 +02001657 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001658
Radek Krejci8d81e002015-12-10 11:18:59 +01001659 /* linkage-stmts */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001660 for (i = 0; i < module->imp_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001661 ly_print(out, "\n%*simport %s {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001662 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001663 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1664 module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci39228d22017-01-13 12:43:55 +01001665 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->imp[i].prefix,
1666 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001667 if (module->imp[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001668 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->imp[i].rev,
1669 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001670 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001671 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->imp[i].dsc,
1672 module, module->imp[i].ext, module->imp[i].ext_size);
1673 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->imp[i].ref,
1674 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001675 level--;
Michal Vaskoc8e3ce02016-02-12 14:28:35 +01001676 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001677 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001678 for (i = 0; i < module->inc_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001679 if (module->inc[i].rev[0] || module->inc[i].dsc || module->inc[i].ref || module->inc[i].ext_size) {
1680 ly_print(out, "\n%*sinclude %s {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci8d81e002015-12-10 11:18:59 +01001681 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001682 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1683 module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001684 if (module->inc[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001685 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->inc[i].rev,
1686 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001687 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001688 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->inc[i].dsc,
1689 module, module->inc[i].ext, module->inc[i].ext_size);
1690 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->inc[i].ref,
1691 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001692 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001693 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001694 } else {
Radek Krejcie534c132016-11-23 13:32:31 +01001695 ly_print(out, "\n%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001696 }
1697 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001698
Radek Krejci8d81e002015-12-10 11:18:59 +01001699 /* meta-stmts */
1700 if (module->org || module->contact || module->dsc || module->ref) {
1701 ly_print(out, "\n");
1702 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001703 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org,
1704 module, module->ext, module->ext_size);
1705 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONTACT, 0, module->contact,
1706 module, module->ext, module->ext_size);
1707 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc,
1708 module, module->ext, module->ext_size);
1709 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->ref,
1710 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001711
1712 /* revision-stmts */
1713 if (module->rev_size) {
1714 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001715 }
1716 for (i = 0; i < module->rev_size; i++) {
Radek Krejci7417a082017-02-16 11:07:59 +01001717 yang_print_revision(out, level, module, &module->rev[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001718 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001719
Radek Krejci8d81e002015-12-10 11:18:59 +01001720 /* body-stmts */
Radek Krejcie534c132016-11-23 13:32:31 +01001721 for (i = 0; i < module->extensions_size; i++) {
1722 ly_print(out, "\n");
1723 yang_print_extension(out, level, &module->extensions[i]);
1724 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001725 if (module->ext_size) {
1726 ly_print(out, "\n");
1727 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, module->ext, module->ext_size);
1728 }
Radek Krejcie534c132016-11-23 13:32:31 +01001729
Michal Vasko30f6e912015-07-07 12:24:27 +02001730 for (i = 0; i < module->features_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001731 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001732 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001733 }
1734
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001735 for (i = 0; i < module->ident_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001736 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001737 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001738 }
Radek Krejci6793db02015-05-22 17:49:54 +02001739
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001740 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001741 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001742 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001743 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001744
Radek Krejci5dd25122017-01-11 17:28:13 +01001745 LY_TREE_FOR(lys_main_module(module)->data, node) {
1746 if (node->module != module) {
1747 /* data from submodules */
1748 continue;
1749 }
1750 yang_print_snode(out, level, node, LYS_GROUPING);
Radek Krejci8d81e002015-12-10 11:18:59 +01001751 }
1752
Radek Krejcic4283442016-04-22 09:19:27 +02001753 LY_TREE_FOR(lys_main_module(module)->data, node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001754 if (node->module != module) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001755 /* data from submodules */
Radek Krejcic071c542016-01-27 14:57:51 +01001756 continue;
1757 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001758 yang_print_snode(out, level, node, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1759 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001760 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001761
Michal Vasko6f25f212015-07-07 15:42:07 +02001762 for (i = 0; i < module->augment_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001763 ly_print(out, "\n");
Radek Krejci43e3c312017-01-11 11:34:44 +01001764 yang_print_augment(out, level, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001765 }
1766
Radek Krejci5dd25122017-01-11 17:28:13 +01001767 LY_TREE_FOR(lys_main_module(module)->data, node) {
1768 if (node->module != module) {
1769 /* data from submodules */
1770 continue;
1771 }
1772 yang_print_snode(out, level, node, LYS_RPC | LYS_ACTION);
1773 }
1774
1775 LY_TREE_FOR(lys_main_module(module)->data, node) {
1776 if (node->module != module) {
1777 /* data from submodules */
1778 continue;
1779 }
1780 yang_print_snode(out, level, node, LYS_NOTIF);
1781 }
1782
1783 for (i = 0; i < module->deviation_size; ++i) {
1784 ly_print(out, "\n");
1785 yang_print_deviation(out, level, module, &module->deviation[i]);
1786 }
1787
Radek Krejci37f9ba32017-02-10 16:50:35 +01001788 level--;
1789 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko95068c42016-03-24 14:58:11 +01001790 ly_print_flush(out);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001791
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001792 return EXIT_SUCCESS;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001793}
1794
Radek Krejci37f9ba32017-02-10 16:50:35 +01001795int
1796yang_print_model(struct lyout *out, const struct lys_module *module)
1797{
1798 return yang_print_model_(out, 0, module);
1799}
1800
Radek Krejci8d6b7422017-02-03 14:42:13 +01001801static void
Radek Krejcic1885952017-02-07 09:37:51 +01001802yang_print_extcomplex_bool(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001803 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001804 const char *true_val, const char *false_val, int *content)
1805{
1806 struct lyext_substmt *info;
1807 uint8_t *val;
1808
1809 val = lys_ext_complex_get_substmt(stmt, ext, &info);
1810 if (!val || !(*val)) {
1811 return;
1812 }
1813
1814 yang_print_open(out, content);
1815 if (*val == 1) {
Radek Krejcibe336392017-02-07 10:54:24 +01001816 yang_print_substmt(out, level, stmt, 0, true_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001817 } else if (*val == 2) {
Radek Krejcibe336392017-02-07 10:54:24 +01001818 yang_print_substmt(out, level, stmt, 0, false_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001819 } else {
1820 LOGINT;
1821 }
1822}
1823
1824static void
Radek Krejci8d6b7422017-02-03 14:42:13 +01001825yang_print_extcomplex_str(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001826 struct lys_ext_instance_complex *ext, LY_STMT stmt, int *content)
Radek Krejci8d6b7422017-02-03 14:42:13 +01001827{
1828 struct lyext_substmt *info;
1829 const char **str;
1830 int c;
1831
1832 str = lys_ext_complex_get_substmt(stmt, ext, &info);
1833 if (!str || !(*str)) {
1834 return;
1835 }
1836 if (info->cardinality >= LY_STMT_CARD_SOME) {
1837 /* we have array */
1838 for (str = (const char **)(*str), c = 0; *str; str++, c++) {
1839 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001840 yang_print_substmt(out, level, stmt, c, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001841 }
1842 } else {
1843 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001844 yang_print_substmt(out, level, stmt, 0, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001845 }
1846}
1847
Radek Krejcic1885952017-02-07 09:37:51 +01001848/* val1 is supposed to be the default value */
1849static void
1850yang_print_extcomplex_flags(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001851 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001852 const char *val1_str, const char *val2_str, uint16_t val1, uint16_t val2,
1853 int *content)
1854{
1855 const char *str;
1856 uint16_t *flags;
1857
1858 flags = lys_ext_complex_get_substmt(stmt, ext, NULL);
1859 if (!flags) {
1860 return;
1861 }
1862
1863 if (val1 & *flags) {
1864 str = val1_str;
1865 } else if (val2 & *flags) {
1866 str = val2_str;
Radek Krejcibe336392017-02-07 10:54:24 +01001867 } else if (lys_ext_iter(ext->ext, ext->ext_size, 0, stmt) != -1) {
Radek Krejcic1885952017-02-07 09:37:51 +01001868 /* flag not set, but since there are some extension, we are going to print the default value */
1869 str = val1_str;
1870 } else {
1871 return;
1872 }
1873
1874 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001875 yang_print_substmt(out, level, stmt, 0, str, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001876}
1877
Radek Krejci8d6b7422017-02-03 14:42:13 +01001878static void
1879yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
1880 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
1881 struct lys_ext_instance **ext, unsigned int count)
1882{
1883 unsigned int u, x;
1884 struct lys_module *mod;
1885 const char *prefix = NULL, *str;
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01001886 int content, content2, i, j, c;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001887 struct lyext_substmt *info;
1888 uint16_t *flags;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001889 void **pp, *p;
Radek Krejcif95b6292017-02-13 15:57:37 +01001890 struct lys_node *siter;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001891
Radek Krejcif95b6292017-02-13 15:57:37 +01001892#define YANG_PRINT_EXTCOMPLEX_SNODE(STMT) \
1893 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
1894 if (!pp || !(*pp)) { break; } \
1895 LY_TREE_FOR((struct lys_node*)(*pp), siter) { \
1896 if (lys_snode2stmt(siter->nodetype) == STMT) { \
1897 yang_print_open(out, &content); \
1898 yang_print_snode(out, level, siter, LYS_ANY); \
1899 } \
1900 }
Radek Krejci8d6b7422017-02-03 14:42:13 +01001901#define YANG_PRINT_EXTCOMPLEX_STRUCT(STMT, TYPE, FUNC) \
Radek Krejcifebdad72017-02-06 11:35:51 +01001902 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001903 if (!pp || !(*pp)) { break; } \
Radek Krejcifebdad72017-02-06 11:35:51 +01001904 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001905 for (pp = *pp; *pp; pp++) { \
1906 yang_print_open(out, &content); \
Radek Krejci37f9ba32017-02-10 16:50:35 +01001907 FUNC(out, level, (TYPE *)(*pp)); \
1908 } \
1909 } else { /* single item */ \
1910 yang_print_open(out, &content); \
1911 FUNC(out, level, (TYPE *)(*pp)); \
1912 }
Radek Krejciaa9c5202017-02-15 16:10:14 +01001913#define YANG_PRINT_EXTCOMPLEX_STRUCT_M(STMT, TYPE, FUNC, ARGS...) \
Radek Krejci37f9ba32017-02-10 16:50:35 +01001914 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
1915 if (!pp || !(*pp)) { break; } \
1916 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
1917 for (pp = *pp; *pp; pp++) { \
1918 yang_print_open(out, &content); \
Radek Krejciaa9c5202017-02-15 16:10:14 +01001919 FUNC(out, level, module, (TYPE *)(*pp), ##ARGS); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001920 } \
1921 } else { /* single item */ \
1922 yang_print_open(out, &content); \
Radek Krejciaa9c5202017-02-15 16:10:14 +01001923 FUNC(out, level, module, (TYPE *)(*pp), ##ARGS); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001924 }
PavolVican2ed9f4e2017-02-16 00:08:45 +01001925#define YANG_PRINT_EXTCOMPLEX_INT(STMT, TYPE, SIGN) \
Radek Krejci5496fae2017-02-10 13:26:48 +01001926 p = &((struct lys_ext_instance_complex*)ext[u])->content[info[i].offset]; \
Radek Krejci716cd7a2017-02-15 12:23:41 +01001927 if (!p || !*(TYPE**)p) { break; } \
Radek Krejci73250282017-02-17 10:48:00 +01001928 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* we have array */ \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001929 for (c = 0; (*(TYPE***)p)[c]; c++) { \
Radek Krejci5496fae2017-02-10 13:26:48 +01001930 yang_print_open(out, &content); \
PavolVican2ed9f4e2017-02-16 00:08:45 +01001931 yang_print_##SIGN(out, level, STMT, c, module, \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001932 ext[u]->ext, ext[u]->ext_size, *(*(TYPE***)p)[c]); \
Radek Krejci5496fae2017-02-10 13:26:48 +01001933 } \
Radek Krejci716cd7a2017-02-15 12:23:41 +01001934 } else { \
Radek Krejci5496fae2017-02-10 13:26:48 +01001935 yang_print_open(out, &content); \
PavolVican2ed9f4e2017-02-16 00:08:45 +01001936 yang_print_##SIGN(out, level, STMT, 0, module, \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001937 ext[u]->ext, ext[u]->ext_size, (**(TYPE**)p)); \
Radek Krejci5496fae2017-02-10 13:26:48 +01001938 }
Radek Krejci8d6b7422017-02-03 14:42:13 +01001939
1940 for (u = 0; u < count; u++) {
1941 if (ext[u]->flags & LYEXT_OPT_INHERIT) {
1942 /* ignore the inherited extensions which were not explicitely instantiated in the module */
1943 continue;
Radek Krejcifebdad72017-02-06 11:35:51 +01001944 } else if (ext[u]->insubstmt != substmt || ext[u]->insubstmt_index != substmt_index) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001945 /* do not print the other substatement than the required */
1946 continue;
1947 }
1948
1949 mod = lys_main_module(ext[u]->def->module);
1950 if (mod == lys_main_module(module)) {
1951 prefix = module->prefix;
1952 } else {
1953 for (x = 0; x < module->imp_size; x++) {
1954 if (mod == module->imp[x].module) {
1955 prefix = module->imp[x].prefix;
1956 break;
1957 }
1958 }
1959 }
1960
1961 content = 0;
1962 ly_print(out, "%*s%s:%s", LEVEL, INDENT, prefix, ext[u]->def->name);
1963 /* extension - generic part */
1964 if (ext[u]->arg_value) {
1965 ly_print(out, " \"%s\"", ext[u]->arg_value);
1966 }
1967
1968 /* extensions in extension instance */
1969 if (ext[u]->ext_size) {
1970 yang_print_open(out, &content);
1971 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1972 ext[u]->ext, ext[u]->ext_size);
1973 }
1974
1975 /* extension - type-specific part */
Radek Krejci8de8f612017-02-16 15:03:32 +01001976 switch(ext[u]->ext_type) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001977 case LYEXT_FLAG:
1978 /* flag extension - nothing special */
1979 break;
1980 case LYEXT_COMPLEX:
Radek Krejcifebdad72017-02-06 11:35:51 +01001981 info = ((struct lys_ext_instance_complex*)ext[u])->substmt; /* shortcut */
1982 if (!info) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001983 /* no content */
1984 break;
1985 }
1986 level++;
Radek Krejcifebdad72017-02-06 11:35:51 +01001987 for (i = 0; info[i].stmt; i++) {
1988 switch(info[i].stmt) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001989 case LY_STMT_DESCRIPTION:
Radek Krejci8d6b7422017-02-03 14:42:13 +01001990 case LY_STMT_REFERENCE:
Radek Krejci8d6b7422017-02-03 14:42:13 +01001991 case LY_STMT_UNITS:
Radek Krejcibe336392017-02-07 10:54:24 +01001992 case LY_STMT_ARGUMENT:
1993 case LY_STMT_DEFAULT:
1994 case LY_STMT_ERRTAG:
1995 case LY_STMT_ERRMSG:
1996 case LY_STMT_PREFIX:
1997 case LY_STMT_NAMESPACE:
1998 case LY_STMT_PRESENCE:
1999 case LY_STMT_REVISIONDATE:
2000 case LY_STMT_KEY:
2001 case LY_STMT_BASE:
Radek Krejcibe336392017-02-07 10:54:24 +01002002 case LY_STMT_CONTACT:
2003 case LY_STMT_ORGANIZATION:
2004 case LY_STMT_PATH:
Radek Krejci8d6b7422017-02-03 14:42:13 +01002005 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002006 info[i].stmt, &content);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002007 break;
Radek Krejci897d6072017-02-09 16:00:01 +01002008 case LY_STMT_BELONGSTO:
2009 pp = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, (struct lys_ext_instance_complex*)ext[u], NULL);
2010 if (!pp || !(*pp)) {
2011 break;
2012 }
2013 if (info->cardinality >= LY_STMT_CARD_SOME) {
2014 /* we have array */
2015 for (c = 0; ((const char***)pp)[0][c]; c++) {
2016 yang_print_open(out, &content);
2017 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((const char ***)pp)[0][c]);
2018 j = -1;
2019 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2020 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, c,
2021 &ext[u]->ext[j], 1);
2022 }
2023 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, c, ((const char ***)pp)[1][c],
2024 module, ext[u]->ext, ext[u]->ext_size);
2025 ly_print(out, "%*s}\n", LEVEL, INDENT);
2026 }
2027 } else {
2028 yang_print_open(out, &content);
2029 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, (const char *)pp[0]);
2030 j = -1;
2031 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2032 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0,
2033 &ext[u]->ext[j], 1);
2034 }
2035 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, (const char *)pp[1],
2036 module, ext[u]->ext, ext[u]->ext_size);
2037 ly_print(out, "%*s}\n", LEVEL, INDENT);
2038 }
2039 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002040 case LY_STMT_TYPE:
Radek Krejci37f9ba32017-02-10 16:50:35 +01002041 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_TYPE, struct lys_type, yang_print_type);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002042 break;
Radek Krejci63fc0962017-02-15 13:20:18 +01002043 case LY_STMT_TYPEDEF:
2044 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_TYPEDEF, struct lys_tpdf, yang_print_typedef);
2045 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002046 case LY_STMT_IFFEATURE:
Radek Krejci37f9ba32017-02-10 16:50:35 +01002047 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_IFFEATURE, struct lys_iffeature, yang_print_iffeature);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002048 break;
2049 case LY_STMT_STATUS:
Radek Krejcifebdad72017-02-06 11:35:51 +01002050 flags = lys_ext_complex_get_substmt(LY_STMT_STATUS, (struct lys_ext_instance_complex *)ext[u], NULL);
Radek Krejci2fd2a1f2017-02-13 11:06:04 +01002051 if (!flags || !(*flags)) {
2052 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002053 }
2054
2055 if (*flags & LYS_STATUS_CURR) {
2056 yang_print_open(out, &content);
2057 str = "current";
2058 } else if (*flags & LYS_STATUS_DEPRC) {
2059 yang_print_open(out, &content);
2060 str = "deprecated";
2061 } else if (*flags & LYS_STATUS_OBSLT) {
2062 yang_print_open(out, &content);
2063 str = "obsolete";
2064 }
2065 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, str, module, ext[u]->ext, ext[u]->ext_size);
Radek Krejcic3e36542017-02-08 16:19:23 +01002066 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002067 case LY_STMT_CONFIG:
2068 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002069 LY_STMT_CONFIG, "true", "false",
Radek Krejcic1885952017-02-07 09:37:51 +01002070 LYS_CONFIG_W | LYS_CONFIG_SET, LYS_CONFIG_R | LYS_CONFIG_SET, &content);
2071 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002072 case LY_STMT_MANDATORY:
2073 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002074 LY_STMT_MANDATORY, "false", "true", LYS_MAND_FALSE, LYS_MAND_TRUE,
2075 &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002076 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002077 case LY_STMT_ORDEREDBY:
2078 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002079 LY_STMT_ORDEREDBY, "system", "user", 0, LYS_USERORDERED, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002080 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002081 case LY_STMT_REQINSTANCE:
2082 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002083 info[i].stmt, "true", "false", &content);
Radek Krejcic1885952017-02-07 09:37:51 +01002084 break;
2085 case LY_STMT_MODIFIER:
2086 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002087 LY_STMT_MODIFIER, "invert-match", NULL, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002088 break;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002089 case LY_STMT_DIGITS:
Radek Krejcif8d05c22017-02-10 15:33:35 +01002090 p = &((struct lys_ext_instance_complex*)ext[u])->content[info[i].offset];
2091 if (!p) {
2092 break;
2093 }
Radek Krejci716cd7a2017-02-15 12:23:41 +01002094 if (info->cardinality >= LY_STMT_CARD_SOME && *(uint8_t**)p) { /* we have array */
Radek Krejcif8d05c22017-02-10 15:33:35 +01002095 for (c = 0; (*(uint8_t**)p)[c]; c++) {
2096 yang_print_open(out, &content);
2097 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, c, module,
2098 ext[u]->ext, ext[u]->ext_size, (*(uint8_t**)p)[c]);
2099 }
2100 } else if ((*(uint8_t*)p)) {
2101 yang_print_open(out, &content);
2102 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, 0, module,
2103 ext[u]->ext, ext[u]->ext_size, (*(uint8_t*)p));
2104 }
Radek Krejci5496fae2017-02-10 13:26:48 +01002105 break;
2106 case LY_STMT_MAX:
PavolVican2ed9f4e2017-02-16 00:08:45 +01002107 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MAX, uint32_t, unsigned);
Radek Krejci5496fae2017-02-10 13:26:48 +01002108 break;
2109 case LY_STMT_MIN:
PavolVican2ed9f4e2017-02-16 00:08:45 +01002110 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MIN, uint32_t, unsigned);
Radek Krejci5496fae2017-02-10 13:26:48 +01002111 break;
2112 case LY_STMT_POSITION:
PavolVican2ed9f4e2017-02-16 00:08:45 +01002113 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_POSITION, uint32_t, unsigned);
2114 break;
2115 case LY_STMT_VALUE:
2116 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_VALUE, int32_t, signed);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002117 break;
Radek Krejcic3f1b6f2017-02-15 10:51:10 +01002118 case LY_STMT_UNIQUE:
2119 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_UNIQUE, struct lys_unique, yang_print_unique);
2120
2121 pp = lys_ext_complex_get_substmt(LY_STMT_UNIQUE, (struct lys_ext_instance_complex *)ext[u], NULL);
2122 if (!pp || !(*pp)) {
2123 break;
2124 }
2125 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */
2126 for (pp = *pp, c = 0; *pp; pp++, c++) {
2127 yang_print_open(out, &content);
2128 yang_print_unique(out, level, (struct lys_unique*)(*pp));
2129 /* unique's extensions */
2130 j = -1; content2 = 0;
2131 do {
2132 j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE);
2133 } while (j != -1 && ext[u]->ext[j]->insubstmt_index != c);
2134 if (j != -1) {
2135 yang_print_open(out, &content);
2136 do {
2137 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, c,
2138 &ext[u]->ext[j], 1);
2139 do {
2140 j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE);
2141 } while (j != -1 && ext[u]->ext[j]->insubstmt_index != c);
2142 } while (j != -1);
2143 }
2144 yang_print_close(out, level, content2);
2145 }
2146 } else { /* single item */
2147 yang_print_open(out, &content);
2148 yang_print_unique(out, level, (struct lys_unique*)(*pp));
2149 /* unique's extensions */
2150 j = -1; content2 = 0;
2151 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
2152 yang_print_open(out, &content);
2153 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, 0,
2154 &ext[u]->ext[j], 1);
2155 }
2156 yang_print_close(out, level, content2);
2157 }
2158 break;
Radek Krejci37f9ba32017-02-10 16:50:35 +01002159 case LY_STMT_MODULE:
PavolVicand197fb12017-02-15 17:59:45 +01002160 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_MODULE, struct lys_module, yang_print_model_);
Radek Krejci37f9ba32017-02-10 16:50:35 +01002161 break;
Radek Krejcif95b6292017-02-13 15:57:37 +01002162 case LY_STMT_ACTION:
2163 case LY_STMT_ANYDATA:
2164 case LY_STMT_ANYXML:
2165 case LY_STMT_CASE:
2166 case LY_STMT_CHOICE:
2167 case LY_STMT_CONTAINER:
2168 case LY_STMT_GROUPING:
2169 case LY_STMT_INPUT:
2170 case LY_STMT_OUTPUT:
2171 case LY_STMT_LEAF:
2172 case LY_STMT_LEAFLIST:
2173 case LY_STMT_LIST:
2174 case LY_STMT_NOTIFICATION:
2175 case LY_STMT_USES:
2176 YANG_PRINT_EXTCOMPLEX_SNODE(info[i].stmt);
2177 break;
Radek Krejciaa9c5202017-02-15 16:10:14 +01002178 case LY_STMT_LENGTH:
2179 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_LENGTH, struct lys_restr, yang_print_restr,
2180 "length", ((struct lys_restr *)(*pp))->expr);
2181 break;
2182 case LY_STMT_MUST:
2183 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_MUST, struct lys_restr, yang_print_must);
2184 break;
2185 case LY_STMT_PATTERN:
2186 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_PATTERN, struct lys_restr, yang_print_restr,
2187 "pattern", &((struct lys_restr *)(*pp))->expr[1]);
2188 break;
2189 case LY_STMT_RANGE:
2190 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_RANGE, struct lys_restr, yang_print_restr,
2191 "range", ((struct lys_restr *)(*pp))->expr);
2192 break;
Radek Krejcic5cc5302017-02-16 10:07:46 +01002193 case LY_STMT_WHEN:
2194 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_WHEN, struct lys_when, yang_print_when);
2195 break;
Radek Krejci7417a082017-02-16 11:07:59 +01002196 case LY_STMT_REVISION:
2197 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_REVISION, struct lys_revision, yang_print_revision);
2198 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002199 default:
2200 /* TODO */
2201 break;
2202 }
2203 }
2204 level--;
2205 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002206 }
2207
2208 /* close extension */
2209 yang_print_close(out, level, content);
2210 }
2211#undef YANG_PRINT_EXTCOMPLEX_STRUCT
Radek Krejci37f9ba32017-02-10 16:50:35 +01002212#undef YANG_PRINT_EXTCOMPLEX_STRUCT_M
2213#undef YANG_PRINT_EXTCOMPLEX_INT
Radek Krejcida04f4a2015-05-21 12:54:09 +02002214}