blob: c5f0acaebcccbd9e812f3436eda68154cd4e3b18 [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 Krejci6e4ffbb2015-06-16 10:34:41 +02001624int
Michal Vasko1e62a092015-12-01 12:27:20 +01001625yang_print_model(struct lyout *out, 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 Krejci43e3c312017-01-11 11:34:44 +01001628 int level = 0, 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) {
Michal Vasko89563fc2016-07-28 16:19:35 +02001634 ly_print(out, "submodule %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001635 level++;
Radek Krejci77424f72017-01-20 13:21:09 +01001636 if (lys_main_module(module)->version > 1 ||
Radek Krejcibf285832017-01-26 16:05:41 +01001637 lys_ext_iter(module->ext, module->ext_size, 0, LYEXT_SUBSTMT_VERSION) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001638 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0,
1639 ((struct lys_submodule *)module)->belongsto->version == 2 ? "1.1" : "1",
1640 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001641 }
Radek Krejci76b07902015-10-09 09:11:25 +02001642 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Radek Krejcicfce0292017-01-13 12:37:57 +01001643 p = -1;
Radek Krejcibf285832017-01-26 16:05:41 +01001644 while ((p = lys_ext_iter(module->ext, module->ext_size, p + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001645 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0, &module->ext[p], 1);
1646 }
1647 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1648 module, module->ext, module->ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001649 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001650 } else {
Michal Vasko89563fc2016-07-28 16:19:35 +02001651 ly_print(out, "module %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001652 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001653 if (module->version) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001654 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == 2 ? "1.1" : "1",
1655 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001656 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001657 yang_print_substmt(out, level, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns,
1658 module, module->ext, module->ext_size);
1659 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1660 module, module->ext, module->ext_size);
Michal Vasko116172e2015-07-07 11:54:37 +02001661 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001662
Radek Krejci8d81e002015-12-10 11:18:59 +01001663 /* linkage-stmts */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001664 for (i = 0; i < module->imp_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001665 ly_print(out, "\n%*simport %s {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001666 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001667 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1668 module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci39228d22017-01-13 12:43:55 +01001669 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->imp[i].prefix,
1670 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001671 if (module->imp[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001672 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->imp[i].rev,
1673 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001674 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001675 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->imp[i].dsc,
1676 module, module->imp[i].ext, module->imp[i].ext_size);
1677 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->imp[i].ref,
1678 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001679 level--;
Michal Vaskoc8e3ce02016-02-12 14:28:35 +01001680 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001681 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001682 for (i = 0; i < module->inc_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001683 if (module->inc[i].rev[0] || module->inc[i].dsc || module->inc[i].ref || module->inc[i].ext_size) {
1684 ly_print(out, "\n%*sinclude %s {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci8d81e002015-12-10 11:18:59 +01001685 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001686 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1687 module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001688 if (module->inc[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001689 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->inc[i].rev,
1690 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001691 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001692 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->inc[i].dsc,
1693 module, module->inc[i].ext, module->inc[i].ext_size);
1694 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->inc[i].ref,
1695 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001696 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001697 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001698 } else {
Radek Krejcie534c132016-11-23 13:32:31 +01001699 ly_print(out, "\n%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001700 }
1701 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001702
Radek Krejci8d81e002015-12-10 11:18:59 +01001703 /* meta-stmts */
1704 if (module->org || module->contact || module->dsc || module->ref) {
1705 ly_print(out, "\n");
1706 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001707 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org,
1708 module, module->ext, module->ext_size);
1709 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONTACT, 0, module->contact,
1710 module, module->ext, module->ext_size);
1711 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc,
1712 module, module->ext, module->ext_size);
1713 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->ref,
1714 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001715
1716 /* revision-stmts */
1717 if (module->rev_size) {
1718 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001719 }
1720 for (i = 0; i < module->rev_size; i++) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001721 if (module->rev[i].dsc || module->rev[i].ref || module->rev[i].ext_size) {
Radek Krejci76b07902015-10-09 09:11:25 +02001722 ly_print(out, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci5dd25122017-01-11 17:28:13 +01001723 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1724 module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci43e3c312017-01-11 11:34:44 +01001725 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_DESCRIPTION, 0, module->rev[i].dsc,
1726 module, module->rev[i].ext, module->rev[i].ext_size);
1727 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_REFERENCE, 0, module->rev[i].ref,
1728 module, module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001729 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001730 } else {
Michal Vasko86dfd262016-02-15 14:26:31 +01001731 ly_print(out, "%*srevision %s;\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001732 }
1733 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001734
Radek Krejci8d81e002015-12-10 11:18:59 +01001735 /* body-stmts */
Radek Krejcie534c132016-11-23 13:32:31 +01001736 for (i = 0; i < module->extensions_size; i++) {
1737 ly_print(out, "\n");
1738 yang_print_extension(out, level, &module->extensions[i]);
1739 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001740 if (module->ext_size) {
1741 ly_print(out, "\n");
1742 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, module->ext, module->ext_size);
1743 }
Radek Krejcie534c132016-11-23 13:32:31 +01001744
Michal Vasko30f6e912015-07-07 12:24:27 +02001745 for (i = 0; i < module->features_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001746 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001747 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001748 }
1749
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001750 for (i = 0; i < module->ident_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001751 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001752 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001753 }
Radek Krejci6793db02015-05-22 17:49:54 +02001754
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001755 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001756 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001757 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001758 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001759
Radek Krejci5dd25122017-01-11 17:28:13 +01001760 LY_TREE_FOR(lys_main_module(module)->data, node) {
1761 if (node->module != module) {
1762 /* data from submodules */
1763 continue;
1764 }
1765 yang_print_snode(out, level, node, LYS_GROUPING);
Radek Krejci8d81e002015-12-10 11:18:59 +01001766 }
1767
Radek Krejcic4283442016-04-22 09:19:27 +02001768 LY_TREE_FOR(lys_main_module(module)->data, node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001769 if (node->module != module) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001770 /* data from submodules */
Radek Krejcic071c542016-01-27 14:57:51 +01001771 continue;
1772 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001773 yang_print_snode(out, level, node, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1774 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001775 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001776
Michal Vasko6f25f212015-07-07 15:42:07 +02001777 for (i = 0; i < module->augment_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001778 ly_print(out, "\n");
Radek Krejci43e3c312017-01-11 11:34:44 +01001779 yang_print_augment(out, level, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001780 }
1781
Radek Krejci5dd25122017-01-11 17:28:13 +01001782 LY_TREE_FOR(lys_main_module(module)->data, node) {
1783 if (node->module != module) {
1784 /* data from submodules */
1785 continue;
1786 }
1787 yang_print_snode(out, level, node, LYS_RPC | LYS_ACTION);
1788 }
1789
1790 LY_TREE_FOR(lys_main_module(module)->data, node) {
1791 if (node->module != module) {
1792 /* data from submodules */
1793 continue;
1794 }
1795 yang_print_snode(out, level, node, LYS_NOTIF);
1796 }
1797
1798 for (i = 0; i < module->deviation_size; ++i) {
1799 ly_print(out, "\n");
1800 yang_print_deviation(out, level, module, &module->deviation[i]);
1801 }
1802
Radek Krejci76b07902015-10-09 09:11:25 +02001803 ly_print(out, "}\n");
Michal Vasko95068c42016-03-24 14:58:11 +01001804 ly_print_flush(out);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001805
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001806 return EXIT_SUCCESS;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001807}
1808
1809static void
Radek Krejcic1885952017-02-07 09:37:51 +01001810yang_print_extcomplex_bool(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001811 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001812 const char *true_val, const char *false_val, int *content)
1813{
1814 struct lyext_substmt *info;
1815 uint8_t *val;
1816
1817 val = lys_ext_complex_get_substmt(stmt, ext, &info);
1818 if (!val || !(*val)) {
1819 return;
1820 }
1821
1822 yang_print_open(out, content);
1823 if (*val == 1) {
Radek Krejcibe336392017-02-07 10:54:24 +01001824 yang_print_substmt(out, level, stmt, 0, true_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001825 } else if (*val == 2) {
Radek Krejcibe336392017-02-07 10:54:24 +01001826 yang_print_substmt(out, level, stmt, 0, false_val, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001827 } else {
1828 LOGINT;
1829 }
1830}
1831
1832static void
Radek Krejci8d6b7422017-02-03 14:42:13 +01001833yang_print_extcomplex_str(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001834 struct lys_ext_instance_complex *ext, LY_STMT stmt, int *content)
Radek Krejci8d6b7422017-02-03 14:42:13 +01001835{
1836 struct lyext_substmt *info;
1837 const char **str;
1838 int c;
1839
1840 str = lys_ext_complex_get_substmt(stmt, ext, &info);
1841 if (!str || !(*str)) {
1842 return;
1843 }
1844 if (info->cardinality >= LY_STMT_CARD_SOME) {
1845 /* we have array */
1846 for (str = (const char **)(*str), c = 0; *str; str++, c++) {
1847 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001848 yang_print_substmt(out, level, stmt, c, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001849 }
1850 } else {
1851 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001852 yang_print_substmt(out, level, stmt, 0, *str, module, ext->ext, ext->ext_size);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001853 }
1854}
1855
Radek Krejcic1885952017-02-07 09:37:51 +01001856/* val1 is supposed to be the default value */
1857static void
1858yang_print_extcomplex_flags(struct lyout *out, int level, const struct lys_module *module,
Radek Krejcibe336392017-02-07 10:54:24 +01001859 struct lys_ext_instance_complex *ext, LY_STMT stmt,
Radek Krejcic1885952017-02-07 09:37:51 +01001860 const char *val1_str, const char *val2_str, uint16_t val1, uint16_t val2,
1861 int *content)
1862{
1863 const char *str;
1864 uint16_t *flags;
1865
1866 flags = lys_ext_complex_get_substmt(stmt, ext, NULL);
1867 if (!flags) {
1868 return;
1869 }
1870
1871 if (val1 & *flags) {
1872 str = val1_str;
1873 } else if (val2 & *flags) {
1874 str = val2_str;
Radek Krejcibe336392017-02-07 10:54:24 +01001875 } else if (lys_ext_iter(ext->ext, ext->ext_size, 0, stmt) != -1) {
Radek Krejcic1885952017-02-07 09:37:51 +01001876 /* flag not set, but since there are some extension, we are going to print the default value */
1877 str = val1_str;
1878 } else {
1879 return;
1880 }
1881
1882 yang_print_open(out, content);
Radek Krejcibe336392017-02-07 10:54:24 +01001883 yang_print_substmt(out, level, stmt, 0, str, module, ext->ext, ext->ext_size);
Radek Krejcic1885952017-02-07 09:37:51 +01001884}
1885
Radek Krejci8d6b7422017-02-03 14:42:13 +01001886static void
1887yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
1888 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
1889 struct lys_ext_instance **ext, unsigned int count)
1890{
1891 unsigned int u, x;
1892 struct lys_module *mod;
1893 const char *prefix = NULL, *str;
Radek Krejci897d6072017-02-09 16:00:01 +01001894 int content, i, j, c;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001895 struct lyext_substmt *info;
1896 uint16_t *flags;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01001897 void **pp, *p;
Radek Krejci8d6b7422017-02-03 14:42:13 +01001898
1899#define YANG_PRINT_EXTCOMPLEX_STRUCT(STMT, TYPE, FUNC) \
Radek Krejcifebdad72017-02-06 11:35:51 +01001900 pp = lys_ext_complex_get_substmt(STMT, (struct lys_ext_instance_complex *)ext[u], NULL); \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001901 if (!pp || !(*pp)) { break; } \
Radek Krejcifebdad72017-02-06 11:35:51 +01001902 if (info[i].cardinality >= LY_STMT_CARD_SOME) { /* process array */ \
Radek Krejci8d6b7422017-02-03 14:42:13 +01001903 for (pp = *pp; *pp; pp++) { \
1904 yang_print_open(out, &content); \
1905 FUNC(out, level, module, (TYPE *)(*pp)); \
1906 } \
1907 } else { /* single item */ \
1908 yang_print_open(out, &content); \
1909 FUNC(out, level, module, (TYPE *)(*pp)); \
1910 }
Radek Krejci5496fae2017-02-10 13:26:48 +01001911#define YANG_PRINT_EXTCOMPLEX_INT(STMT, TYPE) \
1912 p = &((struct lys_ext_instance_complex*)ext[u])->content[info[i].offset]; \
1913 if (!p) { break; } \
1914 if (info->cardinality >= LY_STMT_CARD_SOME) { /* we have array */ \
1915 for (c = 0; (*(TYPE**)p)[c]; c++) { \
1916 yang_print_open(out, &content); \
1917 yang_print_unsigned(out, level, STMT, c, module, \
1918 ext[u]->ext, ext[u]->ext_size, (*(TYPE**)p)[c]); \
1919 } \
1920 } else if ((*(TYPE*)p)) { \
1921 yang_print_open(out, &content); \
1922 yang_print_unsigned(out, level, STMT, 0, module, \
1923 ext[u]->ext, ext[u]->ext_size, (*(TYPE*)p)); \
1924 }
Radek Krejci8d6b7422017-02-03 14:42:13 +01001925
1926 for (u = 0; u < count; u++) {
1927 if (ext[u]->flags & LYEXT_OPT_INHERIT) {
1928 /* ignore the inherited extensions which were not explicitely instantiated in the module */
1929 continue;
Radek Krejcifebdad72017-02-06 11:35:51 +01001930 } else if (ext[u]->insubstmt != substmt || ext[u]->insubstmt_index != substmt_index) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001931 /* do not print the other substatement than the required */
1932 continue;
1933 }
1934
1935 mod = lys_main_module(ext[u]->def->module);
1936 if (mod == lys_main_module(module)) {
1937 prefix = module->prefix;
1938 } else {
1939 for (x = 0; x < module->imp_size; x++) {
1940 if (mod == module->imp[x].module) {
1941 prefix = module->imp[x].prefix;
1942 break;
1943 }
1944 }
1945 }
1946
1947 content = 0;
1948 ly_print(out, "%*s%s:%s", LEVEL, INDENT, prefix, ext[u]->def->name);
1949 /* extension - generic part */
1950 if (ext[u]->arg_value) {
1951 ly_print(out, " \"%s\"", ext[u]->arg_value);
1952 }
1953
1954 /* extensions in extension instance */
1955 if (ext[u]->ext_size) {
1956 yang_print_open(out, &content);
1957 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1958 ext[u]->ext, ext[u]->ext_size);
1959 }
1960
1961 /* extension - type-specific part */
1962 switch(lys_ext_instance_type(ext[u])) {
1963 case LYEXT_FLAG:
1964 /* flag extension - nothing special */
1965 break;
1966 case LYEXT_COMPLEX:
Radek Krejcifebdad72017-02-06 11:35:51 +01001967 info = ((struct lys_ext_instance_complex*)ext[u])->substmt; /* shortcut */
1968 if (!info) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001969 /* no content */
1970 break;
1971 }
1972 level++;
Radek Krejcifebdad72017-02-06 11:35:51 +01001973 for (i = 0; info[i].stmt; i++) {
1974 switch(info[i].stmt) {
Radek Krejci8d6b7422017-02-03 14:42:13 +01001975 case LY_STMT_DESCRIPTION:
Radek Krejci8d6b7422017-02-03 14:42:13 +01001976 case LY_STMT_REFERENCE:
Radek Krejci8d6b7422017-02-03 14:42:13 +01001977 case LY_STMT_UNITS:
Radek Krejcibe336392017-02-07 10:54:24 +01001978 case LY_STMT_ARGUMENT:
1979 case LY_STMT_DEFAULT:
1980 case LY_STMT_ERRTAG:
1981 case LY_STMT_ERRMSG:
1982 case LY_STMT_PREFIX:
1983 case LY_STMT_NAMESPACE:
1984 case LY_STMT_PRESENCE:
1985 case LY_STMT_REVISIONDATE:
1986 case LY_STMT_KEY:
1987 case LY_STMT_BASE:
Radek Krejcibe336392017-02-07 10:54:24 +01001988 case LY_STMT_CONTACT:
1989 case LY_STMT_ORGANIZATION:
1990 case LY_STMT_PATH:
1991 case LY_STMT_VERSION:
1992 case LY_STMT_VALUE:
Radek Krejci8d6b7422017-02-03 14:42:13 +01001993 yang_print_extcomplex_str(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01001994 info[i].stmt, &content);
Radek Krejci8d6b7422017-02-03 14:42:13 +01001995 break;
Radek Krejci897d6072017-02-09 16:00:01 +01001996 case LY_STMT_BELONGSTO:
1997 pp = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, (struct lys_ext_instance_complex*)ext[u], NULL);
1998 if (!pp || !(*pp)) {
1999 break;
2000 }
2001 if (info->cardinality >= LY_STMT_CARD_SOME) {
2002 /* we have array */
2003 for (c = 0; ((const char***)pp)[0][c]; c++) {
2004 yang_print_open(out, &content);
2005 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((const char ***)pp)[0][c]);
2006 j = -1;
2007 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2008 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, c,
2009 &ext[u]->ext[j], 1);
2010 }
2011 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, c, ((const char ***)pp)[1][c],
2012 module, ext[u]->ext, ext[u]->ext_size);
2013 ly_print(out, "%*s}\n", LEVEL, INDENT);
2014 }
2015 } else {
2016 yang_print_open(out, &content);
2017 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, (const char *)pp[0]);
2018 j = -1;
2019 while ((j = lys_ext_iter(ext[u]->ext, ext[u]->ext_size, j + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
2020 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0,
2021 &ext[u]->ext[j], 1);
2022 }
2023 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, (const char *)pp[1],
2024 module, ext[u]->ext, ext[u]->ext_size);
2025 ly_print(out, "%*s}\n", LEVEL, INDENT);
2026 }
2027 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002028 case LY_STMT_TYPE:
2029 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_TYPE, struct lys_type, yang_print_type);
2030 break;
2031 case LY_STMT_IFFEATURE:
2032 YANG_PRINT_EXTCOMPLEX_STRUCT(LY_STMT_IFFEATURE, struct lys_iffeature, yang_print_iffeature);
2033 break;
2034 case LY_STMT_STATUS:
Radek Krejcifebdad72017-02-06 11:35:51 +01002035 flags = lys_ext_complex_get_substmt(LY_STMT_STATUS, (struct lys_ext_instance_complex *)ext[u], NULL);
Radek Krejci8d6b7422017-02-03 14:42:13 +01002036 if (!flags) {
2037 return;
2038 }
2039
2040 if (*flags & LYS_STATUS_CURR) {
2041 yang_print_open(out, &content);
2042 str = "current";
2043 } else if (*flags & LYS_STATUS_DEPRC) {
2044 yang_print_open(out, &content);
2045 str = "deprecated";
2046 } else if (*flags & LYS_STATUS_OBSLT) {
2047 yang_print_open(out, &content);
2048 str = "obsolete";
2049 }
2050 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 +01002051 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002052 case LY_STMT_CONFIG:
2053 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002054 LY_STMT_CONFIG, "true", "false",
Radek Krejcic1885952017-02-07 09:37:51 +01002055 LYS_CONFIG_W | LYS_CONFIG_SET, LYS_CONFIG_R | LYS_CONFIG_SET, &content);
2056 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002057 case LY_STMT_MANDATORY:
2058 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002059 LY_STMT_MANDATORY, "false", "true", LYS_MAND_FALSE, LYS_MAND_TRUE,
2060 &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002061 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002062 case LY_STMT_ORDEREDBY:
2063 yang_print_extcomplex_flags(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002064 LY_STMT_ORDEREDBY, "system", "user", 0, LYS_USERORDERED, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002065 break;
Radek Krejcic1885952017-02-07 09:37:51 +01002066 case LY_STMT_REQINSTANCE:
Radek Krejcibe336392017-02-07 10:54:24 +01002067 case LY_STMT_YINELEM:
Radek Krejcic1885952017-02-07 09:37:51 +01002068 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002069 info[i].stmt, "true", "false", &content);
Radek Krejcic1885952017-02-07 09:37:51 +01002070 break;
2071 case LY_STMT_MODIFIER:
2072 yang_print_extcomplex_bool(out, level, module, (struct lys_ext_instance_complex*)ext[u],
Radek Krejcibe336392017-02-07 10:54:24 +01002073 LY_STMT_MODIFIER, "invert-match", NULL, &content);
Radek Krejci83ac2cd2017-02-06 14:59:47 +01002074 break;
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002075 case LY_STMT_DIGITS:
Radek Krejci5496fae2017-02-10 13:26:48 +01002076 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_DIGITS, uint8_t);
2077 break;
2078 case LY_STMT_MAX:
2079 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MAX, uint32_t);
2080 break;
2081 case LY_STMT_MIN:
2082 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_MIN, uint32_t);
2083 break;
2084 case LY_STMT_POSITION:
2085 YANG_PRINT_EXTCOMPLEX_INT(LYEXT_SUBSTMT_POSITION, uint32_t);
Radek Krejci3a14dfd2017-02-07 13:27:33 +01002086 break;
Radek Krejci8d6b7422017-02-03 14:42:13 +01002087 default:
2088 /* TODO */
2089 break;
2090 }
2091 }
2092 level--;
2093 break;
2094 case LYEXT_ERR:
2095 LOGINT;
2096 break;
2097 }
2098
2099 /* close extension */
2100 yang_print_close(out, level, content);
2101 }
2102#undef YANG_PRINT_EXTCOMPLEX_STRUCT
Radek Krejcida04f4a2015-05-21 12:54:09 +02002103}