blob: 26ab4562de0e57cca71b479f32b6d13f1199253f [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);
Radek Krejci9ff0a922016-07-14 13:08:05 +0200178 ly_print_iffeature(out, module, iffeature);
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 Krejci43e3c312017-01-11 11:34:44 +0100343yang_print_restr(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *restr, int *flag)
Radek Krejci41726f92015-06-19 13:11:05 +0200344{
Radek Krejci5dd25122017-01-11 17:28:13 +0100345 if (restr->ext_size) {
346 yang_print_open(out, flag);
347 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, restr->ext, restr->ext_size);
348 }
Radek Krejcidaa95c42017-01-16 10:25:29 +0100349 if (restr->expr[0] == 0x15) {
350 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
351 yang_print_open(out, flag);
352 yang_print_substmt(out, level, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match",
353 module, restr->ext, restr->ext_size);
354 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100355 if (restr->emsg != NULL) {
356 yang_print_open(out, flag);
357 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg,
358 module, restr->ext, restr->ext_size);
359 }
360 if (restr->eapptag != NULL) {
361 yang_print_open(out, flag);
362 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag,
363 module, restr->ext, restr->ext_size);
364 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200365 if (restr->dsc != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100366 yang_print_open(out, flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100367 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, restr->dsc,
368 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200369 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200370 if (restr->ref != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100371 yang_print_open(out, flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100372 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, restr->ref,
373 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200374 }
Radek Krejci41726f92015-06-19 13:11:05 +0200375}
376
377static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100378yang_print_when(struct lyout *out, int level, const struct lys_module *module, const struct lys_when *when)
Michal Vasko1f0428a2015-07-07 14:55:04 +0200379{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100380 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100381 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200382
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100383 str = transform_json2schema(module, when->cond);
384 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200385 ly_print(out, "(!error!)");
386 return;
387 }
388
Michal Vasko25cb6c62016-02-12 14:36:21 +0100389 ly_print(out, "%*swhen \"", LEVEL, INDENT);
390 yang_encode(out, str, -1);
391 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100392 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200393
Michal Vasko1f0428a2015-07-07 14:55:04 +0200394 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100395
Radek Krejci43e3c312017-01-11 11:34:44 +0100396 if (when->ext_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100397 /* 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 +0100398 yang_print_open(out, &flag);
399 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, when->ext, when->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200400 }
Radek Krejci11e88fd2017-01-16 15:34:37 +0100401 if (when->dsc != NULL) {
402 yang_print_open(out, &flag);
403 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, when->dsc,
404 module, when->ext, when->ext_size);
405 }
406 if (when->ref != NULL) {
407 yang_print_open(out, &flag);
408 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, when->ref,
409 module, when->ext, when->ext_size);
410 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100411
Michal Vasko1f0428a2015-07-07 14:55:04 +0200412 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100413 yang_print_close(out, level, flag);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200414}
415
416static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100417yang_print_type(struct lyout *out, int level, const struct lys_module *module, const struct lys_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200418{
Radek Krejci5dd25122017-01-11 17:28:13 +0100419 int i;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100420 int flag = 0, flag2;
Michal Vasko0fb82c62015-10-20 13:41:53 +0200421 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100422 char *s;
Radek Krejcic071c542016-01-27 14:57:51 +0100423 struct lys_module *mod;
Radek Krejci25d782a2015-05-22 15:03:23 +0200424
Michal Vasko0fb82c62015-10-20 13:41:53 +0200425 if (type->module_name) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100426 ly_print(out, "%*stype %s:%s", LEVEL, INDENT,
427 transform_module_name2import_prefix(module, type->module_name), type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200428 } else {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100429 ly_print(out, "%*stype %s", LEVEL, INDENT, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200430 }
431 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100432
433 /* extensions */
434 if (type->ext_size) {
435 yang_print_open(out, &flag);
436 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, type->ext, type->ext_size);
437 }
438
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200439 switch (type->base) {
440 case LY_TYPE_BINARY:
Michal Vasko4634cda2016-02-16 09:22:09 +0100441 if (type->info.binary.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100442 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100443 ly_print(out, "%*slength \"", LEVEL, INDENT);
444 yang_encode(out, type->info.binary.length->expr, -1);
445 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100446 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100447 yang_print_restr(out, level + 1, module, type->info.binary.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100448 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200449 }
450 break;
451 case LY_TYPE_BITS:
452 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100453 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100454 ly_print(out, "%*sbit %s", LEVEL, INDENT, type->info.bits.bit[i].name);
455 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200456 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100457 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
458 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100459 if (!(type->info.bits.bit[i].flags & LYS_AUTOASSIGNED)) {
460 yang_print_open(out, &flag2);
Radek Krejci43e3c312017-01-11 11:34:44 +0100461 asprintf(&s, "%u", type->info.bits.bit[i].pos);
462 yang_print_substmt(out, level, LYEXT_SUBSTMT_POSITION, 0, s,
463 module, type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size);
464 free(s);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100465 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100466 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
467 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200468 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100469 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200470 }
471 break;
472 case LY_TYPE_DEC64:
Radek Krejcib51d5932016-09-08 14:02:52 +0200473 if (!type->der->type.der) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100474 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100475 asprintf(&s, "%d", type->info.dec64.dig);
476 yang_print_substmt(out, level, LYEXT_SUBSTMT_DIGITS, 0, s, module, type->ext, type->ext_size);
477 free(s);
Michal Vasko4634cda2016-02-16 09:22:09 +0100478 }
Michal Vaskoea505ee2015-07-07 14:01:00 +0200479 if (type->info.dec64.range != NULL) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100480 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100481 ly_print(out, "%*srange \"", LEVEL, INDENT);
482 yang_encode(out, type->info.dec64.range->expr, -1);
483 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100484 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100485 yang_print_restr(out, level + 1, module, type->info.dec64.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100486 yang_print_close(out, level, flag2);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200487 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200488 break;
489 case LY_TYPE_ENUM:
490 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100491 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100492 ly_print(out, "%*senum \"%s\"", LEVEL, INDENT, type->info.enums.enm[i].name);
493 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200494 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100495 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
496 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100497 if (!(type->info.enums.enm[i].flags & LYS_AUTOASSIGNED)) {
498 yang_print_open(out, &flag2);
Radek Krejci43e3c312017-01-11 11:34:44 +0100499 asprintf(&s, "%d", type->info.enums.enm[i].value);
500 yang_print_substmt(out, level, LYEXT_SUBSTMT_VALUE, 0, s,
501 module, type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size);
502 free(s);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100503 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100504 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
505 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200506 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100507 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200508 }
509 break;
510 case LY_TYPE_IDENT:
Michal Vaskof2d43962016-09-02 11:10:16 +0200511 if (type->info.ident.count) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100512 yang_print_open(out, &flag);
Michal Vaskof2d43962016-09-02 11:10:16 +0200513 for (i = 0; i < type->info.ident.count; ++i) {
514 mod = lys_main_module(type->info.ident.ref[i]->module);
515 if (lys_main_module(module) == mod) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100516 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, type->info.ident.ref[i]->name,
517 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
Michal Vaskof2d43962016-09-02 11:10:16 +0200518 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100519 asprintf(&s, "%s:%s", transform_module_name2import_prefix(module, mod->name),
520 type->info.ident.ref[i]->name);
521 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, s,
522 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
523 free(s);
Michal Vaskof2d43962016-09-02 11:10:16 +0200524 }
Michal Vasko4634cda2016-02-16 09:22:09 +0100525 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200526 }
527 break;
528 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200529 if (type->info.inst.req == 1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100530 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100531 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "true", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200532 } else if (type->info.inst.req == -1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100533 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100534 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "false", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200535 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200536 break;
537 case LY_TYPE_INT8:
538 case LY_TYPE_INT16:
539 case LY_TYPE_INT32:
540 case LY_TYPE_INT64:
541 case LY_TYPE_UINT8:
542 case LY_TYPE_UINT16:
543 case LY_TYPE_UINT32:
544 case LY_TYPE_UINT64:
Michal Vasko4634cda2016-02-16 09:22:09 +0100545 if (type->info.num.range) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100546 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100547 ly_print(out, "%*srange \"", LEVEL, INDENT);
548 yang_encode(out, type->info.num.range->expr, -1);
549 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100550 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100551 yang_print_restr(out, level + 1, module, type->info.num.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100552 yang_print_close(out, level, flag2);
Radek Krejcif2860132015-06-20 12:37:20 +0200553 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200554 break;
555 case LY_TYPE_LEAFREF:
Radek Krejci0dbff6a2016-07-17 12:40:18 +0200556 if (ly_strequal(type->der->name, "leafref", 0)) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100557 yang_print_open(out, &flag);
558 str = transform_json2schema(module, type->info.lref.path);
Radek Krejci43e3c312017-01-11 11:34:44 +0100559 yang_print_substmt(out, level, LYEXT_SUBSTMT_PATH, 0, str, module, type->ext, type->ext_size);
Michal Vasko4634cda2016-02-16 09:22:09 +0100560 lydict_remove(module->ctx, str);
561 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100562 if (type->info.lref.req == 1) {
563 yang_print_open(out, &flag);
564 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "true", module, type->ext, type->ext_size);
565 } else if (type->info.lref.req == -1) {
566 yang_print_open(out, &flag);
567 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "false", module, type->ext, type->ext_size);
568 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200569 break;
570 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200571 if (type->info.str.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100572 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100573 ly_print(out, "%*slength \"", LEVEL, INDENT);
574 yang_encode(out, type->info.str.length->expr, -1);
575 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100576 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100577 yang_print_restr(out, level + 1, module, type->info.str.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100578 yang_print_close(out, level, flag2);
Radek Krejci061bd522015-06-19 13:45:16 +0200579 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200580 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100581 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100582 ly_print(out, "%*spattern \"", LEVEL, INDENT);
Radek Krejci0d23e7a2016-08-04 12:46:17 +0200583 yang_encode(out, &type->info.str.patterns[i].expr[1], -1);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100584 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100585 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100586 yang_print_restr(out, level + 1, module, &type->info.str.patterns[i], &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100587 yang_print_close(out, level, flag2);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200588 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200589 break;
590 case LY_TYPE_UNION:
591 for (i = 0; i < type->info.uni.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100592 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200593 yang_print_type(out, level, module, &type->info.uni.types[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200594 }
595 break;
596 default:
597 /* other types do not have substatements */
598 break;
599 }
Radek Krejcie534c132016-11-23 13:32:31 +0100600
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200601 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100602 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200603}
604
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200605static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100606yang_print_must(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200607{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100608 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100609 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200610
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100611 str = transform_json2schema(module, must->expr);
612 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200613 ly_print(out, "(!error!)");
614 return;
615 }
616
Michal Vasko25cb6c62016-02-12 14:36:21 +0100617 ly_print(out, "%*smust \"", LEVEL, INDENT);
618 yang_encode(out, str, -1);
619 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100620 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200621
Radek Krejci43e3c312017-01-11 11:34:44 +0100622 yang_print_restr(out, level + 1, module, must, &flag);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100623 yang_print_close(out, level, flag);
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;
Radek Krejci43e3c312017-01-11 11:34:44 +0100643 char *s;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200644
Michal Vasko5d112852016-02-12 16:47:13 +0100645 str = transform_json2schema(module, refine->target_name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100646 ly_print(out, "%*srefine \"%s\"", LEVEL, INDENT, str);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200647 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200648 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200649
Radek Krejci5dd25122017-01-11 17:28:13 +0100650 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 +0200651 for (i = 0; i < refine->must_size; ++i) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100652 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200653 yang_print_must(out, level, module, &refine->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200654 }
Pavol Vican3e7c73a2016-08-17 10:24:11 +0200655 if (refine->target_type == LYS_CONTAINER) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100656 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100657 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, refine->mod.presence,
658 module, refine->ext, refine->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100659 }
660 for (i = 0; i < refine->dflt_size; ++i) {
661 yang_print_open(out, &flag);
662 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, refine->dflt[i], module, refine->ext, refine->ext_size);
663 }
664 if (refine->flags & LYS_CONFIG_W) {
665 yang_print_open(out, &flag);
666 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module, refine->ext, refine->ext_size);
667 } else if (refine->flags & LYS_CONFIG_R) {
668 yang_print_open(out, &flag);
669 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module, refine->ext, refine->ext_size);
670 }
671 if (refine->flags & LYS_MAND_TRUE) {
672 yang_print_open(out, &flag);
673 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module, refine->ext, refine->ext_size);
674 } else if (refine->flags & LYS_MAND_FALSE) {
675 yang_print_open(out, &flag);
676 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module, refine->ext, refine->ext_size);
677 }
678 if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200679 if (refine->flags & LYS_RFN_MINSET) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100680 asprintf(&s, "%u", refine->mod.list.min);
Radek Krejci5dd25122017-01-11 17:28:13 +0100681 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100682 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, s, module, refine->ext, refine->ext_size);
683 free(s);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200684 }
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200685 if (refine->flags & LYS_RFN_MAXSET) {
Radek Krejci0d7b2472016-02-12 11:11:03 +0100686 if (refine->mod.list.max) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100687 asprintf(&s, "%u", refine->mod.list.max);
Radek Krejci0d7b2472016-02-12 11:11:03 +0100688 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100689 s = NULL;
Radek Krejci0d7b2472016-02-12 11:11:03 +0100690 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100691 yang_print_open(out, &flag);
Radek Krejci803c2fd2017-01-23 15:54:46 +0100692 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, s ? s : "unbounded", module, refine->ext, refine->ext_size);
Radek Krejci43e3c312017-01-11 11:34:44 +0100693 free(s);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200694 }
695 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100696 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 +0200697
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200698 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +0100699 yang_print_close(out, level, flag);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200700}
701
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200702static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100703yang_print_deviation(struct lyout *out, int level, const struct lys_module *module,
704 const struct lys_deviation *deviation)
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200705{
Radek Krejci033983b2017-01-13 12:43:20 +0100706 int i, j, p;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200707 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100708 char *s;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200709
Michal Vasko5d112852016-02-12 16:47:13 +0100710 str = transform_json2schema(module, deviation->target_name);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200711 ly_print(out, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, str);
712 lydict_remove(module->ctx, str);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200713 level++;
714
Radek Krejci5dd25122017-01-11 17:28:13 +0100715 if (deviation->ext_size) {
716 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, deviation->ext, deviation->ext_size);
717 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100718 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, deviation->dsc,
719 module, deviation->ext, deviation->ext_size);
720 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, deviation->ref,
721 module, deviation->ext, deviation->ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200722
723 for (i = 0; i < deviation->deviate_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200724 ly_print(out, "%*sdeviate ", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200725 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100726 if (deviation->deviate[i].ext_size) {
727 ly_print(out, "not-supported {\n");
728 } else {
729 ly_print(out, "not-supported;\n");
730 continue;
731 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200732 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
Radek Krejci76b07902015-10-09 09:11:25 +0200733 ly_print(out, "add {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200734 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200735 ly_print(out, "replace {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200736 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200737 ly_print(out, "delete {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200738 }
739 level++;
740
Radek Krejci5dd25122017-01-11 17:28:13 +0100741 /* extensions */
742 if (deviation->deviate[i].ext_size) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100743 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
Radek Krejci5dd25122017-01-11 17:28:13 +0100744 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200745 }
746
Radek Krejci5dd25122017-01-11 17:28:13 +0100747 /* type */
748 if (deviation->deviate[i].type) {
749 yang_print_type(out, level, module, deviation->deviate[i].type);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200750 }
751
Radek Krejci5dd25122017-01-11 17:28:13 +0100752 /* units */
753 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, deviation->deviate[i].units, module,
754 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200755
Radek Krejci5dd25122017-01-11 17:28:13 +0100756 /* must */
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200757 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
Michal Vaskof9893382015-10-09 14:03:04 +0200758 yang_print_must(out, level, module, &deviation->deviate[i].must[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200759 }
760
Radek Krejci5dd25122017-01-11 17:28:13 +0100761 /* unique */
762
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200763 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
Radek Krejci76b07902015-10-09 09:11:25 +0200764 yang_print_unique(out, level, &deviation->deviate[i].unique[j]);
Radek Krejci43e3c312017-01-11 11:34:44 +0100765 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +0100766 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100767 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100768 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejcicfce0292017-01-13 12:37:57 +0100769 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100770 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100771 if (p != -1) {
772 ly_print(out, " {\n");
773 do {
774 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, j,
775 &deviation->deviate[i].ext[p], 1);
776 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100777 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejci43e3c312017-01-11 11:34:44 +0100778 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100779 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100780 } while (p != -1);
781 ly_print(out, "%*s}\n", LEVEL, INDENT);
782 } else {
783 ly_print(out, ";\n");
784 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200785 }
786
Radek Krejci5dd25122017-01-11 17:28:13 +0100787 /* default */
Radek Krejci033983b2017-01-13 12:43:20 +0100788 for (j = 0; j < deviation->deviate[i].dflt_size; ++j) {
789 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, j, deviation->deviate[i].dflt[j], module,
Radek Krejci5dd25122017-01-11 17:28:13 +0100790 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200791 }
792
Radek Krejci5dd25122017-01-11 17:28:13 +0100793 /* config */
794 if (deviation->deviate[i].flags & LYS_CONFIG_W) {
795 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module,
796 deviation->deviate->ext, deviation->deviate[i].ext_size);
797 } else if (deviation->deviate[i].flags & LYS_CONFIG_R) {
798 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module,
799 deviation->deviate->ext, deviation->deviate[i].ext_size);
800 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100801
Radek Krejci5dd25122017-01-11 17:28:13 +0100802 /* mandatory */
803 if (deviation->deviate[i].flags & LYS_MAND_TRUE) {
804 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module,
805 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
806 } else if (deviation->deviate[i].flags & LYS_MAND_FALSE) {
807 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module,
808 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
809 }
810
811 /* min-elements */
812 if (deviation->deviate[i].min_set) {
813 asprintf(&s, "%u", deviation->deviate[i].min);
814 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, s, module,
815 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
816 free(s);
817 }
818
819 /* max-elements */
820 if (deviation->deviate[i].max_set) {
821 if (deviation->deviate[i].max) {
822 asprintf(&s, "%u", deviation->deviate[i].max);
823 } else {
824 s = NULL;
825 }
826 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, s ? s : "unbounded", module,
827 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
828 free(s);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200829 }
830
831 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200832 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200833 }
834
835 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200836 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200837}
838
839static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100840yang_print_augment(struct lyout *out, int level, const struct lys_node_augment *augment)
Michal Vasko6f25f212015-07-07 15:42:07 +0200841{
Radek Krejci76512572015-08-04 09:47:08 +0200842 struct lys_node *sub;
Michal Vasko488c19e2015-10-20 15:21:00 +0200843 const char *str;
Michal Vasko6f25f212015-07-07 15:42:07 +0200844
Radek Krejci43e3c312017-01-11 11:34:44 +0100845 str = transform_json2schema(augment->module, augment->target_name);
Michal Vasko488c19e2015-10-20 15:21:00 +0200846 ly_print(out, "%*saugment \"%s\" {\n", LEVEL, INDENT, str);
Radek Krejci43e3c312017-01-11 11:34:44 +0100847 lydict_remove(augment->module->ctx, str);
Michal Vasko6f25f212015-07-07 15:42:07 +0200848 level++;
849
Radek Krejci5dd25122017-01-11 17:28:13 +0100850 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL, SNODE_COMMON_EXT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200851 if (augment->when) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100852 yang_print_when(out, level, augment->module, augment->when);
Michal Vasko6f25f212015-07-07 15:42:07 +0200853 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100854 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL,
855 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200856
857 LY_TREE_FOR(augment->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100858 /* only our augment */
859 if (sub->parent != (struct lys_node *)augment) {
860 continue;
861 }
Radek Krejci76b07902015-10-09 09:11:25 +0200862 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200863 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +0100864 LYS_USES | LYS_ANYDATA | LYS_CASE | LYS_ACTION | LYS_NOTIF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200865 }
866
867 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200868 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200869}
870
871static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100872yang_print_typedef(struct lyout *out, int level, const struct lys_module *module, const struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200873{
Radek Krejci033983b2017-01-13 12:43:20 +0100874 const char *dflt;
875
Radek Krejci76b07902015-10-09 09:11:25 +0200876 ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200877 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200878
Radek Krejci5dd25122017-01-11 17:28:13 +0100879 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL, SNODE_COMMON_EXT);
Radek Krejci76b07902015-10-09 09:11:25 +0200880 yang_print_type(out, level, module, &tpdf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200881 if (tpdf->units != NULL) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100882 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, module, tpdf->ext, tpdf->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200883 }
884 if (tpdf->dflt != NULL) {
Radek Krejcibd117f02016-11-04 16:28:08 +0100885 if (tpdf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +0100886 assert(strchr(tpdf->dflt, ':'));
887 if (!strncmp(tpdf->dflt, module->name, strchr(tpdf->dflt, ':') - tpdf->dflt)) {
888 /* local module */
889 dflt = lydict_insert(module->ctx, strchr(tpdf->dflt, ':') + 1, 0);
890 } else {
891 dflt = transform_json2schema(module, tpdf->dflt);
892 }
Radek Krejcibd117f02016-11-04 16:28:08 +0100893 } else {
894 dflt = tpdf->dflt;
895 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100896 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt, module, tpdf->ext, tpdf->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +0100897 if (tpdf->flags & LYS_DFLTJSON) {
898 lydict_remove(module->ctx, dflt);
899 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200900 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100901 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL,
902 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200903
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200904 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200905 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200906}
907
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200908static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100909yang_print_identity(struct lyout *out, int level, const struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200910{
Radek Krejci018f1f52016-08-03 16:01:20 +0200911 int flag = 0, i;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100912 struct lys_module *mod;
Radek Krejci43e3c312017-01-11 11:34:44 +0100913 char *str;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100914
915 ly_print(out, "%*sidentity %s", LEVEL, INDENT, ident->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200916 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200917
Radek Krejci5dd25122017-01-11 17:28:13 +0100918 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
919 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
920
Radek Krejci018f1f52016-08-03 16:01:20 +0200921 for (i = 0; i < ident->base_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100922 yang_print_open(out, &flag);
Radek Krejci018f1f52016-08-03 16:01:20 +0200923 mod = lys_main_module(ident->base[i]->module);
Radek Krejci43e3c312017-01-11 11:34:44 +0100924 if (lys_main_module(ident->module) == mod) {
Radek Krejcib5e58d32017-01-23 13:45:59 +0100925 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, ident->base[i]->name,
Radek Krejci43e3c312017-01-11 11:34:44 +0100926 ident->module, ident->ext, ident->ext_size);
927 } else {
928 asprintf(&str, "%s:%s", transform_module_name2import_prefix(ident->module, mod->name), ident->base[i]->name);
Radek Krejcib5e58d32017-01-23 13:45:59 +0100929 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, str,
Radek Krejci43e3c312017-01-11 11:34:44 +0100930 ident->module, ident->ext, ident->ext_size);
931 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200932 }
933 }
Radek Krejci6793db02015-05-22 17:49:54 +0200934
Radek Krejci5dd25122017-01-11 17:28:13 +0100935 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
936 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
937
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200938 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100939 yang_print_close(out, level, flag);
Radek Krejci6793db02015-05-22 17:49:54 +0200940}
941
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200942static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100943yang_print_container(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200944{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100945 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +0200946 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200947 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200948
Radek Krejci32cce7c2015-12-09 16:44:13 +0100949 ly_print(out, "%*scontainer %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200950 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200951
Radek Krejci5dd25122017-01-11 17:28:13 +0100952 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +0100953 if (cont->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100954 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +0100955 yang_print_when(out, level, node->module, cont->when);
956 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200957 for (i = 0; i < cont->iffeature_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +0100958 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +0200959 yang_print_iffeature(out, level, node->module, &cont->iffeature[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200960 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200961 for (i = 0; i < cont->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100962 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200963 yang_print_must(out, level, node->module, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200964 }
Radek Krejci8d81e002015-12-10 11:18:59 +0100965 if (cont->presence != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100966 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100967 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence,
968 node->module, node->ext, node->ext_size);
Michal Vasko4773b762015-07-07 12:15:10 +0200969 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100970 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG |
971 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200972 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100973 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200974 yang_print_typedef(out, level, node->module, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200975 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200976 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100977 /* augments */
978 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200979 continue;
980 }
Radek Krejci32cce7c2015-12-09 16:44:13 +0100981 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100982 yang_print_snode(out, level, sub, LYS_GROUPING);
983 }
984 LY_TREE_FOR(node->child, sub) {
985 /* augments */
986 if (sub->parent != node) {
987 continue;
988 }
989 yang_print_open(out, &flag);
990 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
991 LYS_USES | LYS_ANYDATA );
992 }
993 LY_TREE_FOR(node->child, sub) {
994 /* augments */
995 if (sub->parent != node) {
996 continue;
997 }
998 yang_print_open(out, &flag);
999 yang_print_snode(out, level, sub, LYS_ACTION);
1000 }
1001 LY_TREE_FOR(node->child, sub) {
1002 /* augments */
1003 if (sub->parent != node) {
1004 continue;
1005 }
1006 yang_print_open(out, &flag);
Radek Krejci033983b2017-01-13 12:43:20 +01001007 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001008 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001009
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001010 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001011 yang_print_close(out, level, flag);
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001012}
1013
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001014static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001015yang_print_case(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001016{
Radek Krejci5dd25122017-01-11 17:28:13 +01001017 int flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001018 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001019 struct lys_node_case *cas = (struct lys_node_case *)node;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001020
Radek Krejci5dd25122017-01-11 17:28:13 +01001021 ly_print(out, "%*scase %s", LEVEL, INDENT, cas->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001022 level++;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001023
Radek Krejci5dd25122017-01-11 17:28:13 +01001024 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001025 if (cas->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001026 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001027 yang_print_when(out, level, node->module, cas->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001028 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001029 yang_print_snode_common(out, level, node, node->module, &flag,
1030 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001031
Radek Krejci1d82ef62015-08-07 14:44:40 +02001032 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001033 /* augments */
1034 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001035 continue;
1036 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001037 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001038 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001039 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejcibf2abff2016-08-23 15:51:52 +02001040 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001041 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001042
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001043 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001044 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001045}
1046
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001047static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001048yang_print_choice(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001049{
Radek Krejci5dd25122017-01-11 17:28:13 +01001050 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001051 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001052 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001053
Radek Krejci5dd25122017-01-11 17:28:13 +01001054 ly_print(out, "%*schoice %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001055 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001056
1057 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1058 if (choice->when) {
1059 yang_print_open(out, &flag);
1060 yang_print_when(out, level, node->module, choice->when);
1061 }
1062 for (i = 0; i < choice->iffeature_size; i++) {
1063 yang_print_open(out, &flag);
1064 yang_print_iffeature(out, level, node->module, &choice->iffeature[i]);
1065 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001066 if (choice->dflt != NULL) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001067 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001068 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt->name,
1069 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001070 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001071 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1072 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001073
Radek Krejci1d82ef62015-08-07 14:44:40 +02001074 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001075 /* augments */
1076 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001077 continue;
1078 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001079 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001080 yang_print_snode(out, level, sub,
Radek Krejci5dd25122017-01-11 17:28:13 +01001081 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_CASE);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001082 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001083
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001084 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001085 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001086}
1087
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001088static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001089yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001090{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001091 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001092 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001093 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001094
Radek Krejci76b07902015-10-09 09:11:25 +02001095 ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001096 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001097
1098 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001099 if (leaf->when) {
1100 yang_print_when(out, level, node->module, leaf->when);
1101 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001102 for (i = 0; i < leaf->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001103 yang_print_iffeature(out, level, node->module, &leaf->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001104 }
Radek Krejci76b07902015-10-09 09:11:25 +02001105 yang_print_type(out, level, node->module, &leaf->type);
Radek Krejci43e3c312017-01-11 11:34:44 +01001106 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, leaf->units,
1107 node->module, node->ext, node->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +01001108 for (i = 0; i < leaf->must_size; i++) {
1109 yang_print_must(out, level, node->module, &leaf->must[i]);
1110 }
Michal Vaskod875e882016-05-19 10:57:30 +02001111 if (leaf->dflt) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001112 if (leaf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001113 assert(strchr(leaf->dflt, ':'));
1114 if (!strncmp(leaf->dflt, lys_node_module(node)->name, strchr(leaf->dflt, ':') - leaf->dflt)) {
1115 /* local module */
1116 dflt = lydict_insert(node->module->ctx, strchr(leaf->dflt, ':') + 1, 0);
1117 } else {
1118 dflt = transform_json2schema(node->module, leaf->dflt);
1119 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001120 } else {
1121 dflt = leaf->dflt;
1122 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001123 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt,
1124 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001125 if (leaf->flags & LYS_DFLTJSON) {
1126 lydict_remove(node->module->ctx, dflt);
1127 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001128 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001129 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1130 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001131 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001132 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +02001133}
1134
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001135static void
Radek Krejcibf2abff2016-08-23 15:51:52 +02001136yang_print_anydata(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko16083662015-06-09 14:00:45 +02001137{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001138 int i, flag = 0;
Radek Krejcibf2abff2016-08-23 15:51:52 +02001139 struct lys_node_anydata *any = (struct lys_node_anydata *)node;
Michal Vasko16083662015-06-09 14:00:45 +02001140
Radek Krejcibf2abff2016-08-23 15:51:52 +02001141 ly_print(out, "%*s%s %s", LEVEL, INDENT, any->nodetype == LYS_ANYXML ? "anyxml" : "anydata", any->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001142 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001143
1144 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1145 if (any->when) {
1146 yang_print_open(out, &flag);
1147 yang_print_when(out, level, node->module, any->when);
1148 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001149 for (i = 0; i < any->iffeature_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001150 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001151 yang_print_iffeature(out, level, node->module, &any->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001152 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001153 for (i = 0; i < any->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001154 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001155 yang_print_must(out, level, node->module, &any->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001156 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001157 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1158 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001159 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001160 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001161}
1162
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001163static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001164yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001165{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001166 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001167 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001168 const char *dflt;
Radek Krejci43e3c312017-01-11 11:34:44 +01001169 char *str;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001170
Radek Krejci76b07902015-10-09 09:11:25 +02001171 ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001172 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001173 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001174 if (llist->when) {
1175 yang_print_when(out, level, llist->module, llist->when);
1176 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001177 for (i = 0; i < llist->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001178 yang_print_iffeature(out, level, node->module, &llist->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001179 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001180 yang_print_type(out, level, node->module, &llist->type);
1181 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, llist->units,
1182 node->module, node->ext, node->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001183 for (i = 0; i < llist->must_size; i++) {
1184 yang_print_must(out, level, node->module, &llist->must[i]);
1185 }
Pavol Vican38321d02016-08-16 14:56:02 +02001186 for (i = 0; i < llist->dflt_size; ++i) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001187 if (llist->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001188 assert(strchr(llist->dflt[i], ':'));
1189 if (!strncmp(llist->dflt[i], lys_node_module(node)->name, strchr(llist->dflt[i], ':') - llist->dflt[i])) {
1190 /* local module */
1191 dflt = lydict_insert(node->module->ctx, strchr(llist->dflt[i], ':') + 1, 0);
1192 } else {
1193 dflt = transform_json2schema(node->module, llist->dflt[i]);
1194 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001195 } else {
1196 dflt = llist->dflt[i];
1197 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001198 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, dflt,
1199 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001200 if (llist->flags & LYS_DFLTJSON) {
1201 lydict_remove(node->module->ctx, dflt);
1202 }
Pavol Vican38321d02016-08-16 14:56:02 +02001203 }
Radek Krejci178a0942017-01-16 15:36:35 +01001204 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001205 if (llist->min > 0) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001206 asprintf(&str, "%u", llist->min);
1207 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, str,
1208 node->module, node->ext, node->ext_size);
1209 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001210 }
1211 if (llist->max > 0) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001212 asprintf(&str, "%u", llist->max);
1213 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, str,
1214 node->module, node->ext, node->ext_size);
1215 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001216 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001217 if (llist->flags & LYS_USERORDERED) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001218 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1219 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001220 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001221 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1222 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001223 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001224 yang_print_snode_common(out, level, node, node->module, NULL,
1225 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001226 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001227 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001228}
1229
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001230static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001231yang_print_list(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001232{
Radek Krejci5dd25122017-01-11 17:28:13 +01001233 int i, p, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001234 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001235 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejci43e3c312017-01-11 11:34:44 +01001236 char *str;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001237
Radek Krejci5dd25122017-01-11 17:28:13 +01001238 ly_print(out, "%*slist %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001239 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001240 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001241 if (list->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001242 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001243 yang_print_when(out, level, list->module, list->when);
1244 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001245 for (i = 0; i < list->iffeature_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001246 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001247 yang_print_iffeature(out, level, node->module, &list->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001248 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001249 for (i = 0; i < list->must_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001250 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001251 yang_print_must(out, level, list->module, &list->must[i]);
1252 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001253 if (list->keys_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001254 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001255 yang_print_substmt(out, level, LYEXT_SUBSTMT_KEY, 0, list->keys_str,
1256 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001257 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001258 for (i = 0; i < list->unique_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001259 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001260 yang_print_unique(out, level, &list->unique[i]);
Radek Krejci43e3c312017-01-11 11:34:44 +01001261 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +01001262 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +01001263 do {
Radek Krejcibf285832017-01-26 16:05:41 +01001264 p = lys_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +01001265 } while (p != -1 && list->ext[p]->insubstmt_index != i);
Radek Krejci43e3c312017-01-11 11:34:44 +01001266 if (p != -1) {
1267 ly_print(out, " {\n");
1268 do {
1269 yang_print_extension_instances(out, level + 1, list->module, LYEXT_SUBSTMT_UNIQUE, i, &list->ext[p], 1);
1270 do {
Radek Krejcibf285832017-01-26 16:05:41 +01001271 p = lys_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +01001272 } while (p != -1 && list->ext[p]->insubstmt_index != i);
Radek Krejci43e3c312017-01-11 11:34:44 +01001273 } while (p != -1);
1274 ly_print(out, "%*s}\n", LEVEL, INDENT);
1275 } else {
1276 ly_print(out, ";\n");
1277 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001278 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001279 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001280 if (list->min > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001281 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001282 asprintf(&str, "%u", list->min);
1283 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, str,
1284 node->module, node->ext, node->ext_size);
1285 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001286 }
1287 if (list->max > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001288 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001289 asprintf(&str, "%u", list->max);
1290 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, str,
1291 node->module, node->ext, node->ext_size);
1292 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001293 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001294 if (list->flags & LYS_USERORDERED) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001295 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001296 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1297 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001298 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001299 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001300 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1301 node->module, node->ext, node->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001302 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001303 yang_print_snode_common(out, level, node, node->module, &flag,
1304 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001305 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001306 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001307 yang_print_typedef(out, level, list->module, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001308 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001309
Radek Krejci1d82ef62015-08-07 14:44:40 +02001310 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001311 /* augments */
1312 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001313 continue;
1314 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001315 yang_print_open(out, &flag);
1316 yang_print_snode(out, level, sub, LYS_GROUPING);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001317 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001318
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_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1326 LYS_USES | LYS_GROUPING | LYS_ANYDATA);
1327 }
1328
1329 LY_TREE_FOR(node->child, sub) {
1330 /* augments */
1331 if (sub->parent != node) {
1332 continue;
1333 }
1334 yang_print_open(out, &flag);
1335 yang_print_snode(out, level, sub, LYS_ACTION);
1336 }
1337
1338 LY_TREE_FOR(node->child, sub) {
1339 /* augments */
1340 if (sub->parent != node) {
1341 continue;
1342 }
1343 yang_print_open(out, &flag);
1344 yang_print_snode(out, level, sub, LYS_NOTIF);
1345 }
1346
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001347 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001348 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001349}
1350
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001351static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001352yang_print_grouping(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001353{
Radek Krejci5dd25122017-01-11 17:28:13 +01001354 int i, flag = 0;
Michal Vasko0c5e9282016-02-15 13:11:57 +01001355 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001356 struct lys_node_grp *grp = (struct lys_node_grp *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001357
Radek Krejci5dd25122017-01-11 17:28:13 +01001358 ly_print(out, "%*sgrouping %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001359 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001360
Radek Krejci5dd25122017-01-11 17:28:13 +01001361 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_STATUS |
1362 SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001363
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001364 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001365 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001366 yang_print_typedef(out, level, node->module, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001367 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001368
Michal Vasko0c5e9282016-02-15 13:11:57 +01001369 LY_TREE_FOR(node->child, sub) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001370 yang_print_open(out, &flag);
1371 yang_print_snode(out, level, sub, LYS_GROUPING);
1372 }
1373
1374 LY_TREE_FOR(node->child, sub) {
1375 yang_print_open(out, &flag);
1376 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1377 LYS_USES | LYS_ANYDATA);
1378 }
1379
1380 LY_TREE_FOR(node->child, sub) {
1381 yang_print_open(out, &flag);
1382 yang_print_snode(out, level, sub, LYS_ACTION);
1383 }
1384
1385 LY_TREE_FOR(node->child, sub) {
1386 yang_print_open(out, &flag);
1387 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001388 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001389
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001390 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001391 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001392}
1393
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001394static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001395yang_print_uses(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001396{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001397 int i, flag = 0;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001398 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001399 struct lys_module *mod;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001400
Radek Krejci76b07902015-10-09 09:11:25 +02001401 ly_print(out, "%*suses ", LEVEL, INDENT);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001402 if (node->child) {
Michal Vasko6c629ac2016-02-15 14:08:23 +01001403 mod = lys_node_module(node->child);
Michal Vasko1dae8ec2016-02-15 14:49:01 +01001404 if (lys_node_module(node) != mod) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001405 ly_print(out, "%s:", transform_module_name2import_prefix(node->module, mod->name));
1406 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +02001407 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001408 ly_print(out, "%s", uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001409 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001410
Radek Krejci5dd25122017-01-11 17:28:13 +01001411 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001412 if (uses->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001413 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001414 yang_print_when(out, level, node->module, uses->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001415 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001416 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_IFF |
1417 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001418 for (i = 0; i < uses->refine_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001419 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001420 yang_print_refine(out, level, node->module, &uses->refine[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001421 }
Michal Vasko6f25f212015-07-07 15:42:07 +02001422 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001423 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001424 yang_print_augment(out, level, &uses->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001425 }
1426
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001427 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001428 yang_print_close(out, level, flag);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001429}
1430
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001431static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001432yang_print_input_output(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko5bbae102015-06-16 12:16:44 +02001433{
Michal Vaskof4d3d742015-06-16 11:51:09 +02001434 int i;
Radek Krejci76512572015-08-04 09:47:08 +02001435 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001436 struct lys_node_inout *inout = (struct lys_node_inout *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001437
Radek Krejci76b07902015-10-09 09:11:25 +02001438 ly_print(out, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LYS_INPUT ? "input" : "output"));
Michal Vaskof4d3d742015-06-16 11:51:09 +02001439 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001440
Radek Krejcie534c132016-11-23 13:32:31 +01001441 if (node->ext_size) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001442 yang_print_extension_instances(out, level, node->module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001443 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001444 for (i = 0; i < inout->must_size; i++) {
1445 yang_print_must(out, level, node->module, &inout->must[i]);
1446 }
Radek Krejcie534c132016-11-23 13:32:31 +01001447 for (i = 0; i < inout->tpdf_size; i++) {
1448 yang_print_typedef(out, level, node->module, &inout->tpdf[i]);
1449 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001450 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001451 /* augments */
1452 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001453 continue;
1454 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001455 yang_print_snode(out, level, sub, LYS_GROUPING);
1456 }
1457 LY_TREE_FOR(node->child, sub) {
1458 /* augments */
1459 if (sub->parent != node) {
1460 continue;
1461 }
1462 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1463 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001464 }
1465
1466 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001467 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001468}
1469
1470static void
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001471yang_print_rpc_action(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskof4d3d742015-06-16 11:51:09 +02001472{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001473 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001474 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001475 struct lys_node_rpc_action *rpc = (struct lys_node_rpc_action *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001476
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001477 ly_print(out, "%*s%s %s", LEVEL, INDENT, (node->nodetype == LYS_RPC ? "rpc" : "action"), node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001478
1479 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001480 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF |
1481 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko4773b762015-07-07 12:15:10 +02001482
Michal Vaskof4d3d742015-06-16 11:51:09 +02001483 for (i = 0; i < rpc->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001484 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001485 yang_print_typedef(out, level, node->module, &rpc->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001486 }
1487
Radek Krejci1d82ef62015-08-07 14:44:40 +02001488 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001489 /* augments */
1490 if (sub->parent != node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001491 continue;
1492 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001493 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +01001494 yang_print_snode(out, level, sub, LYS_GROUPING);
1495 }
1496
1497 LY_TREE_FOR(node->child, sub) {
1498 /* augments */
1499 if (sub->parent != node) {
1500 continue;
1501 }
1502 yang_print_open(out, &flag);
1503 yang_print_snode(out, level, sub, LYS_INPUT);
1504 }
1505
1506 LY_TREE_FOR(node->child, sub) {
Michal Vasko8b942f02017-01-24 13:12:59 +01001507 /* augments and implicit nodes */
1508 if ((sub->parent != node) || ((sub->nodetype & (LYS_INPUT | LYS_OUTPUT) && (sub->flags & LYS_IMPLICIT)))) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001509 continue;
1510 }
1511 yang_print_open(out, &flag);
1512 yang_print_snode(out, level, sub, LYS_OUTPUT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001513 }
1514
1515 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001516 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001517}
1518
1519static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001520yang_print_notif(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko7690bc12015-06-16 12:26:05 +02001521{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001522 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001523 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001524 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001525
Radek Krejci32cce7c2015-12-09 16:44:13 +01001526 ly_print(out, "%*snotification %s", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001527
1528 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001529 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Radek Krejci12032a52016-07-29 15:42:56 +02001530 for (i = 0; i < notif->must_size; i++) {
1531 yang_print_open(out, &flag);
1532 yang_print_must(out, level, node->module, &notif->must[i]);
1533 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001534 yang_print_snode_common(out, level, node, node->module, &flag,
1535 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
1536 for (i = 0; i < notif->tpdf_size; i++) {
1537 yang_print_open(out, &flag);
1538 yang_print_typedef(out, level, node->module, &notif->tpdf[i]);
1539 }
1540 LY_TREE_FOR(node->child, sub) {
1541 /* augments */
1542 if (sub->parent != node) {
1543 continue;
1544 }
1545 yang_print_open(out, &flag);
1546 yang_print_snode(out, level, sub, LYS_GROUPING);
1547 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001548 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001549 /* augments */
1550 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001551 continue;
1552 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001553 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001554 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001555 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +01001556 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001557 }
1558
1559 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001560 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001561}
1562
1563static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001564yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001565{
Radek Krejci2c99a622017-01-12 10:11:13 +01001566 if (node->nodetype & mask) {
1567 if ((node->nodetype & (LYS_INPUT | LYS_OUTPUT)) && (node->flags & LYS_IMPLICIT)) {
1568 /* implicit input/output node is not supposed to be printed */
1569 return;
1570 } else if (!node->parent ||
1571 (node->parent->nodetype == LYS_AUGMENT && node != node->parent->child) ||
1572 (node->parent->nodetype != LYS_AUGMENT && node->prev->next)) {
1573 /* do not print the blank line before the first data-def node */
1574 ly_print(out, "\n");
1575 }
1576 }
1577
Radek Krejci1d82ef62015-08-07 14:44:40 +02001578 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +02001579 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +02001580 yang_print_container(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001581 break;
Radek Krejci76512572015-08-04 09:47:08 +02001582 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +02001583 yang_print_choice(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001584 break;
Radek Krejci76512572015-08-04 09:47:08 +02001585 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +02001586 yang_print_leaf(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001587 break;
Radek Krejci76512572015-08-04 09:47:08 +02001588 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001589 yang_print_leaflist(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001590 break;
Radek Krejci76512572015-08-04 09:47:08 +02001591 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001592 yang_print_list(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001593 break;
Radek Krejci76512572015-08-04 09:47:08 +02001594 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +02001595 yang_print_uses(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001596 break;
Radek Krejci76512572015-08-04 09:47:08 +02001597 case LYS_GROUPING:
Radek Krejci76b07902015-10-09 09:11:25 +02001598 yang_print_grouping(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001599 break;
Radek Krejci76512572015-08-04 09:47:08 +02001600 case LYS_ANYXML:
Radek Krejcibf2abff2016-08-23 15:51:52 +02001601 case LYS_ANYDATA:
1602 yang_print_anydata(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001603 break;
Radek Krejci76512572015-08-04 09:47:08 +02001604 case LYS_CASE:
Radek Krejci76b07902015-10-09 09:11:25 +02001605 yang_print_case(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001606 break;
Radek Krejci5dd25122017-01-11 17:28:13 +01001607 case LYS_RPC:
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001608 case LYS_ACTION:
1609 yang_print_rpc_action(out, level, node);
1610 break;
Radek Krejci76512572015-08-04 09:47:08 +02001611 case LYS_INPUT:
1612 case LYS_OUTPUT:
Radek Krejci2c99a622017-01-12 10:11:13 +01001613 yang_print_input_output(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001614 break;
Michal Vaskob15cae22016-09-15 09:40:56 +02001615 case LYS_NOTIF:
1616 yang_print_notif(out, level, node);
1617 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001618 default:
1619 break;
1620 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001621}
1622
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001623int
Michal Vasko1e62a092015-12-01 12:27:20 +01001624yang_print_model(struct lyout *out, const struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001625{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001626 unsigned int i;
Radek Krejci43e3c312017-01-11 11:34:44 +01001627 int level = 0, p;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001628
Radek Krejci1d82ef62015-08-07 14:44:40 +02001629 struct lys_node *node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001630
Radek Krejci8d81e002015-12-10 11:18:59 +01001631 /* (sub)module-header-stmts */
Michal Vasko116172e2015-07-07 11:54:37 +02001632 if (module->type) {
Michal Vasko89563fc2016-07-28 16:19:35 +02001633 ly_print(out, "submodule %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001634 level++;
Radek Krejci77424f72017-01-20 13:21:09 +01001635 if (lys_main_module(module)->version > 1 ||
Radek Krejcibf285832017-01-26 16:05:41 +01001636 lys_ext_iter(module->ext, module->ext_size, 0, LYEXT_SUBSTMT_VERSION) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001637 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0,
1638 ((struct lys_submodule *)module)->belongsto->version == 2 ? "1.1" : "1",
1639 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001640 }
Radek Krejci76b07902015-10-09 09:11:25 +02001641 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Radek Krejcicfce0292017-01-13 12:37:57 +01001642 p = -1;
Radek Krejcibf285832017-01-26 16:05:41 +01001643 while ((p = lys_ext_iter(module->ext, module->ext_size, p + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001644 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0, &module->ext[p], 1);
1645 }
1646 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1647 module, module->ext, module->ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001648 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001649 } else {
Michal Vasko89563fc2016-07-28 16:19:35 +02001650 ly_print(out, "module %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001651 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001652 if (module->version) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001653 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == 2 ? "1.1" : "1",
1654 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001655 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001656 yang_print_substmt(out, level, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns,
1657 module, module->ext, module->ext_size);
1658 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1659 module, module->ext, module->ext_size);
Michal Vasko116172e2015-07-07 11:54:37 +02001660 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001661
Radek Krejci8d81e002015-12-10 11:18:59 +01001662 /* linkage-stmts */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001663 for (i = 0; i < module->imp_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001664 ly_print(out, "\n%*simport %s {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001665 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001666 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1667 module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci39228d22017-01-13 12:43:55 +01001668 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->imp[i].prefix,
1669 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001670 if (module->imp[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001671 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->imp[i].rev,
1672 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001673 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001674 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->imp[i].dsc,
1675 module, module->imp[i].ext, module->imp[i].ext_size);
1676 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->imp[i].ref,
1677 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001678 level--;
Michal Vaskoc8e3ce02016-02-12 14:28:35 +01001679 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001680 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001681 for (i = 0; i < module->inc_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001682 if (module->inc[i].rev[0] || module->inc[i].dsc || module->inc[i].ref || module->inc[i].ext_size) {
1683 ly_print(out, "\n%*sinclude %s {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci8d81e002015-12-10 11:18:59 +01001684 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001685 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1686 module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001687 if (module->inc[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001688 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->inc[i].rev,
1689 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001690 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001691 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->inc[i].dsc,
1692 module, module->inc[i].ext, module->inc[i].ext_size);
1693 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->inc[i].ref,
1694 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001695 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001696 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001697 } else {
Radek Krejcie534c132016-11-23 13:32:31 +01001698 ly_print(out, "\n%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001699 }
1700 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001701
Radek Krejci8d81e002015-12-10 11:18:59 +01001702 /* meta-stmts */
1703 if (module->org || module->contact || module->dsc || module->ref) {
1704 ly_print(out, "\n");
1705 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001706 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org,
1707 module, module->ext, module->ext_size);
1708 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONTACT, 0, module->contact,
1709 module, module->ext, module->ext_size);
1710 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc,
1711 module, module->ext, module->ext_size);
1712 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->ref,
1713 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001714
1715 /* revision-stmts */
1716 if (module->rev_size) {
1717 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001718 }
1719 for (i = 0; i < module->rev_size; i++) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001720 if (module->rev[i].dsc || module->rev[i].ref || module->rev[i].ext_size) {
Radek Krejci76b07902015-10-09 09:11:25 +02001721 ly_print(out, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci5dd25122017-01-11 17:28:13 +01001722 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1723 module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci43e3c312017-01-11 11:34:44 +01001724 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_DESCRIPTION, 0, module->rev[i].dsc,
1725 module, module->rev[i].ext, module->rev[i].ext_size);
1726 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_REFERENCE, 0, module->rev[i].ref,
1727 module, module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001728 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001729 } else {
Michal Vasko86dfd262016-02-15 14:26:31 +01001730 ly_print(out, "%*srevision %s;\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001731 }
1732 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001733
Radek Krejci8d81e002015-12-10 11:18:59 +01001734 /* body-stmts */
Radek Krejcie534c132016-11-23 13:32:31 +01001735 for (i = 0; i < module->extensions_size; i++) {
1736 ly_print(out, "\n");
1737 yang_print_extension(out, level, &module->extensions[i]);
1738 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001739 if (module->ext_size) {
1740 ly_print(out, "\n");
1741 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, module->ext, module->ext_size);
1742 }
Radek Krejcie534c132016-11-23 13:32:31 +01001743
Michal Vasko30f6e912015-07-07 12:24:27 +02001744 for (i = 0; i < module->features_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001745 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001746 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001747 }
1748
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001749 for (i = 0; i < module->ident_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001750 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001751 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001752 }
Radek Krejci6793db02015-05-22 17:49:54 +02001753
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001754 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001755 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001756 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001757 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001758
Radek Krejci5dd25122017-01-11 17:28:13 +01001759 LY_TREE_FOR(lys_main_module(module)->data, node) {
1760 if (node->module != module) {
1761 /* data from submodules */
1762 continue;
1763 }
1764 yang_print_snode(out, level, node, LYS_GROUPING);
Radek Krejci8d81e002015-12-10 11:18:59 +01001765 }
1766
Radek Krejcic4283442016-04-22 09:19:27 +02001767 LY_TREE_FOR(lys_main_module(module)->data, node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001768 if (node->module != module) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001769 /* data from submodules */
Radek Krejcic071c542016-01-27 14:57:51 +01001770 continue;
1771 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001772 yang_print_snode(out, level, node, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1773 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001774 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001775
Michal Vasko6f25f212015-07-07 15:42:07 +02001776 for (i = 0; i < module->augment_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001777 ly_print(out, "\n");
Radek Krejci43e3c312017-01-11 11:34:44 +01001778 yang_print_augment(out, level, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001779 }
1780
Radek Krejci5dd25122017-01-11 17:28:13 +01001781 LY_TREE_FOR(lys_main_module(module)->data, node) {
1782 if (node->module != module) {
1783 /* data from submodules */
1784 continue;
1785 }
1786 yang_print_snode(out, level, node, LYS_RPC | LYS_ACTION);
1787 }
1788
1789 LY_TREE_FOR(lys_main_module(module)->data, node) {
1790 if (node->module != module) {
1791 /* data from submodules */
1792 continue;
1793 }
1794 yang_print_snode(out, level, node, LYS_NOTIF);
1795 }
1796
1797 for (i = 0; i < module->deviation_size; ++i) {
1798 ly_print(out, "\n");
1799 yang_print_deviation(out, level, module, &module->deviation[i]);
1800 }
1801
Radek Krejci76b07902015-10-09 09:11:25 +02001802 ly_print(out, "}\n");
Michal Vasko95068c42016-03-24 14:58:11 +01001803 ly_print_flush(out);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001804
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001805 return EXIT_SUCCESS;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001806}
1807
1808static void
Radek Krejcic1885952017-02-07 09:37:51 +01001809yang_print_extcomplex_bool(struct lyout *out, int level, const struct lys_module *module,
1810 struct lys_ext_instance_complex *ext, LY_STMT stmt, LYEXT_SUBSTMT substmt,
1811 const char *true_val, const char *false_val, int *content)
1812{
1813 struct lyext_substmt *info;
1814 uint8_t *val;
1815
1816 val = lys_ext_complex_get_substmt(stmt, ext, &info);
1817 if (!val || !(*val)) {
1818 return;
1819 }
1820
1821 yang_print_open(out, content);
1822 if (*val == 1) {
1823 yang_print_substmt(out, level, substmt, 0, true_val, module, ext->ext, ext->ext_size);
1824 } else if (*val == 2) {
1825 yang_print_substmt(out, level, substmt, 0, false_val, module, ext->ext, ext->ext_size);
1826 } else {
1827 LOGINT;
1828 }
1829}
1830
1831static void
Radek Krejci8d6b7422017-02-03 14:42:13 +01001832yang_print_extcomplex_str(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcic1885952017-02-07 09:37:51 +01001833 struct lys_ext_instance_complex *ext, LY_STMT stmt, LYEXT_SUBSTMT substmt, int *content)
Radek Krejci8d6b7422017-02-03 14:42:13 +01001834{
1835 struct lyext_substmt *info;
1836 const char **str;
1837 int c;
1838
1839 str = lys_ext_complex_get_substmt(stmt, ext, &info);
1840 if (!str || !(*str)) {
1841 return;
1842 }
1843 if (info->cardinality >= LY_STMT_CARD_SOME) {
1844 /* we have array */
1845 for (str = (const char **)(*str), c = 0; *str; str++, c++) {
1846 yang_print_open(out, content);
Radek Krejcic1885952017-02-07 09:37:51 +01001847 yang_print_substmt(out, level, substmt, c, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001848 }
1849 } else {
1850 yang_print_open(out, content);
Radek Krejcic1885952017-02-07 09:37:51 +01001851 yang_print_substmt(out, level, substmt, 0, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001852 }
1853}
1854
Radek Krejcic1885952017-02-07 09:37:51 +01001855/* val1 is supposed to be the default value */
1856static void
1857yang_print_extcomplex_flags(struct lyout *out, int level, const struct lys_module *module,
1858 struct lys_ext_instance_complex *ext, LY_STMT stmt, LYEXT_SUBSTMT substmt,
1859 const char *val1_str, const char *val2_str, uint16_t val1, uint16_t val2,
1860 int *content)
1861{
1862 const char *str;
1863 uint16_t *flags;
1864
1865 flags = lys_ext_complex_get_substmt(stmt, ext, NULL);
1866 if (!flags) {
1867 return;
1868 }
1869
1870 if (val1 & *flags) {
1871 str = val1_str;
1872 } else if (val2 & *flags) {
1873 str = val2_str;
1874 } else if (lys_ext_iter(ext->ext, ext->ext_size, 0, substmt) != -1) {
1875 /* flag not set, but since there are some extension, we are going to print the default value */
1876 str = val1_str;
1877 } else {
1878 return;
1879 }
1880
1881 yang_print_open(out, content);
1882 yang_print_substmt(out, level, substmt, 0, str, module, ext->ext, ext->ext_size);
1883}
1884
Radek Krejci8d6b7422017-02-03 14:42:13 +01001885static void
1886yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
1887 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
1888 struct lys_ext_instance **ext, unsigned int count)
1889{
1890 unsigned int u, x;
1891 struct lys_module *mod;
1892 const char *prefix = NULL, *str;
1893 int content, i;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001894 struct lyext_substmt *info;
1895 uint16_t *flags;
1896 void **pp;
1897
1898#define YANG_PRINT_EXTCOMPLEX_STRUCT(STMT, TYPE, FUNC) \
Radek Krejcifebdad72017-02-06 11:35:51 +01001899 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001900 if (!pp || !(*pp)) { break; } \
Radek Krejcifebdad72017-02-06 11:35:51 +01001901 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001902 for (pp = *pp; *pp; pp++) { \
1903 yang_print_open(out, &content); \
1904 FUNC(out, level, module, (TYPE *)(*pp)); \
1905 } \
1906 } else { /* single item */ \
1907 yang_print_open(out, &content); \
1908 FUNC(out, level, module, (TYPE *)(*pp)); \
1909 }
1910
1911 for (u = 0; u < count; u++) {
1912 if (ext[u]->flags & LYEXT_OPT_INHERIT) {
1913 /* ignore the inherited extensions which were not explicitely instantiated in the module */
1914 continue;
Radek Krejcifebdad72017-02-06 11:35:51 +01001915 } else if (ext[u]->insubstmt != substmt || ext[u]->insubstmt_index != substmt_index) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001916 /* do not print the other substatement than the required */
1917 continue;
1918 }
1919
1920 mod = lys_main_module(ext[u]->def->module);
1921 if (mod == lys_main_module(module)) {
1922 prefix = module->prefix;
1923 } else {
1924 for (x = 0; x < module->imp_size; x++) {
1925 if (mod == module->imp[x].module) {
1926 prefix = module->imp[x].prefix;
1927 break;
1928 }
1929 }
1930 }
1931
1932 content = 0;
1933 ly_print(out, "%*s%s:%s", LEVEL, INDENT, prefix, ext[u]->def->name);
1934 /* extension - generic part */
1935 if (ext[u]->arg_value) {
1936 ly_print(out, " \"%s\"", ext[u]->arg_value);
1937 }
1938
1939 /* extensions in extension instance */
1940 if (ext[u]->ext_size) {
1941 yang_print_open(out, &content);
1942 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1943 ext[u]->ext, ext[u]->ext_size);
1944 }
1945
1946 /* extension - type-specific part */
1947 switch(lys_ext_instance_type(ext[u])) {
1948 case LYEXT_FLAG:
1949 /* flag extension - nothing special */
1950 break;
1951 case LYEXT_COMPLEX:
Radek Krejcifebdad72017-02-06 11:35:51 +01001952 info = ((struct lys_ext_instance_complex*)ext[u])->substmt; /* shortcut */
1953 if (!info) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001954 /* no content */
1955 break;
1956 }
1957 level++;
Radek Krejcifebdad72017-02-06 11:35:51 +01001958 for (i = 0; info[i].stmt; i++) {
1959 switch(info[i].stmt) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001960 case LY_STMT_DESCRIPTION:
1961 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
1962 LY_STMT_DESCRIPTION, LYEXT_SUBSTMT_DESCRIPTION, &content);
1963 break;
1964 case LY_STMT_REFERENCE:
1965 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
1966 LY_STMT_REFERENCE, LYEXT_SUBSTMT_REFERENCE, &content);
1967 break;
1968 case LY_STMT_UNITS:
1969 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
1970 LY_STMT_UNITS, LYEXT_SUBSTMT_UNITS, &content);
1971 break;
1972 case LY_STMT_TYPE:
1973 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_TYPE, struct lys_type, yang_print_type);
1974 break;
1975 case LY_STMT_IFFEATURE:
1976 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_IFFEATURE, struct lys_iffeature, yang_print_iffeature);
1977 break;
1978 case LY_STMT_STATUS:
Radek Krejcifebdad72017-02-06 11:35:51 +01001979 flags = lys_ext_complex_get_substmt(LY_STMT_STATUS, (struct lys_ext_instance_complex *)ext[u], NULL);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001980 if (!flags) {
1981 return;
1982 }
1983
1984 if (*flags & LYS_STATUS_CURR) {
1985 yang_print_open(out, &content);
1986 str = "current";
1987 } else if (*flags & LYS_STATUS_DEPRC) {
1988 yang_print_open(out, &content);
1989 str = "deprecated";
1990 } else if (*flags & LYS_STATUS_OBSLT) {
1991 yang_print_open(out, &content);
1992 str = "obsolete";
1993 }
1994 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, str, module, ext[u]->ext, ext[u]->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001995 case LY_STMT_CONFIG:
1996 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
1997 LY_STMT_CONFIG, LYEXT_SUBSTMT_CONFIG,
1998 "true", "false",
1999 LYS_CONFIG_W | LYS_CONFIG_SET, LYS_CONFIG_R | LYS_CONFIG_SET, &content);
2000 break;
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002001 case LY_STMT_ARGUMENT:
2002 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2003 LY_STMT_ARGUMENT, LYEXT_SUBSTMT_ARGUMENT, &content);
2004 break;
2005 break;
2006 case LY_STMT_DEFAULT:
2007 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2008 LY_STMT_DEFAULT, LYEXT_SUBSTMT_DEFAULT, &content);
2009 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002010 case LY_STMT_MANDATORY:
2011 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2012 LY_STMT_MANDATORY, LYEXT_SUBSTMT_MANDATORY,
2013 "false", "true", LYS_MAND_FALSE, LYS_MAND_TRUE, &content);
2014 break;
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002015 case LY_STMT_ERRTAG:
2016 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2017 LY_STMT_ERRTAG, LYEXT_SUBSTMT_ERRTAG, &content);
2018 break;
2019 case LY_STMT_ERRMSG:
2020 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2021 LY_STMT_ERRMSG, LYEXT_SUBSTMT_ERRMSG, &content);
2022 break;
2023 case LY_STMT_PREFIX:
2024 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2025 LY_STMT_PREFIX, LYEXT_SUBSTMT_PREFIX, &content);
2026 break;
2027 case LY_STMT_NAMESPACE:
2028 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2029 LY_STMT_NAMESPACE, LYEXT_SUBSTMT_NAMESPACE, &content);
2030 break;
2031 case LY_STMT_PRESENCE:
2032 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2033 LY_STMT_PRESENCE, LYEXT_SUBSTMT_PRESENCE, &content);
2034 break;
2035 case LY_STMT_REVISIONDATE:
2036 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2037 LY_STMT_REVISIONDATE, LYEXT_SUBSTMT_REVISIONDATE, &content);
2038 break;
2039 case LY_STMT_KEY:
2040 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2041 LY_STMT_KEY, LYEXT_SUBSTMT_KEY, &content);
2042 break;
2043 case LY_STMT_BASE:
2044 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2045 LY_STMT_BASE, LYEXT_SUBSTMT_BASE, &content);
2046 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002047 case LY_STMT_ORDEREDBY:
2048 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2049 LY_STMT_ORDEREDBY, LYEXT_SUBSTMT_ORDEREDBY,
2050 "system", "user", 0, LYS_USERORDERED, &content);
2051 break;
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002052 case LY_STMT_BELONGSTO:
2053 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2054 LY_STMT_BELONGSTO, LYEXT_SUBSTMT_BELONGSTO, &content);
2055 break;
2056 case LY_STMT_CONTACT:
2057 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2058 LY_STMT_CONTACT, LYEXT_SUBSTMT_CONTACT, &content);
2059 break;
2060 case LY_STMT_ORG:
2061 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2062 LY_STMT_ORG, LYEXT_SUBSTMT_ORGANIZATION, &content);
2063 break;
2064 case LY_STMT_PATH:
2065 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2066 LY_STMT_PATH, LYEXT_SUBSTMT_PATH, &content);
2067 break;
2068 case LY_STMT_VERSION:
2069 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2070 LY_STMT_VERSION, LYEXT_SUBSTMT_VERSION, &content);
2071 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002072 case LY_STMT_REQINSTANCE:
2073 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2074 LY_STMT_REQINSTANCE, LYEXT_SUBSTMT_REQINST, "true", "false", &content);
2075 break;
2076 case LY_STMT_MODIFIER:
2077 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2078 LY_STMT_MODIFIER, LYEXT_SUBSTMT_MODIFIER, "invert-match", NULL, &content);
2079 break;
2080 case LY_STMT_YINELEM:
2081 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2082 LY_STMT_YINELEM, LYEXT_SUBSTMT_YINELEM, "true", "false", &content);
2083 break;
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002084 case LY_STMT_VALUE:
2085 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
2086 LY_STMT_VALUE, LYEXT_SUBSTMT_VALUE, &content);
2087 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002088 default:
2089 /* TODO */
2090 break;
2091 }
2092 }
2093 level--;
2094 break;
2095 case LYEXT_ERR:
2096 LOGINT;
2097 break;
2098 }
2099
2100 /* close extension */
2101 yang_print_close(out, level, content);
2102 }
2103#undef YANG_PRINT_EXTCOMPLEX_STRUCT
Radek Krejcida04f4a2015-05-21 12:54:09 +02002104}