blob: 700da85ba4159b71d4c91c80afcba509d1204fcc [file] [log] [blame]
Radek Krejcida04f4a2015-05-21 12:54:09 +02001/**
Radek Krejciefdd0ce2015-05-26 16:48:29 +02002 * @file printer/yang.c
Radek Krejcida04f4a2015-05-21 12:54:09 +02003 * @author Radek Krejci <rkrejci@cesnet.cz>
Radek Krejciefdd0ce2015-05-26 16:48:29 +02004 * @brief YANG printer for libyang data model structure
Radek Krejcida04f4a2015-05-21 12:54:09 +02005 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
Radek Krejci54f6fb32016-02-24 12:56:39 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
Michal Vasko8de098c2016-02-26 10:00:25 +010011 *
Radek Krejci54f6fb32016-02-24 12:56:39 +010012 * https://opensource.org/licenses/BSD-3-Clause
Radek Krejcida04f4a2015-05-21 12:54:09 +020013 */
Radek Krejci43e3c312017-01-11 11:34:44 +010014#define _GNU_SOURCE
15#include <stdio.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020016#include <stdlib.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020017#include <string.h>
Michal Vasko25cb6c62016-02-12 14:36:21 +010018#include <stdint.h>
Michal Vaskof30ea3e2016-12-06 12:16:02 +010019#include <assert.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020020
Radek Krejci998a0b82015-08-17 13:14:36 +020021#include "common.h"
Radek Krejci76b07902015-10-09 09:11:25 +020022#include "printer.h"
Michal Vasko2d162e12015-09-24 14:33:29 +020023#include "tree_schema.h"
Radek Krejcida04f4a2015-05-21 12:54:09 +020024
25#define INDENT ""
26#define LEVEL (level*2)
27
Michal Vasko1e62a092015-12-01 12:27:20 +010028static void yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask);
Radek Krejci8d6b7422017-02-03 14:42:13 +010029static void yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
30 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
31 struct lys_ext_instance **ext, unsigned int count);
Radek Krejcida04f4a2015-05-21 12:54:09 +020032
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020033static void
Michal Vasko25cb6c62016-02-12 14:36:21 +010034yang_encode(struct lyout *out, const char *text, int len)
35{
36 int i, start_len;
37 const char *start;
38 char special = 0;
39
40 if (!len) {
41 return;
42 }
43
44 if (len < 0) {
45 len = strlen(text);
46 }
47
48 start = text;
49 start_len = 0;
50 for (i = 0; i < len; ++i) {
51 switch (text[i]) {
52 case '\n':
53 case '\t':
54 case '\"':
55 case '\\':
56 special = text[i];
57 break;
58 default:
59 ++start_len;
60 break;
61 }
62
63 if (special) {
64 ly_write(out, start, start_len);
65 switch (special) {
66 case '\n':
67 ly_write(out, "\\n", 2);
68 break;
69 case '\t':
70 ly_write(out, "\\t", 2);
71 break;
72 case '\"':
73 ly_write(out, "\\\"", 2);
74 break;
75 case '\\':
76 ly_write(out, "\\\\", 2);
77 break;
78 }
79
80 start += start_len + 1;
81 start_len = 0;
82
83 special = 0;
84 }
85 }
86
87 ly_write(out, start, start_len);
88}
89
90static void
Radek Krejci32cce7c2015-12-09 16:44:13 +010091yang_print_open(struct lyout *out, int *flag)
92{
93 if (flag && !*flag) {
94 *flag = 1;
95 ly_print(out, " {\n");
96 }
97}
98
99static void
100yang_print_close(struct lyout *out, int level, int flag)
101{
102 if (flag) {
103 ly_print(out, "%*s}\n", LEVEL, INDENT);
104 } else {
105 ly_print(out, ";\n");
106 }
107}
108
109static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100110yang_print_text(struct lyout *out, int level, const char *name, const char *text, int singleline, int closed)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200111{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200112 const char *s, *t;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200113
Radek Krejci8d81e002015-12-10 11:18:59 +0100114 if (singleline) {
115 ly_print(out, "%*s%s \"", LEVEL, INDENT, name);
116 } else {
117 ly_print(out, "%*s%s\n", LEVEL, INDENT, name);
118 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200119
Radek Krejci8d81e002015-12-10 11:18:59 +0100120 ly_print(out, "%*s\"", LEVEL, INDENT);
121 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200122 t = text;
123 while ((s = strchr(t, '\n'))) {
Michal Vasko25cb6c62016-02-12 14:36:21 +0100124 yang_encode(out, t, s - t);
125 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200126 t = s + 1;
Michal Vasko25cb6c62016-02-12 14:36:21 +0100127 ly_print(out, "%*s ", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200128 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200129
范昌虎1006995277de5fc2016-10-08 07:33:29 -0400130 yang_encode(out, t, strlen(t));
Radek Krejci43e3c312017-01-11 11:34:44 +0100131 if (closed) {
132 ly_print(out, "\";\n");
133 } else {
134 ly_print(out, "\"");
135 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200136 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200137
138}
139
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200140static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100141yang_print_substmt(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text,
142 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size)
143{
Radek Krejcicfce0292017-01-13 12:37:57 +0100144 int i = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100145
146 if (!text) {
147 /* nothing to print */
148 return;
149 }
150
Radek Krejcicfce0292017-01-13 12:37:57 +0100151 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100152 i = lys_ext_iter(ext, ext_size, i + 1, substmt);
Radek Krejcifebdad72017-02-06 11:35:51 +0100153 } while (i != -1 && ext[i]->insubstmt_index != substmt_index);
Radek Krejcicfce0292017-01-13 12:37:57 +0100154
Radek Krejci43e3c312017-01-11 11:34:44 +0100155 if (ext_substmt_info[substmt].flags & SUBST_FLAG_ID) {
156 ly_print(out, "%*s%s %s%s", LEVEL, INDENT, ext_substmt_info[substmt].name, text, i == -1 ? ";\n" : "");
157 } else {
158 yang_print_text(out, level, ext_substmt_info[substmt].name, text,
159 (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) ? 0 : 1, i == -1 ? 1 : 0);
160 }
161
162 if (i != -1) {
163 ly_print(out, " {\n");
164 do {
165 yang_print_extension_instances(out, level + 1, module, substmt, substmt_index, &ext[i], 1);
166 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100167 i = lys_ext_iter(ext, ext_size, i + 1, substmt);
Radek Krejcifebdad72017-02-06 11:35:51 +0100168 } while (i != -1 && ext[i]->insubstmt_index != substmt_index);
Radek Krejci43e3c312017-01-11 11:34:44 +0100169 } while (i != -1);
170 ly_print(out, "%*s}\n", LEVEL, INDENT);
171 }
172}
173
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200174static void
Radek Krejci9ff0a922016-07-14 13:08:05 +0200175yang_print_iffeature(struct lyout *out, int level, const struct lys_module *module, struct lys_iffeature *iffeature)
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200176{
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200177 ly_print(out, "%*sif-feature \"", LEVEL, INDENT);
Michal Vasko77e8a952017-02-03 15:10:08 +0100178 ly_print_iffeature(out, module, iffeature, 0);
Radek Krejci43e3c312017-01-11 11:34:44 +0100179
180 /* extensions */
181 if (iffeature->ext_size) {
182 ly_print(out, "\" {\n");
183 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0, iffeature->ext, iffeature->ext_size);
184 ly_print(out, "%*s}\n", LEVEL, INDENT);
185 } else {
186 ly_print(out, "\";\n");
187 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200188}
189
Radek Krejci5dd25122017-01-11 17:28:13 +0100190/*
191 * Covers:
192 * extension (instances), if-features, config, mandatory, status, description, reference
193 */
194#define SNODE_COMMON_EXT 0x01
195#define SNODE_COMMON_IFF 0x02
196#define SNODE_COMMON_CONFIG 0x04
197#define SNODE_COMMON_MAND 0x08
198#define SNODE_COMMON_STATUS 0x10
199#define SNODE_COMMON_DSC 0x20
200#define SNODE_COMMON_REF 0x40
201static void
202yang_print_snode_common(struct lyout *out, int level, const struct lys_node *node, const struct lys_module *module,
203 int *flag, int mask)
204{
205 int i;
206 const char *status = NULL;
207
208 /* extensions */
209 if ((mask & SNODE_COMMON_EXT) && node->ext_size) {
210 yang_print_open(out, flag);
211 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
212 }
213
214 /* if-features */
215 if (mask & SNODE_COMMON_IFF) {
216 for (i = 0; i < node->iffeature_size; ++i) {
217 yang_print_open(out, flag);
218 yang_print_iffeature(out, level, module, &node->iffeature[i]);
219 }
220 }
221
222 /* config */
223 if (mask & SNODE_COMMON_CONFIG) {
224 /* get info if there is an extension for the config statement */
Radek Krejcibf285832017-01-26 16:05:41 +0100225 i = lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_CONFIG);
Radek Krejci5dd25122017-01-11 17:28:13 +0100226
227 if (lys_parent(node)) {
228 if ((node->flags & LYS_CONFIG_SET) || i != -1) {
229 /* print config when it differs from the parent or if it has an extension instance ... */
230 if (node->flags & LYS_CONFIG_W) {
231 yang_print_open(out, flag);
232 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
233 module, node->ext, node->ext_size);
234 } else if (node->flags & LYS_CONFIG_R) {
235 yang_print_open(out, flag);
236 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
237 module, node->ext, node->ext_size);
238 }
239 }
240 } else if (node->flags & LYS_CONFIG_R) {
241 /* ... or it's a top-level state node */
242 yang_print_open(out, flag);
243 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
244 module, node->ext, node->ext_size);
245 } else if (i != -1) {
246 /* the config has an extension, so we have to print it */
247 yang_print_open(out, flag);
248 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
249 module, node->ext, node->ext_size);
250 }
251 }
252
253 /* mandatory */
254 if ((mask & SNODE_COMMON_MAND) && (node->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
255 if (node->flags & LYS_MAND_TRUE) {
256 yang_print_open(out, flag);
257 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true",
258 module, node->ext, node->ext_size);
259 } else if (node->flags & LYS_MAND_FALSE) {
260 yang_print_open(out, flag);
261 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false",
262 module, node->ext, node->ext_size);
263 }
264 }
265
266 /* status */
267 if (mask & SNODE_COMMON_STATUS) {
268 if (node->flags & LYS_STATUS_CURR) {
269 yang_print_open(out, flag);
270 status = "current";
271 } else if (node->flags & LYS_STATUS_DEPRC) {
272 yang_print_open(out, flag);
273 status = "deprecated";
274 } else if (node->flags & LYS_STATUS_OBSLT) {
275 yang_print_open(out, flag);
276 status = "obsolete";
277 }
278 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, status, module, node->ext, node->ext_size);
279 }
280
281 /* description */
282 if ((mask & SNODE_COMMON_DSC) && node->dsc) {
283 yang_print_open(out, flag);
284 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, node->dsc,
285 module, node->ext, node->ext_size);
286 }
287
288 /* reference */
289 if ((mask & SNODE_COMMON_REF) && node->ref) {
290 yang_print_open(out, flag);
291 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, node->ref,
292 module, node->ext, node->ext_size);
293 }
294}
295
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200296static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100297yang_print_feature(struct lyout *out, int level, const struct lys_feature *feat)
Michal Vasko4773b762015-07-07 12:15:10 +0200298{
Radek Krejci5dd25122017-01-11 17:28:13 +0100299 int flag = 0;
Michal Vasko30f6e912015-07-07 12:24:27 +0200300
Radek Krejci32cce7c2015-12-09 16:44:13 +0100301 ly_print(out, "%*sfeature %s", LEVEL, INDENT, feat->name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100302 yang_print_snode_common(out, level + 1, (struct lys_node *)feat, feat->module, &flag, SNODE_COMMON_EXT |
303 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100304 yang_print_close(out, level, flag);
Michal Vasko4773b762015-07-07 12:15:10 +0200305}
306
307static void
Radek Krejcia1a6b762016-11-14 09:53:38 +0900308yang_print_extension(struct lyout *out, int level, const struct lys_ext *ext)
309{
Radek Krejcicfce0292017-01-13 12:37:57 +0100310 int flag = 0, flag2 = 0, i;
Radek Krejcia1a6b762016-11-14 09:53:38 +0900311
312 ly_print(out, "%*sextension %s", LEVEL, INDENT, ext->name);
313 level++;
314
Radek Krejci5dd25122017-01-11 17:28:13 +0100315 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
316 SNODE_COMMON_EXT);
317
Radek Krejcia1a6b762016-11-14 09:53:38 +0900318 if (ext->argument) {
319 yang_print_open(out, &flag);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900320
Radek Krejcicfce0292017-01-13 12:37:57 +0100321 ly_print(out, "%*sargument %s", LEVEL, INDENT, ext->argument);
322 i = -1;
Radek Krejcibf285832017-01-26 16:05:41 +0100323 while ((i = lys_ext_iter(ext->ext, ext->ext_size, i + 1, LYEXT_SUBSTMT_ARGUMENT)) != -1) {
Radek Krejcicfce0292017-01-13 12:37:57 +0100324 yang_print_open(out, &flag2);
325 yang_print_extension_instances(out, level + 1, ext->module, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->ext[i], 1);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900326 }
Radek Krejcibf285832017-01-26 16:05:41 +0100327 if ((ext->flags & LYS_YINELEM) || lys_ext_iter(ext->ext, ext->ext_size, 0, LYEXT_SUBSTMT_YINELEM) != -1) {
Radek Krejcicfce0292017-01-13 12:37:57 +0100328 yang_print_open(out, &flag2);
Radek Krejci87f90572017-01-24 11:19:42 +0100329 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, 0,
330 (ext->flags & LYS_YINELEM) ? "true" : "false", ext->module, ext->ext, ext->ext_size);
Radek Krejcicfce0292017-01-13 12:37:57 +0100331 }
332 yang_print_close(out, level, flag2);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900333 }
334
Radek Krejci5dd25122017-01-11 17:28:13 +0100335 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
336 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
337
Radek Krejcia1a6b762016-11-14 09:53:38 +0900338 level--;
339 yang_print_close(out, level, flag);
340}
341
342static void
Radek 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
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100417yang_print_unsigned(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
418 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size,
419 unsigned int attr_value)
420{
421 char *str;
422
423 asprintf(&str, "%u", attr_value);
424 yang_print_substmt(out, level, substmt, substmt_index, str, module, ext, ext_size);
425 free(str);
426}
427
428static void
429yang_print_signed(struct lyout *out, int level, LYEXT_SUBSTMT substmt, const struct lys_module *module,
430 struct lys_ext_instance **ext, unsigned int ext_size, signed int attr_value)
431{
432 char *str;
433
434 asprintf(&str, "%d", attr_value);
435 yang_print_substmt(out, level, substmt, 0, str, module, ext, ext_size);
436 free(str);
437}
438
439static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100440yang_print_type(struct lyout *out, int level, const struct lys_module *module, const struct lys_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200441{
Radek Krejci5dd25122017-01-11 17:28:13 +0100442 int i;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100443 int flag = 0, flag2;
Michal Vasko0fb82c62015-10-20 13:41:53 +0200444 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100445 char *s;
Radek Krejcic071c542016-01-27 14:57:51 +0100446 struct lys_module *mod;
Radek Krejci25d782a2015-05-22 15:03:23 +0200447
Michal Vasko0fb82c62015-10-20 13:41:53 +0200448 if (type->module_name) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100449 ly_print(out, "%*stype %s:%s", LEVEL, INDENT,
450 transform_module_name2import_prefix(module, type->module_name), type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200451 } else {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100452 ly_print(out, "%*stype %s", LEVEL, INDENT, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200453 }
454 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100455
456 /* extensions */
457 if (type->ext_size) {
458 yang_print_open(out, &flag);
459 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, type->ext, type->ext_size);
460 }
461
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200462 switch (type->base) {
463 case LY_TYPE_BINARY:
Michal Vasko4634cda2016-02-16 09:22:09 +0100464 if (type->info.binary.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100465 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100466 ly_print(out, "%*slength \"", LEVEL, INDENT);
467 yang_encode(out, type->info.binary.length->expr, -1);
468 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100469 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100470 yang_print_restr(out, level + 1, module, type->info.binary.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100471 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200472 }
473 break;
474 case LY_TYPE_BITS:
475 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100476 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100477 ly_print(out, "%*sbit %s", LEVEL, INDENT, type->info.bits.bit[i].name);
478 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200479 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100480 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
481 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100482 if (!(type->info.bits.bit[i].flags & LYS_AUTOASSIGNED)) {
483 yang_print_open(out, &flag2);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100484 yang_print_unsigned(out, level, LYEXT_SUBSTMT_POSITION, 0, module,
485 type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
486 type->info.bits.bit[i].pos);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100487 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100488 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
489 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200490 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100491 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200492 }
493 break;
494 case LY_TYPE_DEC64:
Radek Krejcib51d5932016-09-08 14:02:52 +0200495 if (!type->der->type.der) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100496 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100497 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, 0, module,
498 type->ext, type->ext_size, type->info.dec64.dig);
Michal Vasko4634cda2016-02-16 09:22:09 +0100499 }
Michal Vaskoea505ee2015-07-07 14:01:00 +0200500 if (type->info.dec64.range != NULL) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100501 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100502 ly_print(out, "%*srange \"", LEVEL, INDENT);
503 yang_encode(out, type->info.dec64.range->expr, -1);
504 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100505 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100506 yang_print_restr(out, level + 1, module, type->info.dec64.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100507 yang_print_close(out, level, flag2);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200508 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200509 break;
510 case LY_TYPE_ENUM:
511 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100512 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100513 ly_print(out, "%*senum \"%s\"", LEVEL, INDENT, type->info.enums.enm[i].name);
514 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200515 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100516 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
517 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100518 if (!(type->info.enums.enm[i].flags & LYS_AUTOASSIGNED)) {
519 yang_print_open(out, &flag2);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100520 yang_print_signed(out, level, LYEXT_SUBSTMT_VALUE, module,
521 type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
522 type->info.enums.enm[i].value);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100523 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100524 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
525 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200526 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100527 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200528 }
529 break;
530 case LY_TYPE_IDENT:
Michal Vaskof2d43962016-09-02 11:10:16 +0200531 if (type->info.ident.count) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100532 yang_print_open(out, &flag);
Michal Vaskof2d43962016-09-02 11:10:16 +0200533 for (i = 0; i < type->info.ident.count; ++i) {
534 mod = lys_main_module(type->info.ident.ref[i]->module);
535 if (lys_main_module(module) == mod) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100536 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, type->info.ident.ref[i]->name,
537 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
Michal Vaskof2d43962016-09-02 11:10:16 +0200538 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100539 asprintf(&s, "%s:%s", transform_module_name2import_prefix(module, mod->name),
540 type->info.ident.ref[i]->name);
541 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, s,
542 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
543 free(s);
Michal Vaskof2d43962016-09-02 11:10:16 +0200544 }
Michal Vasko4634cda2016-02-16 09:22:09 +0100545 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200546 }
547 break;
548 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200549 if (type->info.inst.req == 1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100550 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100551 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "true", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200552 } else if (type->info.inst.req == -1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100553 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100554 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "false", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200555 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200556 break;
557 case LY_TYPE_INT8:
558 case LY_TYPE_INT16:
559 case LY_TYPE_INT32:
560 case LY_TYPE_INT64:
561 case LY_TYPE_UINT8:
562 case LY_TYPE_UINT16:
563 case LY_TYPE_UINT32:
564 case LY_TYPE_UINT64:
Michal Vasko4634cda2016-02-16 09:22:09 +0100565 if (type->info.num.range) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100566 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100567 ly_print(out, "%*srange \"", LEVEL, INDENT);
568 yang_encode(out, type->info.num.range->expr, -1);
569 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100570 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100571 yang_print_restr(out, level + 1, module, type->info.num.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100572 yang_print_close(out, level, flag2);
Radek Krejcif2860132015-06-20 12:37:20 +0200573 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200574 break;
575 case LY_TYPE_LEAFREF:
Radek Krejci0dbff6a2016-07-17 12:40:18 +0200576 if (ly_strequal(type->der->name, "leafref", 0)) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100577 yang_print_open(out, &flag);
578 str = transform_json2schema(module, type->info.lref.path);
Radek Krejci43e3c312017-01-11 11:34:44 +0100579 yang_print_substmt(out, level, LYEXT_SUBSTMT_PATH, 0, str, module, type->ext, type->ext_size);
Michal Vasko4634cda2016-02-16 09:22:09 +0100580 lydict_remove(module->ctx, str);
581 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100582 if (type->info.lref.req == 1) {
583 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100584 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "true", module, type->ext, type->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100585 } else if (type->info.lref.req == -1) {
586 yang_print_open(out, &flag);
Radek Krejcibe336392017-02-07 10:54:24 +0100587 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINSTANCE, 0, "false", module, type->ext, type->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100588 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200589 break;
590 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200591 if (type->info.str.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100592 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100593 ly_print(out, "%*slength \"", LEVEL, INDENT);
594 yang_encode(out, type->info.str.length->expr, -1);
595 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100596 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100597 yang_print_restr(out, level + 1, module, type->info.str.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100598 yang_print_close(out, level, flag2);
Radek Krejci061bd522015-06-19 13:45:16 +0200599 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200600 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100601 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100602 ly_print(out, "%*spattern \"", LEVEL, INDENT);
Radek Krejci0d23e7a2016-08-04 12:46:17 +0200603 yang_encode(out, &type->info.str.patterns[i].expr[1], -1);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100604 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100605 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100606 yang_print_restr(out, level + 1, module, &type->info.str.patterns[i], &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100607 yang_print_close(out, level, flag2);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200608 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200609 break;
610 case LY_TYPE_UNION:
611 for (i = 0; i < type->info.uni.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100612 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200613 yang_print_type(out, level, module, &type->info.uni.types[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200614 }
615 break;
616 default:
617 /* other types do not have substatements */
618 break;
619 }
Radek Krejcie534c132016-11-23 13:32:31 +0100620
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200621 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100622 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200623}
624
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200625static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100626yang_print_must(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200627{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100628 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100629 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200630
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100631 str = transform_json2schema(module, must->expr);
632 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200633 ly_print(out, "(!error!)");
634 return;
635 }
636
Michal Vasko25cb6c62016-02-12 14:36:21 +0100637 ly_print(out, "%*smust \"", LEVEL, INDENT);
638 yang_encode(out, str, -1);
639 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100640 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200641
Radek Krejci43e3c312017-01-11 11:34:44 +0100642 yang_print_restr(out, level + 1, module, must, &flag);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100643 yang_print_close(out, level, flag);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200644}
645
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200646static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100647yang_print_unique(struct lyout *out, int level, const struct lys_unique *uniq)
Michal Vasko1ef07972015-07-07 14:01:35 +0200648{
649 int i;
650
Radek Krejci76b07902015-10-09 09:11:25 +0200651 ly_print(out, "%*sunique \"", LEVEL, INDENT);
Radek Krejci581ce772015-11-10 17:22:40 +0100652 for (i = 0; i < uniq->expr_size; i++) {
653 ly_print(out, "%s%s", uniq->expr[i], i + 1 < uniq->expr_size ? " " : "");
Michal Vasko1ef07972015-07-07 14:01:35 +0200654 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100655 ly_print(out, "\"");
Michal Vasko1ef07972015-07-07 14:01:35 +0200656}
657
658static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100659yang_print_refine(struct lyout *out, int level, const struct lys_module *module, const struct lys_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200660{
Radek Krejci5dd25122017-01-11 17:28:13 +0100661 int i, flag = 0;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200662 const char *str;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200663
Michal Vasko5d112852016-02-12 16:47:13 +0100664 str = transform_json2schema(module, refine->target_name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100665 ly_print(out, "%*srefine \"%s\"", LEVEL, INDENT, str);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200666 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200667 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200668
Radek Krejci5dd25122017-01-11 17:28:13 +0100669 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 +0200670 for (i = 0; i < refine->must_size; ++i) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100671 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200672 yang_print_must(out, level, module, &refine->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200673 }
Pavol Vican3e7c73a2016-08-17 10:24:11 +0200674 if (refine->target_type == LYS_CONTAINER) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100675 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100676 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, refine->mod.presence,
677 module, refine->ext, refine->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100678 }
679 for (i = 0; i < refine->dflt_size; ++i) {
680 yang_print_open(out, &flag);
681 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, refine->dflt[i], module, refine->ext, refine->ext_size);
682 }
683 if (refine->flags & LYS_CONFIG_W) {
684 yang_print_open(out, &flag);
685 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module, refine->ext, refine->ext_size);
686 } else if (refine->flags & LYS_CONFIG_R) {
687 yang_print_open(out, &flag);
688 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module, refine->ext, refine->ext_size);
689 }
690 if (refine->flags & LYS_MAND_TRUE) {
691 yang_print_open(out, &flag);
692 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module, refine->ext, refine->ext_size);
693 } else if (refine->flags & LYS_MAND_FALSE) {
694 yang_print_open(out, &flag);
695 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module, refine->ext, refine->ext_size);
696 }
697 if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200698 if (refine->flags & LYS_RFN_MINSET) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100699 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100700 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, module, refine->ext, refine->ext_size,
701 refine->mod.list.min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200702 }
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200703 if (refine->flags & LYS_RFN_MAXSET) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100704 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100705 if (refine->mod.list.max) {
706 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, module, refine->ext, refine->ext_size,
707 refine->mod.list.max);
708 } else {
709 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, "unbounded", module, refine->ext, refine->ext_size);
710 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200711 }
712 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100713 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 +0200714
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200715 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +0100716 yang_print_close(out, level, flag);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200717}
718
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200719static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100720yang_print_deviation(struct lyout *out, int level, const struct lys_module *module,
721 const struct lys_deviation *deviation)
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200722{
Radek Krejci033983b2017-01-13 12:43:20 +0100723 int i, j, p;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200724 const char *str;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200725
Michal Vasko5d112852016-02-12 16:47:13 +0100726 str = transform_json2schema(module, deviation->target_name);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200727 ly_print(out, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, str);
728 lydict_remove(module->ctx, str);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200729 level++;
730
Radek Krejci5dd25122017-01-11 17:28:13 +0100731 if (deviation->ext_size) {
732 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, deviation->ext, deviation->ext_size);
733 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100734 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, deviation->dsc,
735 module, deviation->ext, deviation->ext_size);
736 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, deviation->ref,
737 module, deviation->ext, deviation->ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200738
739 for (i = 0; i < deviation->deviate_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200740 ly_print(out, "%*sdeviate ", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200741 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100742 if (deviation->deviate[i].ext_size) {
743 ly_print(out, "not-supported {\n");
744 } else {
745 ly_print(out, "not-supported;\n");
746 continue;
747 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200748 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
Radek Krejci76b07902015-10-09 09:11:25 +0200749 ly_print(out, "add {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200750 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200751 ly_print(out, "replace {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200752 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200753 ly_print(out, "delete {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200754 }
755 level++;
756
Radek Krejci5dd25122017-01-11 17:28:13 +0100757 /* extensions */
758 if (deviation->deviate[i].ext_size) {
Radek Krejcia4c667f2017-01-24 15:59:23 +0100759 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
Radek Krejci5dd25122017-01-11 17:28:13 +0100760 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200761 }
762
Radek Krejci5dd25122017-01-11 17:28:13 +0100763 /* type */
764 if (deviation->deviate[i].type) {
765 yang_print_type(out, level, module, deviation->deviate[i].type);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200766 }
767
Radek Krejci5dd25122017-01-11 17:28:13 +0100768 /* units */
769 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, deviation->deviate[i].units, module,
770 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200771
Radek Krejci5dd25122017-01-11 17:28:13 +0100772 /* must */
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200773 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
Michal Vaskof9893382015-10-09 14:03:04 +0200774 yang_print_must(out, level, module, &deviation->deviate[i].must[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200775 }
776
Radek Krejci5dd25122017-01-11 17:28:13 +0100777 /* unique */
778
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200779 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
Radek Krejci76b07902015-10-09 09:11:25 +0200780 yang_print_unique(out, level, &deviation->deviate[i].unique[j]);
Radek Krejci43e3c312017-01-11 11:34:44 +0100781 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +0100782 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100783 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100784 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejcicfce0292017-01-13 12:37:57 +0100785 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100786 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100787 if (p != -1) {
788 ly_print(out, " {\n");
789 do {
790 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, j,
791 &deviation->deviate[i].ext[p], 1);
792 do {
Radek Krejcibf285832017-01-26 16:05:41 +0100793 p = lys_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
Radek Krejci43e3c312017-01-11 11:34:44 +0100794 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +0100795 } while (p != -1 && deviation->deviate[i].ext[p]->insubstmt_index != j);
Radek Krejci43e3c312017-01-11 11:34:44 +0100796 } while (p != -1);
797 ly_print(out, "%*s}\n", LEVEL, INDENT);
798 } else {
799 ly_print(out, ";\n");
800 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200801 }
802
Radek Krejci5dd25122017-01-11 17:28:13 +0100803 /* default */
Radek Krejci033983b2017-01-13 12:43:20 +0100804 for (j = 0; j < deviation->deviate[i].dflt_size; ++j) {
805 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, j, deviation->deviate[i].dflt[j], module,
Radek Krejci5dd25122017-01-11 17:28:13 +0100806 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200807 }
808
Radek Krejci5dd25122017-01-11 17:28:13 +0100809 /* config */
810 if (deviation->deviate[i].flags & LYS_CONFIG_W) {
811 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module,
812 deviation->deviate->ext, deviation->deviate[i].ext_size);
813 } else if (deviation->deviate[i].flags & LYS_CONFIG_R) {
814 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module,
815 deviation->deviate->ext, deviation->deviate[i].ext_size);
816 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100817
Radek Krejci5dd25122017-01-11 17:28:13 +0100818 /* mandatory */
819 if (deviation->deviate[i].flags & LYS_MAND_TRUE) {
820 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module,
821 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
822 } else if (deviation->deviate[i].flags & LYS_MAND_FALSE) {
823 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module,
824 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
825 }
826
827 /* min-elements */
828 if (deviation->deviate[i].min_set) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100829 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, module,
830 deviation->deviate[i].ext, deviation->deviate[i].ext_size,
831 deviation->deviate[i].min);
Radek Krejci5dd25122017-01-11 17:28:13 +0100832 }
833
834 /* max-elements */
835 if (deviation->deviate[i].max_set) {
836 if (deviation->deviate[i].max) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100837 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, module,
838 deviation->deviate[i].ext, deviation->deviate[i].ext_size,
839 deviation->deviate[i].max);
Radek Krejci5dd25122017-01-11 17:28:13 +0100840 } else {
Radek Krejci3a14dfd2017-02-07 13:27:33 +0100841 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, "unbounded", module,
842 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100843 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200844 }
845
846 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200847 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200848 }
849
850 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200851 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200852}
853
854static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100855yang_print_augment(struct lyout *out, int level, const struct lys_node_augment *augment)
Michal Vasko6f25f212015-07-07 15:42:07 +0200856{
Radek Krejci76512572015-08-04 09:47:08 +0200857 struct lys_node *sub;
Michal Vasko488c19e2015-10-20 15:21:00 +0200858 const char *str;
Michal Vasko6f25f212015-07-07 15:42:07 +0200859
Radek Krejci43e3c312017-01-11 11:34:44 +0100860 str = transform_json2schema(augment->module, augment->target_name);
Michal Vasko488c19e2015-10-20 15:21:00 +0200861 ly_print(out, "%*saugment \"%s\" {\n", LEVEL, INDENT, str);
Radek Krejci43e3c312017-01-11 11:34:44 +0100862 lydict_remove(augment->module->ctx, str);
Michal Vasko6f25f212015-07-07 15:42:07 +0200863 level++;
864
Radek Krejci5dd25122017-01-11 17:28:13 +0100865 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL, SNODE_COMMON_EXT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200866 if (augment->when) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100867 yang_print_when(out, level, augment->module, augment->when);
Michal Vasko6f25f212015-07-07 15:42:07 +0200868 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100869 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL,
870 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200871
872 LY_TREE_FOR(augment->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100873 /* only our augment */
874 if (sub->parent != (struct lys_node *)augment) {
875 continue;
876 }
Radek Krejci76b07902015-10-09 09:11:25 +0200877 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200878 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +0100879 LYS_USES | LYS_ANYDATA | LYS_CASE | LYS_ACTION | LYS_NOTIF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200880 }
881
882 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200883 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200884}
885
886static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100887yang_print_typedef(struct lyout *out, int level, const struct lys_module *module, const struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200888{
Radek Krejci033983b2017-01-13 12:43:20 +0100889 const char *dflt;
890
Radek Krejci76b07902015-10-09 09:11:25 +0200891 ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200892 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200893
Radek Krejci5dd25122017-01-11 17:28:13 +0100894 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL, SNODE_COMMON_EXT);
Radek Krejci76b07902015-10-09 09:11:25 +0200895 yang_print_type(out, level, module, &tpdf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200896 if (tpdf->units != NULL) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100897 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, module, tpdf->ext, tpdf->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200898 }
899 if (tpdf->dflt != NULL) {
Radek Krejcibd117f02016-11-04 16:28:08 +0100900 if (tpdf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +0100901 assert(strchr(tpdf->dflt, ':'));
902 if (!strncmp(tpdf->dflt, module->name, strchr(tpdf->dflt, ':') - tpdf->dflt)) {
903 /* local module */
904 dflt = lydict_insert(module->ctx, strchr(tpdf->dflt, ':') + 1, 0);
905 } else {
906 dflt = transform_json2schema(module, tpdf->dflt);
907 }
Radek Krejcibd117f02016-11-04 16:28:08 +0100908 } else {
909 dflt = tpdf->dflt;
910 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100911 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt, module, tpdf->ext, tpdf->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +0100912 if (tpdf->flags & LYS_DFLTJSON) {
913 lydict_remove(module->ctx, dflt);
914 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200915 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100916 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL,
917 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200918
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200919 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200920 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200921}
922
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200923static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100924yang_print_identity(struct lyout *out, int level, const struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200925{
Radek Krejci018f1f52016-08-03 16:01:20 +0200926 int flag = 0, i;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100927 struct lys_module *mod;
Radek Krejci43e3c312017-01-11 11:34:44 +0100928 char *str;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100929
930 ly_print(out, "%*sidentity %s", LEVEL, INDENT, ident->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200931 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200932
Radek Krejci5dd25122017-01-11 17:28:13 +0100933 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
934 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
935
Radek Krejci018f1f52016-08-03 16:01:20 +0200936 for (i = 0; i < ident->base_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100937 yang_print_open(out, &flag);
Radek Krejci018f1f52016-08-03 16:01:20 +0200938 mod = lys_main_module(ident->base[i]->module);
Radek Krejci43e3c312017-01-11 11:34:44 +0100939 if (lys_main_module(ident->module) == mod) {
Radek Krejcib5e58d32017-01-23 13:45:59 +0100940 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, ident->base[i]->name,
Radek Krejci43e3c312017-01-11 11:34:44 +0100941 ident->module, ident->ext, ident->ext_size);
942 } else {
943 asprintf(&str, "%s:%s", transform_module_name2import_prefix(ident->module, mod->name), ident->base[i]->name);
Radek Krejcib5e58d32017-01-23 13:45:59 +0100944 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, i, str,
Radek Krejci43e3c312017-01-11 11:34:44 +0100945 ident->module, ident->ext, ident->ext_size);
946 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200947 }
948 }
Radek Krejci6793db02015-05-22 17:49:54 +0200949
Radek Krejci5dd25122017-01-11 17:28:13 +0100950 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
951 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
952
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200953 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100954 yang_print_close(out, level, flag);
Radek Krejci6793db02015-05-22 17:49:54 +0200955}
956
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200957static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100958yang_print_container(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200959{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100960 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +0200961 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200962 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200963
Radek Krejci32cce7c2015-12-09 16:44:13 +0100964 ly_print(out, "%*scontainer %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200965 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200966
Radek Krejci5dd25122017-01-11 17:28:13 +0100967 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +0100968 if (cont->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100969 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +0100970 yang_print_when(out, level, node->module, cont->when);
971 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200972 for (i = 0; i < cont->iffeature_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +0100973 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +0200974 yang_print_iffeature(out, level, node->module, &cont->iffeature[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200975 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200976 for (i = 0; i < cont->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100977 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200978 yang_print_must(out, level, node->module, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200979 }
Radek Krejci8d81e002015-12-10 11:18:59 +0100980 if (cont->presence != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100981 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100982 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence,
983 node->module, node->ext, node->ext_size);
Michal Vasko4773b762015-07-07 12:15:10 +0200984 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100985 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG |
986 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200987 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100988 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200989 yang_print_typedef(out, level, node->module, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200990 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200991 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100992 /* augments */
993 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200994 continue;
995 }
Radek Krejci32cce7c2015-12-09 16:44:13 +0100996 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +0100997 yang_print_snode(out, level, sub, LYS_GROUPING);
998 }
999 LY_TREE_FOR(node->child, sub) {
1000 /* augments */
1001 if (sub->parent != node) {
1002 continue;
1003 }
1004 yang_print_open(out, &flag);
1005 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1006 LYS_USES | LYS_ANYDATA );
1007 }
1008 LY_TREE_FOR(node->child, sub) {
1009 /* augments */
1010 if (sub->parent != node) {
1011 continue;
1012 }
1013 yang_print_open(out, &flag);
1014 yang_print_snode(out, level, sub, LYS_ACTION);
1015 }
1016 LY_TREE_FOR(node->child, sub) {
1017 /* augments */
1018 if (sub->parent != node) {
1019 continue;
1020 }
1021 yang_print_open(out, &flag);
Radek Krejci033983b2017-01-13 12:43:20 +01001022 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001023 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001024
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001025 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001026 yang_print_close(out, level, flag);
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001027}
1028
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001029static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001030yang_print_case(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001031{
Radek Krejci5dd25122017-01-11 17:28:13 +01001032 int flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001033 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001034 struct lys_node_case *cas = (struct lys_node_case *)node;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001035
Radek Krejci5dd25122017-01-11 17:28:13 +01001036 ly_print(out, "%*scase %s", LEVEL, INDENT, cas->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001037 level++;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001038
Radek Krejci5dd25122017-01-11 17:28:13 +01001039 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001040 if (cas->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001041 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001042 yang_print_when(out, level, node->module, cas->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001043 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001044 yang_print_snode_common(out, level, node, node->module, &flag,
1045 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001046
Radek Krejci1d82ef62015-08-07 14:44:40 +02001047 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001048 /* augments */
1049 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001050 continue;
1051 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001052 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001053 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001054 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejcibf2abff2016-08-23 15:51:52 +02001055 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001056 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001057
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001058 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001059 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001060}
1061
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001062static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001063yang_print_choice(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001064{
Radek Krejci5dd25122017-01-11 17:28:13 +01001065 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001066 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001067 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001068
Radek Krejci5dd25122017-01-11 17:28:13 +01001069 ly_print(out, "%*schoice %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001070 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001071
1072 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1073 if (choice->when) {
1074 yang_print_open(out, &flag);
1075 yang_print_when(out, level, node->module, choice->when);
1076 }
1077 for (i = 0; i < choice->iffeature_size; i++) {
1078 yang_print_open(out, &flag);
1079 yang_print_iffeature(out, level, node->module, &choice->iffeature[i]);
1080 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001081 if (choice->dflt != NULL) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001082 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001083 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt->name,
1084 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001085 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001086 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1087 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001088
Radek Krejci1d82ef62015-08-07 14:44:40 +02001089 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001090 /* augments */
1091 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001092 continue;
1093 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001094 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001095 yang_print_snode(out, level, sub,
Radek Krejci5dd25122017-01-11 17:28:13 +01001096 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_CASE);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001097 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001098
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001099 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001100 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001101}
1102
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001103static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001104yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001105{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001106 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001107 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001108 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001109
Radek Krejci76b07902015-10-09 09:11:25 +02001110 ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001111 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001112
1113 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001114 if (leaf->when) {
1115 yang_print_when(out, level, node->module, leaf->when);
1116 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001117 for (i = 0; i < leaf->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001118 yang_print_iffeature(out, level, node->module, &leaf->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001119 }
Radek Krejci76b07902015-10-09 09:11:25 +02001120 yang_print_type(out, level, node->module, &leaf->type);
Radek Krejci43e3c312017-01-11 11:34:44 +01001121 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, leaf->units,
1122 node->module, node->ext, node->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +01001123 for (i = 0; i < leaf->must_size; i++) {
1124 yang_print_must(out, level, node->module, &leaf->must[i]);
1125 }
Michal Vaskod875e882016-05-19 10:57:30 +02001126 if (leaf->dflt) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001127 if (leaf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001128 assert(strchr(leaf->dflt, ':'));
1129 if (!strncmp(leaf->dflt, lys_node_module(node)->name, strchr(leaf->dflt, ':') - leaf->dflt)) {
1130 /* local module */
1131 dflt = lydict_insert(node->module->ctx, strchr(leaf->dflt, ':') + 1, 0);
1132 } else {
1133 dflt = transform_json2schema(node->module, leaf->dflt);
1134 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001135 } else {
1136 dflt = leaf->dflt;
1137 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001138 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt,
1139 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001140 if (leaf->flags & LYS_DFLTJSON) {
1141 lydict_remove(node->module->ctx, dflt);
1142 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001143 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001144 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1145 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001146 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001147 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +02001148}
1149
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001150static void
Radek Krejcibf2abff2016-08-23 15:51:52 +02001151yang_print_anydata(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko16083662015-06-09 14:00:45 +02001152{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001153 int i, flag = 0;
Radek Krejcibf2abff2016-08-23 15:51:52 +02001154 struct lys_node_anydata *any = (struct lys_node_anydata *)node;
Michal Vasko16083662015-06-09 14:00:45 +02001155
Radek Krejcibf2abff2016-08-23 15:51:52 +02001156 ly_print(out, "%*s%s %s", LEVEL, INDENT, any->nodetype == LYS_ANYXML ? "anyxml" : "anydata", any->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001157 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001158
1159 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1160 if (any->when) {
1161 yang_print_open(out, &flag);
1162 yang_print_when(out, level, node->module, any->when);
1163 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001164 for (i = 0; i < any->iffeature_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001165 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001166 yang_print_iffeature(out, level, node->module, &any->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001167 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001168 for (i = 0; i < any->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001169 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001170 yang_print_must(out, level, node->module, &any->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001171 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001172 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1173 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001174 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001175 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001176}
1177
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001178static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001179yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001180{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001181 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001182 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001183 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001184
Radek Krejci76b07902015-10-09 09:11:25 +02001185 ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001186 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001187 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001188 if (llist->when) {
1189 yang_print_when(out, level, llist->module, llist->when);
1190 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001191 for (i = 0; i < llist->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001192 yang_print_iffeature(out, level, node->module, &llist->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001193 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001194 yang_print_type(out, level, node->module, &llist->type);
1195 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, llist->units,
1196 node->module, node->ext, node->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001197 for (i = 0; i < llist->must_size; i++) {
1198 yang_print_must(out, level, node->module, &llist->must[i]);
1199 }
Pavol Vican38321d02016-08-16 14:56:02 +02001200 for (i = 0; i < llist->dflt_size; ++i) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001201 if (llist->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001202 assert(strchr(llist->dflt[i], ':'));
1203 if (!strncmp(llist->dflt[i], lys_node_module(node)->name, strchr(llist->dflt[i], ':') - llist->dflt[i])) {
1204 /* local module */
1205 dflt = lydict_insert(node->module->ctx, strchr(llist->dflt[i], ':') + 1, 0);
1206 } else {
1207 dflt = transform_json2schema(node->module, llist->dflt[i]);
1208 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001209 } else {
1210 dflt = llist->dflt[i];
1211 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001212 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, dflt,
1213 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001214 if (llist->flags & LYS_DFLTJSON) {
1215 lydict_remove(node->module->ctx, dflt);
1216 }
Pavol Vican38321d02016-08-16 14:56:02 +02001217 }
Radek Krejci178a0942017-01-16 15:36:35 +01001218 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001219 if (llist->min > 0) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001220 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, node->module, node->ext, node->ext_size, llist->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001221 }
1222 if (llist->max > 0) {
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001223 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, node->module, node->ext, node->ext_size, llist->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001224 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001225 if (llist->flags & LYS_USERORDERED) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001226 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1227 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001228 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001229 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1230 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001231 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001232 yang_print_snode_common(out, level, node, node->module, NULL,
1233 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001234 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001235 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001236}
1237
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001238static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001239yang_print_list(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001240{
Radek Krejci5dd25122017-01-11 17:28:13 +01001241 int i, p, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001242 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001243 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001244
Radek Krejci5dd25122017-01-11 17:28:13 +01001245 ly_print(out, "%*slist %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001246 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001247 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001248 if (list->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001249 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001250 yang_print_when(out, level, list->module, list->when);
1251 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001252 for (i = 0; i < list->iffeature_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001253 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001254 yang_print_iffeature(out, level, node->module, &list->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001255 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001256 for (i = 0; i < list->must_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001257 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001258 yang_print_must(out, level, list->module, &list->must[i]);
1259 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001260 if (list->keys_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001261 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001262 yang_print_substmt(out, level, LYEXT_SUBSTMT_KEY, 0, list->keys_str,
1263 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001264 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001265 for (i = 0; i < list->unique_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001266 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001267 yang_print_unique(out, level, &list->unique[i]);
Radek Krejci43e3c312017-01-11 11:34:44 +01001268 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +01001269 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +01001270 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 if (p != -1) {
1274 ly_print(out, " {\n");
1275 do {
1276 yang_print_extension_instances(out, level + 1, list->module, LYEXT_SUBSTMT_UNIQUE, i, &list->ext[p], 1);
1277 do {
Radek Krejcibf285832017-01-26 16:05:41 +01001278 p = lys_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejcifebdad72017-02-06 11:35:51 +01001279 } while (p != -1 && list->ext[p]->insubstmt_index != i);
Radek Krejci43e3c312017-01-11 11:34:44 +01001280 } while (p != -1);
1281 ly_print(out, "%*s}\n", LEVEL, INDENT);
1282 } else {
1283 ly_print(out, ";\n");
1284 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001285 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001286 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001287 if (list->min > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001288 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001289 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MIN, 0, node->module, node->ext, node->ext_size, list->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001290 }
1291 if (list->max > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001292 yang_print_open(out, &flag);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001293 yang_print_unsigned(out, level, LYEXT_SUBSTMT_MAX, 0, node->module, node->ext, node->ext_size, list->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001294 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001295 if (list->flags & LYS_USERORDERED) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001296 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001297 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1298 node->module, node->ext, node->ext_size);
Radek Krejcibf285832017-01-26 16:05:41 +01001299 } else if (lys_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001300 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001301 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1302 node->module, node->ext, node->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001303 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001304 yang_print_snode_common(out, level, node, node->module, &flag,
1305 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001306 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001307 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001308 yang_print_typedef(out, level, list->module, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001309 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001310
Radek Krejci1d82ef62015-08-07 14:44:40 +02001311 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001312 /* augments */
1313 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001314 continue;
1315 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001316 yang_print_open(out, &flag);
1317 yang_print_snode(out, level, sub, LYS_GROUPING);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001318 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001319
1320 LY_TREE_FOR(node->child, sub) {
1321 /* augments */
1322 if (sub->parent != node) {
1323 continue;
1324 }
1325 yang_print_open(out, &flag);
1326 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1327 LYS_USES | LYS_GROUPING | LYS_ANYDATA);
1328 }
1329
1330 LY_TREE_FOR(node->child, sub) {
1331 /* augments */
1332 if (sub->parent != node) {
1333 continue;
1334 }
1335 yang_print_open(out, &flag);
1336 yang_print_snode(out, level, sub, LYS_ACTION);
1337 }
1338
1339 LY_TREE_FOR(node->child, sub) {
1340 /* augments */
1341 if (sub->parent != node) {
1342 continue;
1343 }
1344 yang_print_open(out, &flag);
1345 yang_print_snode(out, level, sub, LYS_NOTIF);
1346 }
1347
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001348 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001349 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001350}
1351
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001352static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001353yang_print_grouping(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001354{
Radek Krejci5dd25122017-01-11 17:28:13 +01001355 int i, flag = 0;
Michal Vasko0c5e9282016-02-15 13:11:57 +01001356 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001357 struct lys_node_grp *grp = (struct lys_node_grp *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001358
Radek Krejci5dd25122017-01-11 17:28:13 +01001359 ly_print(out, "%*sgrouping %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001360 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001361
Radek Krejci5dd25122017-01-11 17:28:13 +01001362 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_STATUS |
1363 SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001364
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001365 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001366 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001367 yang_print_typedef(out, level, node->module, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001368 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001369
Michal Vasko0c5e9282016-02-15 13:11:57 +01001370 LY_TREE_FOR(node->child, sub) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001371 yang_print_open(out, &flag);
1372 yang_print_snode(out, level, sub, LYS_GROUPING);
1373 }
1374
1375 LY_TREE_FOR(node->child, sub) {
1376 yang_print_open(out, &flag);
1377 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1378 LYS_USES | LYS_ANYDATA);
1379 }
1380
1381 LY_TREE_FOR(node->child, sub) {
1382 yang_print_open(out, &flag);
1383 yang_print_snode(out, level, sub, LYS_ACTION);
1384 }
1385
1386 LY_TREE_FOR(node->child, sub) {
1387 yang_print_open(out, &flag);
1388 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001389 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001390
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001391 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001392 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001393}
1394
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001395static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001396yang_print_uses(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001397{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001398 int i, flag = 0;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001399 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001400 struct lys_module *mod;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001401
Radek Krejci76b07902015-10-09 09:11:25 +02001402 ly_print(out, "%*suses ", LEVEL, INDENT);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001403 if (node->child) {
Michal Vasko6c629ac2016-02-15 14:08:23 +01001404 mod = lys_node_module(node->child);
Michal Vasko1dae8ec2016-02-15 14:49:01 +01001405 if (lys_node_module(node) != mod) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001406 ly_print(out, "%s:", transform_module_name2import_prefix(node->module, mod->name));
1407 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +02001408 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001409 ly_print(out, "%s", uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001410 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001411
Radek Krejci5dd25122017-01-11 17:28:13 +01001412 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001413 if (uses->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001414 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001415 yang_print_when(out, level, node->module, uses->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001416 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001417 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_IFF |
1418 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001419 for (i = 0; i < uses->refine_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001420 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001421 yang_print_refine(out, level, node->module, &uses->refine[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001422 }
Michal Vasko6f25f212015-07-07 15:42:07 +02001423 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001424 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001425 yang_print_augment(out, level, &uses->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001426 }
1427
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001428 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001429 yang_print_close(out, level, flag);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001430}
1431
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001432static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001433yang_print_input_output(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko5bbae102015-06-16 12:16:44 +02001434{
Michal Vaskof4d3d742015-06-16 11:51:09 +02001435 int i;
Radek Krejci76512572015-08-04 09:47:08 +02001436 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001437 struct lys_node_inout *inout = (struct lys_node_inout *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001438
Radek Krejci76b07902015-10-09 09:11:25 +02001439 ly_print(out, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LYS_INPUT ? "input" : "output"));
Michal Vaskof4d3d742015-06-16 11:51:09 +02001440 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001441
Radek Krejcie534c132016-11-23 13:32:31 +01001442 if (node->ext_size) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001443 yang_print_extension_instances(out, level, node->module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001444 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001445 for (i = 0; i < inout->must_size; i++) {
1446 yang_print_must(out, level, node->module, &inout->must[i]);
1447 }
Radek Krejcie534c132016-11-23 13:32:31 +01001448 for (i = 0; i < inout->tpdf_size; i++) {
1449 yang_print_typedef(out, level, node->module, &inout->tpdf[i]);
1450 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001451 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001452 /* augments */
1453 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001454 continue;
1455 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001456 yang_print_snode(out, level, sub, LYS_GROUPING);
1457 }
1458 LY_TREE_FOR(node->child, sub) {
1459 /* augments */
1460 if (sub->parent != node) {
1461 continue;
1462 }
1463 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1464 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001465 }
1466
1467 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001468 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001469}
1470
1471static void
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001472yang_print_rpc_action(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskof4d3d742015-06-16 11:51:09 +02001473{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001474 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001475 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001476 struct lys_node_rpc_action *rpc = (struct lys_node_rpc_action *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001477
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001478 ly_print(out, "%*s%s %s", LEVEL, INDENT, (node->nodetype == LYS_RPC ? "rpc" : "action"), node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001479
1480 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001481 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF |
1482 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko4773b762015-07-07 12:15:10 +02001483
Michal Vaskof4d3d742015-06-16 11:51:09 +02001484 for (i = 0; i < rpc->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001485 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001486 yang_print_typedef(out, level, node->module, &rpc->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001487 }
1488
Radek Krejci1d82ef62015-08-07 14:44:40 +02001489 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001490 /* augments */
1491 if (sub->parent != node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001492 continue;
1493 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001494 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +01001495 yang_print_snode(out, level, sub, LYS_GROUPING);
1496 }
1497
1498 LY_TREE_FOR(node->child, sub) {
1499 /* augments */
1500 if (sub->parent != node) {
1501 continue;
1502 }
1503 yang_print_open(out, &flag);
1504 yang_print_snode(out, level, sub, LYS_INPUT);
1505 }
1506
1507 LY_TREE_FOR(node->child, sub) {
Michal Vasko8b942f02017-01-24 13:12:59 +01001508 /* augments and implicit nodes */
1509 if ((sub->parent != node) || ((sub->nodetype & (LYS_INPUT | LYS_OUTPUT) && (sub->flags & LYS_IMPLICIT)))) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001510 continue;
1511 }
1512 yang_print_open(out, &flag);
1513 yang_print_snode(out, level, sub, LYS_OUTPUT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001514 }
1515
1516 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001517 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001518}
1519
1520static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001521yang_print_notif(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko7690bc12015-06-16 12:26:05 +02001522{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001523 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001524 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001525 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001526
Radek Krejci32cce7c2015-12-09 16:44:13 +01001527 ly_print(out, "%*snotification %s", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001528
1529 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001530 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Radek Krejci12032a52016-07-29 15:42:56 +02001531 for (i = 0; i < notif->must_size; i++) {
1532 yang_print_open(out, &flag);
1533 yang_print_must(out, level, node->module, &notif->must[i]);
1534 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001535 yang_print_snode_common(out, level, node, node->module, &flag,
1536 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
1537 for (i = 0; i < notif->tpdf_size; i++) {
1538 yang_print_open(out, &flag);
1539 yang_print_typedef(out, level, node->module, &notif->tpdf[i]);
1540 }
1541 LY_TREE_FOR(node->child, sub) {
1542 /* augments */
1543 if (sub->parent != node) {
1544 continue;
1545 }
1546 yang_print_open(out, &flag);
1547 yang_print_snode(out, level, sub, LYS_GROUPING);
1548 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001549 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001550 /* augments */
1551 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001552 continue;
1553 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001554 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001555 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001556 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +01001557 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001558 }
1559
1560 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001561 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001562}
1563
1564static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001565yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001566{
Radek Krejci2c99a622017-01-12 10:11:13 +01001567 if (node->nodetype & mask) {
1568 if ((node->nodetype & (LYS_INPUT | LYS_OUTPUT)) && (node->flags & LYS_IMPLICIT)) {
1569 /* implicit input/output node is not supposed to be printed */
1570 return;
1571 } else if (!node->parent ||
1572 (node->parent->nodetype == LYS_AUGMENT && node != node->parent->child) ||
1573 (node->parent->nodetype != LYS_AUGMENT && node->prev->next)) {
1574 /* do not print the blank line before the first data-def node */
1575 ly_print(out, "\n");
1576 }
1577 }
1578
Radek Krejci1d82ef62015-08-07 14:44:40 +02001579 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +02001580 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +02001581 yang_print_container(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001582 break;
Radek Krejci76512572015-08-04 09:47:08 +02001583 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +02001584 yang_print_choice(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001585 break;
Radek Krejci76512572015-08-04 09:47:08 +02001586 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +02001587 yang_print_leaf(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001588 break;
Radek Krejci76512572015-08-04 09:47:08 +02001589 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001590 yang_print_leaflist(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001591 break;
Radek Krejci76512572015-08-04 09:47:08 +02001592 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001593 yang_print_list(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001594 break;
Radek Krejci76512572015-08-04 09:47:08 +02001595 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +02001596 yang_print_uses(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001597 break;
Radek Krejci76512572015-08-04 09:47:08 +02001598 case LYS_GROUPING:
Radek Krejci76b07902015-10-09 09:11:25 +02001599 yang_print_grouping(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001600 break;
Radek Krejci76512572015-08-04 09:47:08 +02001601 case LYS_ANYXML:
Radek Krejcibf2abff2016-08-23 15:51:52 +02001602 case LYS_ANYDATA:
1603 yang_print_anydata(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001604 break;
Radek Krejci76512572015-08-04 09:47:08 +02001605 case LYS_CASE:
Radek Krejci76b07902015-10-09 09:11:25 +02001606 yang_print_case(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001607 break;
Radek Krejci5dd25122017-01-11 17:28:13 +01001608 case LYS_RPC:
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001609 case LYS_ACTION:
1610 yang_print_rpc_action(out, level, node);
1611 break;
Radek Krejci76512572015-08-04 09:47:08 +02001612 case LYS_INPUT:
1613 case LYS_OUTPUT:
Radek Krejci2c99a622017-01-12 10:11:13 +01001614 yang_print_input_output(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001615 break;
Michal Vaskob15cae22016-09-15 09:40:56 +02001616 case LYS_NOTIF:
1617 yang_print_notif(out, level, node);
1618 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001619 default:
1620 break;
1621 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001622}
1623
Radek Krejci37f9ba32017-02-10 16:50:35 +01001624static int
1625yang_print_model_(struct lyout *out, int level, const struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001626{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001627 unsigned int i;
Radek Krejci37f9ba32017-02-10 16:50:35 +01001628 int p;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001629
Radek Krejci1d82ef62015-08-07 14:44:40 +02001630 struct lys_node *node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001631
Radek Krejci8d81e002015-12-10 11:18:59 +01001632 /* (sub)module-header-stmts */
Michal Vasko116172e2015-07-07 11:54:37 +02001633 if (module->type) {
Radek Krejci37f9ba32017-02-10 16:50:35 +01001634 ly_print(out, "%*ssubmodule %s {%s\n", LEVEL, INDENT, module->name,
1635 (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001636 level++;
Radek Krejci77424f72017-01-20 13:21:09 +01001637 if (lys_main_module(module)->version > 1 ||
Radek Krejcibf285832017-01-26 16:05:41 +01001638 lys_ext_iter(module->ext, module->ext_size, 0, LYEXT_SUBSTMT_VERSION) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001639 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0,
1640 ((struct lys_submodule *)module)->belongsto->version == 2 ? "1.1" : "1",
1641 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001642 }
Radek Krejci76b07902015-10-09 09:11:25 +02001643 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Radek Krejcicfce0292017-01-13 12:37:57 +01001644 p = -1;
Radek Krejcibf285832017-01-26 16:05:41 +01001645 while ((p = lys_ext_iter(module->ext, module->ext_size, p + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001646 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0, &module->ext[p], 1);
1647 }
1648 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1649 module, module->ext, module->ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001650 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001651 } else {
Radek Krejci37f9ba32017-02-10 16:50:35 +01001652 ly_print(out, "%*smodule %s {%s\n", LEVEL, INDENT, module->name,
1653 (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001654 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001655 if (module->version) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001656 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == 2 ? "1.1" : "1",
1657 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001658 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001659 yang_print_substmt(out, level, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns,
1660 module, module->ext, module->ext_size);
1661 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1662 module, module->ext, module->ext_size);
Michal Vasko116172e2015-07-07 11:54:37 +02001663 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001664
Radek Krejci8d81e002015-12-10 11:18:59 +01001665 /* linkage-stmts */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001666 for (i = 0; i < module->imp_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001667 ly_print(out, "\n%*simport %s {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001668 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001669 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1670 module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci39228d22017-01-13 12:43:55 +01001671 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->imp[i].prefix,
1672 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001673 if (module->imp[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001674 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->imp[i].rev,
1675 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001676 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001677 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->imp[i].dsc,
1678 module, module->imp[i].ext, module->imp[i].ext_size);
1679 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->imp[i].ref,
1680 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001681 level--;
Michal Vaskoc8e3ce02016-02-12 14:28:35 +01001682 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001683 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001684 for (i = 0; i < module->inc_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001685 if (module->inc[i].rev[0] || module->inc[i].dsc || module->inc[i].ref || module->inc[i].ext_size) {
1686 ly_print(out, "\n%*sinclude %s {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci8d81e002015-12-10 11:18:59 +01001687 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001688 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1689 module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001690 if (module->inc[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001691 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->inc[i].rev,
1692 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001693 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001694 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->inc[i].dsc,
1695 module, module->inc[i].ext, module->inc[i].ext_size);
1696 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->inc[i].ref,
1697 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001698 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001699 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001700 } else {
Radek Krejcie534c132016-11-23 13:32:31 +01001701 ly_print(out, "\n%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001702 }
1703 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001704
Radek Krejci8d81e002015-12-10 11:18:59 +01001705 /* meta-stmts */
1706 if (module->org || module->contact || module->dsc || module->ref) {
1707 ly_print(out, "\n");
1708 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001709 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org,
1710 module, module->ext, module->ext_size);
1711 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONTACT, 0, module->contact,
1712 module, module->ext, module->ext_size);
1713 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc,
1714 module, module->ext, module->ext_size);
1715 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->ref,
1716 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001717
1718 /* revision-stmts */
1719 if (module->rev_size) {
1720 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001721 }
1722 for (i = 0; i < module->rev_size; i++) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001723 if (module->rev[i].dsc || module->rev[i].ref || module->rev[i].ext_size) {
Radek Krejci76b07902015-10-09 09:11:25 +02001724 ly_print(out, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci5dd25122017-01-11 17:28:13 +01001725 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1726 module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci43e3c312017-01-11 11:34:44 +01001727 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_DESCRIPTION, 0, module->rev[i].dsc,
1728 module, module->rev[i].ext, module->rev[i].ext_size);
1729 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_REFERENCE, 0, module->rev[i].ref,
1730 module, module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001731 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001732 } else {
Michal Vasko86dfd262016-02-15 14:26:31 +01001733 ly_print(out, "%*srevision %s;\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001734 }
1735 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001736
Radek Krejci8d81e002015-12-10 11:18:59 +01001737 /* body-stmts */
Radek Krejcie534c132016-11-23 13:32:31 +01001738 for (i = 0; i < module->extensions_size; i++) {
1739 ly_print(out, "\n");
1740 yang_print_extension(out, level, &module->extensions[i]);
1741 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001742 if (module->ext_size) {
1743 ly_print(out, "\n");
1744 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, module->ext, module->ext_size);
1745 }
Radek Krejcie534c132016-11-23 13:32:31 +01001746
Michal Vasko30f6e912015-07-07 12:24:27 +02001747 for (i = 0; i < module->features_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001748 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001749 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001750 }
1751
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001752 for (i = 0; i < module->ident_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001753 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001754 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001755 }
Radek Krejci6793db02015-05-22 17:49:54 +02001756
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001757 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001758 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001759 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001760 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001761
Radek Krejci5dd25122017-01-11 17:28:13 +01001762 LY_TREE_FOR(lys_main_module(module)->data, node) {
1763 if (node->module != module) {
1764 /* data from submodules */
1765 continue;
1766 }
1767 yang_print_snode(out, level, node, LYS_GROUPING);
Radek Krejci8d81e002015-12-10 11:18:59 +01001768 }
1769
Radek Krejcic4283442016-04-22 09:19:27 +02001770 LY_TREE_FOR(lys_main_module(module)->data, node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001771 if (node->module != module) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001772 /* data from submodules */
Radek Krejcic071c542016-01-27 14:57:51 +01001773 continue;
1774 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001775 yang_print_snode(out, level, node, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1776 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001777 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001778
Michal Vasko6f25f212015-07-07 15:42:07 +02001779 for (i = 0; i < module->augment_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001780 ly_print(out, "\n");
Radek Krejci43e3c312017-01-11 11:34:44 +01001781 yang_print_augment(out, level, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001782 }
1783
Radek Krejci5dd25122017-01-11 17:28:13 +01001784 LY_TREE_FOR(lys_main_module(module)->data, node) {
1785 if (node->module != module) {
1786 /* data from submodules */
1787 continue;
1788 }
1789 yang_print_snode(out, level, node, LYS_RPC | LYS_ACTION);
1790 }
1791
1792 LY_TREE_FOR(lys_main_module(module)->data, node) {
1793 if (node->module != module) {
1794 /* data from submodules */
1795 continue;
1796 }
1797 yang_print_snode(out, level, node, LYS_NOTIF);
1798 }
1799
1800 for (i = 0; i < module->deviation_size; ++i) {
1801 ly_print(out, "\n");
1802 yang_print_deviation(out, level, module, &module->deviation[i]);
1803 }
1804
Radek Krejci37f9ba32017-02-10 16:50:35 +01001805 level--;
1806 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko95068c42016-03-24 14:58:11 +01001807 ly_print_flush(out);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001808
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001809 return EXIT_SUCCESS;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001810}
1811
Radek Krejci37f9ba32017-02-10 16:50:35 +01001812int
1813yang_print_model(struct lyout *out, const struct lys_module *module)
1814{
1815 return yang_print_model_(out, 0, module);
1816}
1817
Radek Krejci8d6b7422017-02-03 14:42:13 +01001818static void
Radek Krejcic1885952017-02-07 09:37:51 +01001819yang_print_extcomplex_bool(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001820 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001821 const char *true_val, const char *false_val, int *content)
1822{
1823 struct lyext_substmt *info;
1824 uint8_t *val;
1825
1826 val = lys_ext_complex_get_substmt(stmt, ext, &info);
1827 if (!val || !(*val)) {
1828 return;
1829 }
1830
1831 yang_print_open(out, content);
1832 if (*val == 1) {
Radek Krejcibe336392017-02-07 10:54:24 +01001833 yang_print_substmt(out, level, stmt, 0, true_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001834 } else if (*val == 2) {
Radek Krejcibe336392017-02-07 10:54:24 +01001835 yang_print_substmt(out, level, stmt, 0, false_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001836 } else {
1837 LOGINT;
1838 }
1839}
1840
1841static void
Radek Krejci8d6b7422017-02-03 14:42:13 +01001842yang_print_extcomplex_str(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001843 struct lys_ext_instance_complex *ext, LY_STMT stmt, int *content)
Radek Krejci8d6b7422017-02-03 14:42:13 +01001844{
1845 struct lyext_substmt *info;
1846 const char **str;
1847 int c;
1848
1849 str = lys_ext_complex_get_substmt(stmt, ext, &info);
1850 if (!str || !(*str)) {
1851 return;
1852 }
1853 if (info->cardinality >= LY_STMT_CARD_SOME) {
1854 /* we have array */
1855 for (str = (const char **)(*str), c = 0; *str; str++, c++) {
1856 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001857 yang_print_substmt(out, level, stmt, c, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001858 }
1859 } else {
1860 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001861 yang_print_substmt(out, level, stmt, 0, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001862 }
1863}
1864
Radek Krejcic1885952017-02-07 09:37:51 +01001865/* val1 is supposed to be the default value */
1866static void
1867yang_print_extcomplex_flags(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001868 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001869 const char *val1_str, const char *val2_str, uint16_t val1, uint16_t val2,
1870 int *content)
1871{
1872 const char *str;
1873 uint16_t *flags;
1874
1875 flags = lys_ext_complex_get_substmt(stmt, ext, NULL);
1876 if (!flags) {
1877 return;
1878 }
1879
1880 if (val1 & *flags) {
1881 str = val1_str;
1882 } else if (val2 & *flags) {
1883 str = val2_str;
Radek Krejcibe336392017-02-07 10:54:24 +01001884 } else if (lys_ext_iter(ext->ext, ext->ext_size, 0, stmt) != -1) {
Radek Krejcic1885952017-02-07 09:37:51 +01001885 /* flag not set, but since there are some extension, we are going to print the default value */
1886 str = val1_str;
1887 } else {
1888 return;
1889 }
1890
1891 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001892 yang_print_substmt(out, level, stmt, 0, str, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001893}
1894
Radek Krejci8d6b7422017-02-03 14:42:13 +01001895static void
1896yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
1897 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
1898 struct lys_ext_instance **ext, unsigned int count)
1899{
1900 unsigned int u, x;
1901 struct lys_module *mod;
1902 const char *prefix = NULL, *str;
Radek Krejci897d6072017-02-09 16:00:01 +01001903 int content, i, j, c;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001904 struct lyext_substmt *info;
1905 uint16_t *flags;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001906 void **pp, *p;
Radek Krejcif95b6292017-02-13 15:57:37 +01001907 struct lys_node *siter;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001908
Radek Krejcif95b6292017-02-13 15:57:37 +01001909#define YANG_PRINT_EXTCOMPLEX_SNODE(STMT) \
1910 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
1911 if (!pp || !(*pp)) { break; } \
1912 LY_TREE_FOR((struct lys_node*)(*pp), siter) { \
1913 if (lys_snode2stmt(siter->nodetype) == STMT) { \
1914 yang_print_open(out, &content); \
1915 yang_print_snode(out, level, siter, LYS_ANY); \
1916 } \
1917 }
Radek Krejci8d6b7422017-02-03 14:42:13 +01001918#define YANG_PRINT_EXTCOMPLEX_STRUCT(STMT, TYPE, FUNC) \
Radek Krejcifebdad72017-02-06 11:35:51 +01001919 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001920 if (!pp || !(*pp)) { break; } \
Radek Krejcifebdad72017-02-06 11:35:51 +01001921 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001922 for (pp = *pp; *pp; pp++) { \
1923 yang_print_open(out, &content); \
Radek Krejci37f9ba32017-02-10 16:50:35 +01001924 FUNC(out, level, (TYPE *)(*pp)); \
1925 } \
1926 } else { /* single item */ \
1927 yang_print_open(out, &content); \
1928 FUNC(out, level, (TYPE *)(*pp)); \
1929 }
1930#define YANG_PRINT_EXTCOMPLEX_STRUCT_M(STMT, TYPE, FUNC) \
1931 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
1932 if (!pp || !(*pp)) { break; } \
1933 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
1934 for (pp = *pp; *pp; pp++) { \
1935 yang_print_open(out, &content); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001936 FUNC(out, level, module, (TYPE *)(*pp)); \
1937 } \
1938 } else { /* single item */ \
1939 yang_print_open(out, &content); \
1940 FUNC(out, level, module, (TYPE *)(*pp)); \
1941 }
Radek Krejci5496fae2017-02-10 13:26:48 +01001942#define YANG_PRINT_EXTCOMPLEX_INT(STMT, TYPE) \
1943 p = &((struct lys_ext_instance_complex*)ext[u])->content[info[i].offset]; \
1944 if (!p) { break; } \
1945 if (info->cardinality >= LY_STMT_CARD_SOME) { /* we have array */ \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001946 for (c = 0; (*(TYPE***)p)[c]; c++) { \
Radek Krejci5496fae2017-02-10 13:26:48 +01001947 yang_print_open(out, &content); \
1948 yang_print_unsigned(out, level, STMT, c, module, \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001949 ext[u]->ext, ext[u]->ext_size, *(*(TYPE***)p)[c]); \
Radek Krejci5496fae2017-02-10 13:26:48 +01001950 } \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001951 } else if ((*(TYPE**)p)) { \
Radek Krejci5496fae2017-02-10 13:26:48 +01001952 yang_print_open(out, &content); \
1953 yang_print_unsigned(out, level, STMT, 0, module, \
Radek Krejcif8d05c22017-02-10 15:33:35 +01001954 ext[u]->ext, ext[u]->ext_size, (**(TYPE**)p)); \
Radek Krejci5496fae2017-02-10 13:26:48 +01001955 }
Radek Krejci8d6b7422017-02-03 14:42:13 +01001956
1957 for (u = 0; u < count; u++) {
1958 if (ext[u]->flags & LYEXT_OPT_INHERIT) {
1959 /* ignore the inherited extensions which were not explicitely instantiated in the module */
1960 continue;
Radek Krejcifebdad72017-02-06 11:35:51 +01001961 } else if (ext[u]->insubstmt != substmt || ext[u]->insubstmt_index != substmt_index) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001962 /* do not print the other substatement than the required */
1963 continue;
1964 }
1965
1966 mod = lys_main_module(ext[u]->def->module);
1967 if (mod == lys_main_module(module)) {
1968 prefix = module->prefix;
1969 } else {
1970 for (x = 0; x < module->imp_size; x++) {
1971 if (mod == module->imp[x].module) {
1972 prefix = module->imp[x].prefix;
1973 break;
1974 }
1975 }
1976 }
1977
1978 content = 0;
1979 ly_print(out, "%*s%s:%s", LEVEL, INDENT, prefix, ext[u]->def->name);
1980 /* extension - generic part */
1981 if (ext[u]->arg_value) {
1982 ly_print(out, " \"%s\"", ext[u]->arg_value);
1983 }
1984
1985 /* extensions in extension instance */
1986 if (ext[u]->ext_size) {
1987 yang_print_open(out, &content);
1988 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1989 ext[u]->ext, ext[u]->ext_size);
1990 }
1991
1992 /* extension - type-specific part */
1993 switch(lys_ext_instance_type(ext[u])) {
1994 case LYEXT_FLAG:
1995 /* flag extension - nothing special */
1996 break;
1997 case LYEXT_COMPLEX:
Radek Krejcifebdad72017-02-06 11:35:51 +01001998 info = ((struct lys_ext_instance_complex*)ext[u])->substmt; /* shortcut */
1999 if (!info) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01002000 /* no content */
2001 break;
2002 }
2003 level++;
Radek Krejcifebdad72017-02-06 11:35:51 +01002004 for (i = 0; info[i].stmt; i++) {
2005 switch(info[i].stmt) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01002006 case LY_STMT_DESCRIPTION:
Radek Krejci8d6b7422017-02-03 14:42:13 +01002007 case LY_STMT_REFERENCE:
Radek Krejci8d6b7422017-02-03 14:42:13 +01002008 case LY_STMT_UNITS:
Radek Krejcibe336392017-02-07 10:54:24 +01002009 case LY_STMT_ARGUMENT:
2010 case LY_STMT_DEFAULT:
2011 case LY_STMT_ERRTAG:
2012 case LY_STMT_ERRMSG:
2013 case LY_STMT_PREFIX:
2014 case LY_STMT_NAMESPACE:
2015 case LY_STMT_PRESENCE:
2016 case LY_STMT_REVISIONDATE:
2017 case LY_STMT_KEY:
2018 case LY_STMT_BASE:
Radek Krejcibe336392017-02-07 10:54:24 +01002019 case LY_STMT_CONTACT:
2020 case LY_STMT_ORGANIZATION:
2021 case LY_STMT_PATH:
2022 case LY_STMT_VERSION:
2023 case LY_STMT_VALUE:
Radek Krejci8d6b7422017-02-03 14:42:13 +01002024 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002025 info[i].stmt, &content);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002026 break;
Radek Krejci897d6072017-02-09 16:00:01 +01002027 case LY_STMT_BELONGSTO:
2028 pp = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, (struct lys_ext_instance_complex*)ext[u], NULL);
2029 if (!pp || !(*pp)) {
2030 break;
2031 }
2032 if (info->cardinality >= LY_STMT_CARD_SOME) {
2033 /* we have array */
2034 for (c = 0; ((const char***)pp)[0][c]; c++) {
2035 yang_print_open(out, &content);
2036 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((const char ***)pp)[0][c]);
2037 j = -1;
2038 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2039 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, c,
2040 &ext[u]->ext[j], 1);
2041 }
2042 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, c, ((const char ***)pp)[1][c],
2043 module, ext[u]->ext, ext[u]->ext_size);
2044 ly_print(out, "%*s}\n", LEVEL, INDENT);
2045 }
2046 } else {
2047 yang_print_open(out, &content);
2048 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, (const char *)pp[0]);
2049 j = -1;
2050 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2051 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0,
2052 &ext[u]->ext[j], 1);
2053 }
2054 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, (const char *)pp[1],
2055 module, ext[u]->ext, ext[u]->ext_size);
2056 ly_print(out, "%*s}\n", LEVEL, INDENT);
2057 }
2058 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002059 case LY_STMT_TYPE:
Radek Krejci37f9ba32017-02-10 16:50:35 +01002060 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_TYPE, struct lys_type, yang_print_type);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002061 break;
2062 case LY_STMT_IFFEATURE:
Radek Krejci37f9ba32017-02-10 16:50:35 +01002063 YANG_PRINT_EXTCOMPLEX_STRUCT_M(LY_STMT_IFFEATURE, struct lys_iffeature, yang_print_iffeature);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002064 break;
2065 case LY_STMT_STATUS:
Radek Krejcifebdad72017-02-06 11:35:51 +01002066 flags = lys_ext_complex_get_substmt(LY_STMT_STATUS, (struct lys_ext_instance_complex *)ext[u], NULL);
Radek Krejci2fd2a1f2017-02-13 11:06:04 +01002067 if (!flags || !(*flags)) {
2068 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002069 }
2070
2071 if (*flags & LYS_STATUS_CURR) {
2072 yang_print_open(out, &content);
2073 str = "current";
2074 } else if (*flags & LYS_STATUS_DEPRC) {
2075 yang_print_open(out, &content);
2076 str = "deprecated";
2077 } else if (*flags & LYS_STATUS_OBSLT) {
2078 yang_print_open(out, &content);
2079 str = "obsolete";
2080 }
2081 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, str, module, ext[u]->ext, ext[u]->ext_size);
Radek Krejcic3e36542017-02-08 16:19:23 +01002082 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002083 case LY_STMT_CONFIG:
2084 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002085 LY_STMT_CONFIG, "true", "false",
Radek Krejcic1885952017-02-07 09:37:51 +01002086 LYS_CONFIG_W | LYS_CONFIG_SET, LYS_CONFIG_R | LYS_CONFIG_SET, &content);
2087 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002088 case LY_STMT_MANDATORY:
2089 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002090 LY_STMT_MANDATORY, "false", "true", LYS_MAND_FALSE, LYS_MAND_TRUE,
2091 &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002092 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002093 case LY_STMT_ORDEREDBY:
2094 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002095 LY_STMT_ORDEREDBY, "system", "user", 0, LYS_USERORDERED, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002096 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002097 case LY_STMT_REQINSTANCE:
Radek Krejcibe336392017-02-07 10:54:24 +01002098 case LY_STMT_YINELEM:
Radek Krejcic1885952017-02-07 09:37:51 +01002099 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002100 info[i].stmt, "true", "false", &content);
Radek Krejcic1885952017-02-07 09:37:51 +01002101 break;
2102 case LY_STMT_MODIFIER:
2103 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002104 LY_STMT_MODIFIER, "invert-match", NULL, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002105 break;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002106 case LY_STMT_DIGITS:
Radek Krejcif8d05c22017-02-10 15:33:35 +01002107 p = &((struct lys_ext_instance_complex*)ext[u])->content[info[i].offset];
2108 if (!p) {
2109 break;
2110 }
2111 if (info->cardinality >= LY_STMT_CARD_SOME) { /* we have array */
2112 for (c = 0; (*(uint8_t**)p)[c]; c++) {
2113 yang_print_open(out, &content);
2114 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, c, module,
2115 ext[u]->ext, ext[u]->ext_size, (*(uint8_t**)p)[c]);
2116 }
2117 } else if ((*(uint8_t*)p)) {
2118 yang_print_open(out, &content);
2119 yang_print_unsigned(out, level, LYEXT_SUBSTMT_DIGITS, 0, module,
2120 ext[u]->ext, ext[u]->ext_size, (*(uint8_t*)p));
2121 }
Radek Krejci5496fae2017-02-10 13:26:48 +01002122 break;
2123 case LY_STMT_MAX:
2124 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MAX, uint32_t);
2125 break;
2126 case LY_STMT_MIN:
2127 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MIN, uint32_t);
2128 break;
2129 case LY_STMT_POSITION:
2130 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_POSITION, uint32_t);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002131 break;
Radek Krejci37f9ba32017-02-10 16:50:35 +01002132 case LY_STMT_MODULE:
2133 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_TYPE, struct lys_module, yang_print_model_);
2134 break;
Radek Krejcif95b6292017-02-13 15:57:37 +01002135 case LY_STMT_ACTION:
2136 case LY_STMT_ANYDATA:
2137 case LY_STMT_ANYXML:
2138 case LY_STMT_CASE:
2139 case LY_STMT_CHOICE:
2140 case LY_STMT_CONTAINER:
2141 case LY_STMT_GROUPING:
2142 case LY_STMT_INPUT:
2143 case LY_STMT_OUTPUT:
2144 case LY_STMT_LEAF:
2145 case LY_STMT_LEAFLIST:
2146 case LY_STMT_LIST:
2147 case LY_STMT_NOTIFICATION:
2148 case LY_STMT_USES:
2149 YANG_PRINT_EXTCOMPLEX_SNODE(info[i].stmt);
2150 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002151 default:
2152 /* TODO */
2153 break;
2154 }
2155 }
2156 level--;
2157 break;
2158 case LYEXT_ERR:
2159 LOGINT;
2160 break;
2161 }
2162
2163 /* close extension */
2164 yang_print_close(out, level, content);
2165 }
2166#undef YANG_PRINT_EXTCOMPLEX_STRUCT
Radek Krejci37f9ba32017-02-10 16:50:35 +01002167#undef YANG_PRINT_EXTCOMPLEX_STRUCT_M
2168#undef YANG_PRINT_EXTCOMPLEX_INT
Radek Krejcida04f4a2015-05-21 12:54:09 +02002169}