blob: 1c2839307574d99ed505d738cca4425d0f4325e2 [file] [log] [blame]
Radek Krejcida04f4a2015-05-21 12:54:09 +02001/**
Radek Krejciefdd0ce2015-05-26 16:48:29 +02002 * @file printer/yang.c
Radek Krejcida04f4a2015-05-21 12:54:09 +02003 * @author Radek Krejci <rkrejci@cesnet.cz>
Radek Krejciefdd0ce2015-05-26 16:48:29 +02004 * @brief YANG printer for libyang data model structure
Radek Krejcida04f4a2015-05-21 12:54:09 +02005 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
Radek Krejci54f6fb32016-02-24 12:56:39 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
Michal Vasko8de098c2016-02-26 10:00:25 +010011 *
Radek Krejci54f6fb32016-02-24 12:56:39 +010012 * https://opensource.org/licenses/BSD-3-Clause
Radek Krejcida04f4a2015-05-21 12:54:09 +020013 */
Radek Krejci43e3c312017-01-11 11:34:44 +010014#define _GNU_SOURCE
15#include <stdio.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020016#include <stdlib.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020017#include <string.h>
Michal Vasko25cb6c62016-02-12 14:36:21 +010018#include <stdint.h>
Michal Vaskof30ea3e2016-12-06 12:16:02 +010019#include <assert.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020020
Radek Krejci998a0b82015-08-17 13:14:36 +020021#include "common.h"
Radek Krejci76b07902015-10-09 09:11:25 +020022#include "printer.h"
Michal Vasko2d162e12015-09-24 14:33:29 +020023#include "tree_schema.h"
Radek Krejcida04f4a2015-05-21 12:54:09 +020024
25#define INDENT ""
26#define LEVEL (level*2)
27
Michal Vasko1e62a092015-12-01 12:27:20 +010028static void yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask);
Radek Krejcida04f4a2015-05-21 12:54:09 +020029
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020030static void
Michal Vasko25cb6c62016-02-12 14:36:21 +010031yang_encode(struct lyout *out, const char *text, int len)
32{
33 int i, start_len;
34 const char *start;
35 char special = 0;
36
37 if (!len) {
38 return;
39 }
40
41 if (len < 0) {
42 len = strlen(text);
43 }
44
45 start = text;
46 start_len = 0;
47 for (i = 0; i < len; ++i) {
48 switch (text[i]) {
49 case '\n':
50 case '\t':
51 case '\"':
52 case '\\':
53 special = text[i];
54 break;
55 default:
56 ++start_len;
57 break;
58 }
59
60 if (special) {
61 ly_write(out, start, start_len);
62 switch (special) {
63 case '\n':
64 ly_write(out, "\\n", 2);
65 break;
66 case '\t':
67 ly_write(out, "\\t", 2);
68 break;
69 case '\"':
70 ly_write(out, "\\\"", 2);
71 break;
72 case '\\':
73 ly_write(out, "\\\\", 2);
74 break;
75 }
76
77 start += start_len + 1;
78 start_len = 0;
79
80 special = 0;
81 }
82 }
83
84 ly_write(out, start, start_len);
85}
86
87static void
Radek Krejci32cce7c2015-12-09 16:44:13 +010088yang_print_open(struct lyout *out, int *flag)
89{
90 if (flag && !*flag) {
91 *flag = 1;
92 ly_print(out, " {\n");
93 }
94}
95
96static void
97yang_print_close(struct lyout *out, int level, int flag)
98{
99 if (flag) {
100 ly_print(out, "%*s}\n", LEVEL, INDENT);
101 } else {
102 ly_print(out, ";\n");
103 }
104}
105
106static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100107yang_print_text(struct lyout *out, int level, const char *name, const char *text, int singleline, int closed)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200108{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200109 const char *s, *t;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200110
Radek Krejci8d81e002015-12-10 11:18:59 +0100111 if (singleline) {
112 ly_print(out, "%*s%s \"", LEVEL, INDENT, name);
113 } else {
114 ly_print(out, "%*s%s\n", LEVEL, INDENT, name);
115 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200116
Radek Krejci8d81e002015-12-10 11:18:59 +0100117 ly_print(out, "%*s\"", LEVEL, INDENT);
118 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200119 t = text;
120 while ((s = strchr(t, '\n'))) {
Michal Vasko25cb6c62016-02-12 14:36:21 +0100121 yang_encode(out, t, s - t);
122 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200123 t = s + 1;
Michal Vasko25cb6c62016-02-12 14:36:21 +0100124 ly_print(out, "%*s ", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200125 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200126
范昌虎1006995277de5fc2016-10-08 07:33:29 -0400127 yang_encode(out, t, strlen(t));
Radek Krejci43e3c312017-01-11 11:34:44 +0100128 if (closed) {
129 ly_print(out, "\";\n");
130 } else {
131 ly_print(out, "\"");
132 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200133 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200134
135}
136
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200137static void
Radek Krejcie534c132016-11-23 13:32:31 +0100138yang_print_extension_instances(struct lyout *out, int level, const struct lys_module *module,
Radek Krejci43e3c312017-01-11 11:34:44 +0100139 LYEXT_SUBSTMT substmt, uint8_t substmt_index,
Radek Krejcie534c132016-11-23 13:32:31 +0100140 struct lys_ext_instance **ext, unsigned int count)
141{
142 unsigned int u, x;
143 struct lys_module *mod;
144 const char *prefix = NULL;
145 int flag;
146
147 for (u = 0; u < count; u++) {
Radek Krejci80056d52017-01-05 13:13:33 +0100148 if (ext[u]->flags & LYEXT_OPT_INHERIT) {
149 /* ignore the inherited extensions which were not explicitely instantiated in the module */
150 continue;
Radek Krejci43e3c312017-01-11 11:34:44 +0100151 } else if (ext[u]->substmt != substmt || ext[u]->substmt_index != substmt_index) {
152 /* do not print the other substatement than the required */
153 continue;
Radek Krejci80056d52017-01-05 13:13:33 +0100154 }
155
Radek Krejcie534c132016-11-23 13:32:31 +0100156 mod = lys_main_module(ext[u]->def->module);
Radek Krejci91602182017-01-13 12:41:33 +0100157 if (mod == lys_main_module(module)) {
Radek Krejcie534c132016-11-23 13:32:31 +0100158 prefix = module->prefix;
159 } else {
160 for (x = 0; x < module->imp_size; x++) {
161 if (mod == module->imp[x].module) {
162 prefix = module->imp[x].prefix;
163 break;
164 }
165 }
166 }
167
168 flag = 0;
169 ly_print(out, "%*s%s:%s", LEVEL, INDENT, prefix, ext[u]->def->name);
Radek Krejci0aa821a2016-12-08 11:21:35 +0100170 /* extension - generic part */
171 if (ext[u]->arg_value) {
172 ly_print(out, " \"%s\"", ext[u]->arg_value);
Radek Krejcie534c132016-11-23 13:32:31 +0100173 }
174
Radek Krejci0aa821a2016-12-08 11:21:35 +0100175 /* extension - type-specific part */
176 switch(lys_ext_instance_type(ext[u])) {
177 case LYEXT_FLAG:
178 /* flag extension - nothing special */
Radek Krejci17000ac2017-01-04 16:16:13 +0100179 break;
Radek Krejci0aa821a2016-12-08 11:21:35 +0100180 case LYEXT_ERR:
181 LOGINT;
182 break;
183 }
184
185 /* extensions in extension instance */
Radek Krejcie534c132016-11-23 13:32:31 +0100186 if (ext[u]->ext_size) {
187 yang_print_open(out, &flag);
Radek Krejcic65474c2017-01-16 10:38:35 +0100188 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
189 ext[u]->ext, ext[u]->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +0100190 }
191
192 /* close extension */
193 yang_print_close(out, level, flag);
194 }
195}
196
Radek Krejci43e3c312017-01-11 11:34:44 +0100197static void
198yang_print_substmt(struct lyout *out, int level, LYEXT_SUBSTMT substmt, uint8_t substmt_index, const char *text,
199 const struct lys_module *module, struct lys_ext_instance **ext, unsigned int ext_size)
200{
Radek Krejcicfce0292017-01-13 12:37:57 +0100201 int i = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100202
203 if (!text) {
204 /* nothing to print */
205 return;
206 }
207
Radek Krejcicfce0292017-01-13 12:37:57 +0100208 do {
209 i = ly_print_ext_iter(ext, ext_size, i + 1, substmt);
210 } while (i != -1 && ext[i]->substmt_index != substmt_index);
211
Radek Krejci43e3c312017-01-11 11:34:44 +0100212 if (ext_substmt_info[substmt].flags & SUBST_FLAG_ID) {
213 ly_print(out, "%*s%s %s%s", LEVEL, INDENT, ext_substmt_info[substmt].name, text, i == -1 ? ";\n" : "");
214 } else {
215 yang_print_text(out, level, ext_substmt_info[substmt].name, text,
216 (ext_substmt_info[substmt].flags & SUBST_FLAG_YIN) ? 0 : 1, i == -1 ? 1 : 0);
217 }
218
219 if (i != -1) {
220 ly_print(out, " {\n");
221 do {
222 yang_print_extension_instances(out, level + 1, module, substmt, substmt_index, &ext[i], 1);
223 do {
224 i = ly_print_ext_iter(ext, ext_size, i + 1, substmt);
225 } while (i != -1 && ext[i]->substmt_index != substmt_index);
226 } while (i != -1);
227 ly_print(out, "%*s}\n", LEVEL, INDENT);
228 }
229}
230
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200231static void
Radek Krejci9ff0a922016-07-14 13:08:05 +0200232yang_print_iffeature(struct lyout *out, int level, const struct lys_module *module, struct lys_iffeature *iffeature)
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200233{
Michal Vaskoc5c26b02016-06-29 11:10:29 +0200234 ly_print(out, "%*sif-feature \"", LEVEL, INDENT);
Radek Krejci9ff0a922016-07-14 13:08:05 +0200235 ly_print_iffeature(out, module, iffeature);
Radek Krejci43e3c312017-01-11 11:34:44 +0100236
237 /* extensions */
238 if (iffeature->ext_size) {
239 ly_print(out, "\" {\n");
240 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0, iffeature->ext, iffeature->ext_size);
241 ly_print(out, "%*s}\n", LEVEL, INDENT);
242 } else {
243 ly_print(out, "\";\n");
244 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200245}
246
Radek Krejci5dd25122017-01-11 17:28:13 +0100247/*
248 * Covers:
249 * extension (instances), if-features, config, mandatory, status, description, reference
250 */
251#define SNODE_COMMON_EXT 0x01
252#define SNODE_COMMON_IFF 0x02
253#define SNODE_COMMON_CONFIG 0x04
254#define SNODE_COMMON_MAND 0x08
255#define SNODE_COMMON_STATUS 0x10
256#define SNODE_COMMON_DSC 0x20
257#define SNODE_COMMON_REF 0x40
258static void
259yang_print_snode_common(struct lyout *out, int level, const struct lys_node *node, const struct lys_module *module,
260 int *flag, int mask)
261{
262 int i;
263 const char *status = NULL;
264
265 /* extensions */
266 if ((mask & SNODE_COMMON_EXT) && node->ext_size) {
267 yang_print_open(out, flag);
268 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
269 }
270
271 /* if-features */
272 if (mask & SNODE_COMMON_IFF) {
273 for (i = 0; i < node->iffeature_size; ++i) {
274 yang_print_open(out, flag);
275 yang_print_iffeature(out, level, module, &node->iffeature[i]);
276 }
277 }
278
279 /* config */
280 if (mask & SNODE_COMMON_CONFIG) {
281 /* get info if there is an extension for the config statement */
282 i = ly_print_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_CONFIG);
283
284 if (lys_parent(node)) {
285 if ((node->flags & LYS_CONFIG_SET) || i != -1) {
286 /* print config when it differs from the parent or if it has an extension instance ... */
287 if (node->flags & LYS_CONFIG_W) {
288 yang_print_open(out, flag);
289 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
290 module, node->ext, node->ext_size);
291 } else if (node->flags & LYS_CONFIG_R) {
292 yang_print_open(out, flag);
293 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
294 module, node->ext, node->ext_size);
295 }
296 }
297 } else if (node->flags & LYS_CONFIG_R) {
298 /* ... or it's a top-level state node */
299 yang_print_open(out, flag);
300 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false",
301 module, node->ext, node->ext_size);
302 } else if (i != -1) {
303 /* the config has an extension, so we have to print it */
304 yang_print_open(out, flag);
305 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true",
306 module, node->ext, node->ext_size);
307 }
308 }
309
310 /* mandatory */
311 if ((mask & SNODE_COMMON_MAND) && (node->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
312 if (node->flags & LYS_MAND_TRUE) {
313 yang_print_open(out, flag);
314 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true",
315 module, node->ext, node->ext_size);
316 } else if (node->flags & LYS_MAND_FALSE) {
317 yang_print_open(out, flag);
318 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false",
319 module, node->ext, node->ext_size);
320 }
321 }
322
323 /* status */
324 if (mask & SNODE_COMMON_STATUS) {
325 if (node->flags & LYS_STATUS_CURR) {
326 yang_print_open(out, flag);
327 status = "current";
328 } else if (node->flags & LYS_STATUS_DEPRC) {
329 yang_print_open(out, flag);
330 status = "deprecated";
331 } else if (node->flags & LYS_STATUS_OBSLT) {
332 yang_print_open(out, flag);
333 status = "obsolete";
334 }
335 yang_print_substmt(out, level, LYEXT_SUBSTMT_STATUS, 0, status, module, node->ext, node->ext_size);
336 }
337
338 /* description */
339 if ((mask & SNODE_COMMON_DSC) && node->dsc) {
340 yang_print_open(out, flag);
341 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, node->dsc,
342 module, node->ext, node->ext_size);
343 }
344
345 /* reference */
346 if ((mask & SNODE_COMMON_REF) && node->ref) {
347 yang_print_open(out, flag);
348 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, node->ref,
349 module, node->ext, node->ext_size);
350 }
351}
352
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200353static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100354yang_print_feature(struct lyout *out, int level, const struct lys_feature *feat)
Michal Vasko4773b762015-07-07 12:15:10 +0200355{
Radek Krejci5dd25122017-01-11 17:28:13 +0100356 int flag = 0;
Michal Vasko30f6e912015-07-07 12:24:27 +0200357
Radek Krejci32cce7c2015-12-09 16:44:13 +0100358 ly_print(out, "%*sfeature %s", LEVEL, INDENT, feat->name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100359 yang_print_snode_common(out, level + 1, (struct lys_node *)feat, feat->module, &flag, SNODE_COMMON_EXT |
360 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100361 yang_print_close(out, level, flag);
Michal Vasko4773b762015-07-07 12:15:10 +0200362}
363
364static void
Radek Krejcia1a6b762016-11-14 09:53:38 +0900365yang_print_extension(struct lyout *out, int level, const struct lys_ext *ext)
366{
Radek Krejcicfce0292017-01-13 12:37:57 +0100367 int flag = 0, flag2 = 0, i;
Radek Krejcia1a6b762016-11-14 09:53:38 +0900368
369 ly_print(out, "%*sextension %s", LEVEL, INDENT, ext->name);
370 level++;
371
Radek Krejci5dd25122017-01-11 17:28:13 +0100372 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
373 SNODE_COMMON_EXT);
374
Radek Krejcia1a6b762016-11-14 09:53:38 +0900375 if (ext->argument) {
376 yang_print_open(out, &flag);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900377
Radek Krejcicfce0292017-01-13 12:37:57 +0100378 ly_print(out, "%*sargument %s", LEVEL, INDENT, ext->argument);
379 i = -1;
380 while ((i = ly_print_ext_iter(ext->ext, ext->ext_size, i + 1, LYEXT_SUBSTMT_ARGUMENT)) != -1) {
381 yang_print_open(out, &flag2);
382 yang_print_extension_instances(out, level + 1, ext->module, LYEXT_SUBSTMT_ARGUMENT, 0, &ext->ext[i], 1);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900383 }
Radek Krejcicfce0292017-01-13 12:37:57 +0100384 if (ext->flags & LYS_YINELEM) {
385 yang_print_open(out, &flag2);
386 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_YINELEM, 0, "true", ext->module, ext->ext, ext->ext_size);
387 }
388 yang_print_close(out, level, flag2);
Radek Krejcia1a6b762016-11-14 09:53:38 +0900389 }
390
Radek Krejci5dd25122017-01-11 17:28:13 +0100391 yang_print_snode_common(out, level, (struct lys_node *)ext, ext->module, &flag,
392 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
393
Radek Krejcia1a6b762016-11-14 09:53:38 +0900394 level--;
395 yang_print_close(out, level, flag);
396}
397
398static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100399yang_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 +0200400{
Radek Krejci5dd25122017-01-11 17:28:13 +0100401 if (restr->ext_size) {
402 yang_print_open(out, flag);
403 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, restr->ext, restr->ext_size);
404 }
Radek Krejcidaa95c42017-01-16 10:25:29 +0100405 if (restr->expr[0] == 0x15) {
406 /* special byte value in pattern's expression: 0x15 - invert-match, 0x06 - match */
407 yang_print_open(out, flag);
408 yang_print_substmt(out, level, LYEXT_SUBSTMT_MODIFIER, 0, "invert-match",
409 module, restr->ext, restr->ext_size);
410 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100411 if (restr->emsg != NULL) {
412 yang_print_open(out, flag);
413 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRMSG, 0, restr->emsg,
414 module, restr->ext, restr->ext_size);
415 }
416 if (restr->eapptag != NULL) {
417 yang_print_open(out, flag);
418 yang_print_substmt(out, level, LYEXT_SUBSTMT_ERRTAG, 0, restr->eapptag,
419 module, restr->ext, restr->ext_size);
420 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200421 if (restr->dsc != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100422 yang_print_open(out, flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100423 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, restr->dsc,
424 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200425 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200426 if (restr->ref != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100427 yang_print_open(out, flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100428 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, restr->ref,
429 module, restr->ext, restr->ext_size);
Radek Krejci41726f92015-06-19 13:11:05 +0200430 }
Radek Krejci41726f92015-06-19 13:11:05 +0200431}
432
433static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100434yang_print_when(struct lyout *out, int level, const struct lys_module *module, const struct lys_when *when)
Michal Vasko1f0428a2015-07-07 14:55:04 +0200435{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100436 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100437 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200438
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100439 str = transform_json2schema(module, when->cond);
440 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200441 ly_print(out, "(!error!)");
442 return;
443 }
444
Michal Vasko25cb6c62016-02-12 14:36:21 +0100445 ly_print(out, "%*swhen \"", LEVEL, INDENT);
446 yang_encode(out, str, -1);
447 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100448 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200449
Michal Vasko1f0428a2015-07-07 14:55:04 +0200450 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100451
Radek Krejci43e3c312017-01-11 11:34:44 +0100452 if (when->ext_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100453 /* 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 +0100454 yang_print_open(out, &flag);
455 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, when->ext, when->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200456 }
Radek Krejci11e88fd2017-01-16 15:34:37 +0100457 if (when->dsc != NULL) {
458 yang_print_open(out, &flag);
459 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, when->dsc,
460 module, when->ext, when->ext_size);
461 }
462 if (when->ref != NULL) {
463 yang_print_open(out, &flag);
464 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, when->ref,
465 module, when->ext, when->ext_size);
466 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100467
Michal Vasko1f0428a2015-07-07 14:55:04 +0200468 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100469 yang_print_close(out, level, flag);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200470}
471
472static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100473yang_print_type(struct lyout *out, int level, const struct lys_module *module, const struct lys_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200474{
Radek Krejci5dd25122017-01-11 17:28:13 +0100475 int i;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100476 int flag = 0, flag2;
Michal Vasko0fb82c62015-10-20 13:41:53 +0200477 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100478 char *s;
Radek Krejcic071c542016-01-27 14:57:51 +0100479 struct lys_module *mod;
Radek Krejci25d782a2015-05-22 15:03:23 +0200480
Michal Vasko0fb82c62015-10-20 13:41:53 +0200481 if (type->module_name) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100482 ly_print(out, "%*stype %s:%s", LEVEL, INDENT,
483 transform_module_name2import_prefix(module, type->module_name), type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200484 } else {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100485 ly_print(out, "%*stype %s", LEVEL, INDENT, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200486 }
487 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100488
489 /* extensions */
490 if (type->ext_size) {
491 yang_print_open(out, &flag);
492 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, type->ext, type->ext_size);
493 }
494
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200495 switch (type->base) {
496 case LY_TYPE_BINARY:
Michal Vasko4634cda2016-02-16 09:22:09 +0100497 if (type->info.binary.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100498 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100499 ly_print(out, "%*slength \"", LEVEL, INDENT);
500 yang_encode(out, type->info.binary.length->expr, -1);
501 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100502 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100503 yang_print_restr(out, level + 1, module, type->info.binary.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100504 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200505 }
506 break;
507 case LY_TYPE_BITS:
508 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100509 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100510 ly_print(out, "%*sbit %s", LEVEL, INDENT, type->info.bits.bit[i].name);
511 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200512 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100513 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
514 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100515 if (!(type->info.bits.bit[i].flags & LYS_AUTOASSIGNED)) {
516 yang_print_open(out, &flag2);
Radek Krejci43e3c312017-01-11 11:34:44 +0100517 asprintf(&s, "%u", type->info.bits.bit[i].pos);
518 yang_print_substmt(out, level, LYEXT_SUBSTMT_POSITION, 0, s,
519 module, type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size);
520 free(s);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100521 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100522 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i], module, &flag2,
523 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200524 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100525 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200526 }
527 break;
528 case LY_TYPE_DEC64:
Radek Krejcib51d5932016-09-08 14:02:52 +0200529 if (!type->der->type.der) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100530 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100531 asprintf(&s, "%d", type->info.dec64.dig);
532 yang_print_substmt(out, level, LYEXT_SUBSTMT_DIGITS, 0, s, module, type->ext, type->ext_size);
533 free(s);
Michal Vasko4634cda2016-02-16 09:22:09 +0100534 }
Michal Vaskoea505ee2015-07-07 14:01:00 +0200535 if (type->info.dec64.range != NULL) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100536 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100537 ly_print(out, "%*srange \"", LEVEL, INDENT);
538 yang_encode(out, type->info.dec64.range->expr, -1);
539 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100540 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100541 yang_print_restr(out, level + 1, module, type->info.dec64.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100542 yang_print_close(out, level, flag2);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200543 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200544 break;
545 case LY_TYPE_ENUM:
546 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100547 yang_print_open(out, &flag);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100548 ly_print(out, "%*senum \"%s\"", LEVEL, INDENT, type->info.enums.enm[i].name);
549 flag2 = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200550 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +0100551 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
552 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100553 if (!(type->info.enums.enm[i].flags & LYS_AUTOASSIGNED)) {
554 yang_print_open(out, &flag2);
Radek Krejci43e3c312017-01-11 11:34:44 +0100555 asprintf(&s, "%d", type->info.enums.enm[i].value);
556 yang_print_substmt(out, level, LYEXT_SUBSTMT_VALUE, 0, s,
557 module, type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size);
558 free(s);
Michal Vasko3f053ef2016-02-12 14:27:13 +0100559 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100560 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i], module, &flag2,
561 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200562 level--;
Michal Vasko3f053ef2016-02-12 14:27:13 +0100563 yang_print_close(out, level, flag2);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200564 }
565 break;
566 case LY_TYPE_IDENT:
Michal Vaskof2d43962016-09-02 11:10:16 +0200567 if (type->info.ident.count) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100568 yang_print_open(out, &flag);
Michal Vaskof2d43962016-09-02 11:10:16 +0200569 for (i = 0; i < type->info.ident.count; ++i) {
570 mod = lys_main_module(type->info.ident.ref[i]->module);
571 if (lys_main_module(module) == mod) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100572 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, type->info.ident.ref[i]->name,
573 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
Michal Vaskof2d43962016-09-02 11:10:16 +0200574 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100575 asprintf(&s, "%s:%s", transform_module_name2import_prefix(module, mod->name),
576 type->info.ident.ref[i]->name);
577 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, s,
578 module, type->info.ident.ref[i]->ext, type->info.ident.ref[i]->ext_size);
579 free(s);
Michal Vaskof2d43962016-09-02 11:10:16 +0200580 }
Michal Vasko4634cda2016-02-16 09:22:09 +0100581 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200582 }
583 break;
584 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200585 if (type->info.inst.req == 1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100586 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100587 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "true", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200588 } else if (type->info.inst.req == -1) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100589 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100590 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "false", module, type->ext, type->ext_size);
Radek Krejciaf351422015-06-19 14:49:38 +0200591 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200592 break;
593 case LY_TYPE_INT8:
594 case LY_TYPE_INT16:
595 case LY_TYPE_INT32:
596 case LY_TYPE_INT64:
597 case LY_TYPE_UINT8:
598 case LY_TYPE_UINT16:
599 case LY_TYPE_UINT32:
600 case LY_TYPE_UINT64:
Michal Vasko4634cda2016-02-16 09:22:09 +0100601 if (type->info.num.range) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100602 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100603 ly_print(out, "%*srange \"", LEVEL, INDENT);
604 yang_encode(out, type->info.num.range->expr, -1);
605 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100606 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100607 yang_print_restr(out, level + 1, module, type->info.num.range, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100608 yang_print_close(out, level, flag2);
Radek Krejcif2860132015-06-20 12:37:20 +0200609 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200610 break;
611 case LY_TYPE_LEAFREF:
Radek Krejci0dbff6a2016-07-17 12:40:18 +0200612 if (ly_strequal(type->der->name, "leafref", 0)) {
Michal Vasko4634cda2016-02-16 09:22:09 +0100613 yang_print_open(out, &flag);
614 str = transform_json2schema(module, type->info.lref.path);
Radek Krejci43e3c312017-01-11 11:34:44 +0100615 yang_print_substmt(out, level, LYEXT_SUBSTMT_PATH, 0, str, module, type->ext, type->ext_size);
Michal Vasko4634cda2016-02-16 09:22:09 +0100616 lydict_remove(module->ctx, str);
617 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100618 if (type->info.lref.req == 1) {
619 yang_print_open(out, &flag);
620 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "true", module, type->ext, type->ext_size);
621 } else if (type->info.lref.req == -1) {
622 yang_print_open(out, &flag);
623 yang_print_substmt(out, level, LYEXT_SUBSTMT_REQINST, 0, "false", module, type->ext, type->ext_size);
624 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200625 break;
626 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200627 if (type->info.str.length) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100628 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100629 ly_print(out, "%*slength \"", LEVEL, INDENT);
630 yang_encode(out, type->info.str.length->expr, -1);
631 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100632 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100633 yang_print_restr(out, level + 1, module, type->info.str.length, &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100634 yang_print_close(out, level, flag2);
Radek Krejci061bd522015-06-19 13:45:16 +0200635 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200636 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100637 yang_print_open(out, &flag);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100638 ly_print(out, "%*spattern \"", LEVEL, INDENT);
Radek Krejci0d23e7a2016-08-04 12:46:17 +0200639 yang_encode(out, &type->info.str.patterns[i].expr[1], -1);
Michal Vasko25cb6c62016-02-12 14:36:21 +0100640 ly_print(out, "\"");
Radek Krejci32cce7c2015-12-09 16:44:13 +0100641 flag2 = 0;
Radek Krejci43e3c312017-01-11 11:34:44 +0100642 yang_print_restr(out, level + 1, module, &type->info.str.patterns[i], &flag2);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100643 yang_print_close(out, level, flag2);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200644 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200645 break;
646 case LY_TYPE_UNION:
647 for (i = 0; i < type->info.uni.count; ++i) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100648 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +0200649 yang_print_type(out, level, module, &type->info.uni.types[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200650 }
651 break;
652 default:
653 /* other types do not have substatements */
654 break;
655 }
Radek Krejcie534c132016-11-23 13:32:31 +0100656
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200657 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100658 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200659}
660
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200661static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100662yang_print_must(struct lyout *out, int level, const struct lys_module *module, const struct lys_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200663{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100664 int flag = 0;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100665 const char *str;
Michal Vaskof9893382015-10-09 14:03:04 +0200666
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100667 str = transform_json2schema(module, must->expr);
668 if (!str) {
Michal Vaskof9893382015-10-09 14:03:04 +0200669 ly_print(out, "(!error!)");
670 return;
671 }
672
Michal Vasko25cb6c62016-02-12 14:36:21 +0100673 ly_print(out, "%*smust \"", LEVEL, INDENT);
674 yang_encode(out, str, -1);
675 ly_print(out, "\"");
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100676 lydict_remove(module->ctx, str);
Michal Vaskof9893382015-10-09 14:03:04 +0200677
Radek Krejci43e3c312017-01-11 11:34:44 +0100678 yang_print_restr(out, level + 1, module, must, &flag);
Radek Krejci32cce7c2015-12-09 16:44:13 +0100679 yang_print_close(out, level, flag);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200680}
681
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200682static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100683yang_print_unique(struct lyout *out, int level, const struct lys_unique *uniq)
Michal Vasko1ef07972015-07-07 14:01:35 +0200684{
685 int i;
686
Radek Krejci76b07902015-10-09 09:11:25 +0200687 ly_print(out, "%*sunique \"", LEVEL, INDENT);
Radek Krejci581ce772015-11-10 17:22:40 +0100688 for (i = 0; i < uniq->expr_size; i++) {
689 ly_print(out, "%s%s", uniq->expr[i], i + 1 < uniq->expr_size ? " " : "");
Michal Vasko1ef07972015-07-07 14:01:35 +0200690 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100691 ly_print(out, "\"");
Michal Vasko1ef07972015-07-07 14:01:35 +0200692}
693
694static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100695yang_print_refine(struct lyout *out, int level, const struct lys_module *module, const struct lys_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200696{
Radek Krejci5dd25122017-01-11 17:28:13 +0100697 int i, flag = 0;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200698 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100699 char *s;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200700
Michal Vasko5d112852016-02-12 16:47:13 +0100701 str = transform_json2schema(module, refine->target_name);
Radek Krejci5dd25122017-01-11 17:28:13 +0100702 ly_print(out, "%*srefine \"%s\"", LEVEL, INDENT, str);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200703 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200704 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200705
Radek Krejci5dd25122017-01-11 17:28:13 +0100706 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 +0200707 for (i = 0; i < refine->must_size; ++i) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100708 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +0200709 yang_print_must(out, level, module, &refine->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200710 }
Pavol Vican3e7c73a2016-08-17 10:24:11 +0200711 if (refine->target_type == LYS_CONTAINER) {
Radek Krejci5dd25122017-01-11 17:28:13 +0100712 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100713 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, refine->mod.presence,
714 module, refine->ext, refine->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +0100715 }
716 for (i = 0; i < refine->dflt_size; ++i) {
717 yang_print_open(out, &flag);
718 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, refine->dflt[i], module, refine->ext, refine->ext_size);
719 }
720 if (refine->flags & LYS_CONFIG_W) {
721 yang_print_open(out, &flag);
722 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module, refine->ext, refine->ext_size);
723 } else if (refine->flags & LYS_CONFIG_R) {
724 yang_print_open(out, &flag);
725 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module, refine->ext, refine->ext_size);
726 }
727 if (refine->flags & LYS_MAND_TRUE) {
728 yang_print_open(out, &flag);
729 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module, refine->ext, refine->ext_size);
730 } else if (refine->flags & LYS_MAND_FALSE) {
731 yang_print_open(out, &flag);
732 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module, refine->ext, refine->ext_size);
733 }
734 if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200735 if (refine->flags & LYS_RFN_MINSET) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100736 asprintf(&s, "%u", refine->mod.list.min);
Radek Krejci5dd25122017-01-11 17:28:13 +0100737 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100738 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, s, module, refine->ext, refine->ext_size);
739 free(s);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200740 }
Radek Krejci0f04a6c2016-04-14 16:16:36 +0200741 if (refine->flags & LYS_RFN_MAXSET) {
Radek Krejci0d7b2472016-02-12 11:11:03 +0100742 if (refine->mod.list.max) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100743 asprintf(&s, "%u", refine->mod.list.max);
Radek Krejci0d7b2472016-02-12 11:11:03 +0100744 } else {
Radek Krejci43e3c312017-01-11 11:34:44 +0100745 s = NULL;
Radek Krejci0d7b2472016-02-12 11:11:03 +0100746 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100747 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +0100748 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, s ? s : "unbounded", module, refine->ext, refine->ext_size);
749 free(s);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200750 }
751 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100752 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 +0200753
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200754 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +0100755 yang_print_close(out, level, flag);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200756}
757
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200758static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100759yang_print_deviation(struct lyout *out, int level, const struct lys_module *module,
760 const struct lys_deviation *deviation)
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200761{
Radek Krejci033983b2017-01-13 12:43:20 +0100762 int i, j, p;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200763 const char *str;
Radek Krejci43e3c312017-01-11 11:34:44 +0100764 char *s;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200765
Michal Vasko5d112852016-02-12 16:47:13 +0100766 str = transform_json2schema(module, deviation->target_name);
Michal Vaskoa8b25952015-10-20 15:30:25 +0200767 ly_print(out, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, str);
768 lydict_remove(module->ctx, str);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200769 level++;
770
Radek Krejci5dd25122017-01-11 17:28:13 +0100771 if (deviation->ext_size) {
772 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, deviation->ext, deviation->ext_size);
773 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100774 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, deviation->dsc,
775 module, deviation->ext, deviation->ext_size);
776 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, deviation->ref,
777 module, deviation->ext, deviation->ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200778
779 for (i = 0; i < deviation->deviate_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200780 ly_print(out, "%*sdeviate ", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200781 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
Michal Vaskod875e882016-05-19 10:57:30 +0200782 ly_print(out, "not-supported;\n");
783 continue;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200784 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
Radek Krejci76b07902015-10-09 09:11:25 +0200785 ly_print(out, "add {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200786 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200787 ly_print(out, "replace {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200788 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200789 ly_print(out, "delete {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200790 }
791 level++;
792
Radek Krejci5dd25122017-01-11 17:28:13 +0100793 /* extensions */
794 if (deviation->deviate[i].ext_size) {
795 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
796 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200797 }
798
Radek Krejci5dd25122017-01-11 17:28:13 +0100799 /* type */
800 if (deviation->deviate[i].type) {
801 yang_print_type(out, level, module, deviation->deviate[i].type);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200802 }
803
Radek Krejci5dd25122017-01-11 17:28:13 +0100804 /* units */
805 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, deviation->deviate[i].units, module,
806 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200807
Radek Krejci5dd25122017-01-11 17:28:13 +0100808 /* must */
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200809 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
Michal Vaskof9893382015-10-09 14:03:04 +0200810 yang_print_must(out, level, module, &deviation->deviate[i].must[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200811 }
812
Radek Krejci5dd25122017-01-11 17:28:13 +0100813 /* unique */
814
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200815 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
Radek Krejci76b07902015-10-09 09:11:25 +0200816 yang_print_unique(out, level, &deviation->deviate[i].unique[j]);
Radek Krejci43e3c312017-01-11 11:34:44 +0100817 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +0100818 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +0100819 do {
Radek Krejcicfce0292017-01-13 12:37:57 +0100820 p = ly_print_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
821 p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejci43e3c312017-01-11 11:34:44 +0100822 } while (p != -1 && deviation->deviate[i].ext[p]->substmt_index != j);
823 if (p != -1) {
824 ly_print(out, " {\n");
825 do {
826 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_UNIQUE, j,
827 &deviation->deviate[i].ext[p], 1);
828 do {
829 p = ly_print_ext_iter(deviation->deviate[i].ext, deviation->deviate[i].ext_size,
830 p + 1, LYEXT_SUBSTMT_UNIQUE);
831 } while (p != -1 && deviation->deviate[i].ext[p]->substmt_index != j);
832 } while (p != -1);
833 ly_print(out, "%*s}\n", LEVEL, INDENT);
834 } else {
835 ly_print(out, ";\n");
836 }
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200837 }
838
Radek Krejci5dd25122017-01-11 17:28:13 +0100839 /* default */
Radek Krejci033983b2017-01-13 12:43:20 +0100840 for (j = 0; j < deviation->deviate[i].dflt_size; ++j) {
841 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, j, deviation->deviate[i].dflt[j], module,
Radek Krejci5dd25122017-01-11 17:28:13 +0100842 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200843 }
844
Radek Krejci5dd25122017-01-11 17:28:13 +0100845 /* config */
846 if (deviation->deviate[i].flags & LYS_CONFIG_W) {
847 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "true", module,
848 deviation->deviate->ext, deviation->deviate[i].ext_size);
849 } else if (deviation->deviate[i].flags & LYS_CONFIG_R) {
850 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONFIG, 0, "false", module,
851 deviation->deviate->ext, deviation->deviate[i].ext_size);
852 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100853
Radek Krejci5dd25122017-01-11 17:28:13 +0100854 /* mandatory */
855 if (deviation->deviate[i].flags & LYS_MAND_TRUE) {
856 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "true", module,
857 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
858 } else if (deviation->deviate[i].flags & LYS_MAND_FALSE) {
859 yang_print_substmt(out, level, LYEXT_SUBSTMT_MANDATORY, 0, "false", module,
860 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
861 }
862
863 /* min-elements */
864 if (deviation->deviate[i].min_set) {
865 asprintf(&s, "%u", deviation->deviate[i].min);
866 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, s, module,
867 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
868 free(s);
869 }
870
871 /* max-elements */
872 if (deviation->deviate[i].max_set) {
873 if (deviation->deviate[i].max) {
874 asprintf(&s, "%u", deviation->deviate[i].max);
875 } else {
876 s = NULL;
877 }
878 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, s ? s : "unbounded", module,
879 deviation->deviate[i].ext, deviation->deviate[i].ext_size);
880 free(s);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200881 }
882
883 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200884 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200885 }
886
887 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200888 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200889}
890
891static void
Radek Krejci43e3c312017-01-11 11:34:44 +0100892yang_print_augment(struct lyout *out, int level, const struct lys_node_augment *augment)
Michal Vasko6f25f212015-07-07 15:42:07 +0200893{
Radek Krejci76512572015-08-04 09:47:08 +0200894 struct lys_node *sub;
Michal Vasko488c19e2015-10-20 15:21:00 +0200895 const char *str;
Michal Vasko6f25f212015-07-07 15:42:07 +0200896
Radek Krejci43e3c312017-01-11 11:34:44 +0100897 str = transform_json2schema(augment->module, augment->target_name);
Michal Vasko488c19e2015-10-20 15:21:00 +0200898 ly_print(out, "%*saugment \"%s\" {\n", LEVEL, INDENT, str);
Radek Krejci43e3c312017-01-11 11:34:44 +0100899 lydict_remove(augment->module->ctx, str);
Michal Vasko6f25f212015-07-07 15:42:07 +0200900 level++;
901
Radek Krejci5dd25122017-01-11 17:28:13 +0100902 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL, SNODE_COMMON_EXT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200903 if (augment->when) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100904 yang_print_when(out, level, augment->module, augment->when);
Michal Vasko6f25f212015-07-07 15:42:07 +0200905 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100906 yang_print_snode_common(out, level, (struct lys_node *)augment, augment->module, NULL,
907 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200908
909 LY_TREE_FOR(augment->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +0100910 /* only our augment */
911 if (sub->parent != (struct lys_node *)augment) {
912 continue;
913 }
Radek Krejci76b07902015-10-09 09:11:25 +0200914 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200915 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +0100916 LYS_USES | LYS_ANYDATA | LYS_CASE | LYS_ACTION | LYS_NOTIF);
Michal Vasko6f25f212015-07-07 15:42:07 +0200917 }
918
919 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200920 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200921}
922
923static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100924yang_print_typedef(struct lyout *out, int level, const struct lys_module *module, const struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200925{
Radek Krejci033983b2017-01-13 12:43:20 +0100926 const char *dflt;
927
Radek Krejci76b07902015-10-09 09:11:25 +0200928 ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200929 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200930
Radek Krejci5dd25122017-01-11 17:28:13 +0100931 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL, SNODE_COMMON_EXT);
Radek Krejci76b07902015-10-09 09:11:25 +0200932 yang_print_type(out, level, module, &tpdf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200933 if (tpdf->units != NULL) {
Radek Krejci43e3c312017-01-11 11:34:44 +0100934 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, tpdf->units, module, tpdf->ext, tpdf->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200935 }
936 if (tpdf->dflt != NULL) {
Radek Krejcibd117f02016-11-04 16:28:08 +0100937 if (tpdf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +0100938 assert(strchr(tpdf->dflt, ':'));
939 if (!strncmp(tpdf->dflt, module->name, strchr(tpdf->dflt, ':') - tpdf->dflt)) {
940 /* local module */
941 dflt = lydict_insert(module->ctx, strchr(tpdf->dflt, ':') + 1, 0);
942 } else {
943 dflt = transform_json2schema(module, tpdf->dflt);
944 }
Radek Krejcibd117f02016-11-04 16:28:08 +0100945 } else {
946 dflt = tpdf->dflt;
947 }
Radek Krejci43e3c312017-01-11 11:34:44 +0100948 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt, module, tpdf->ext, tpdf->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +0100949 if (tpdf->flags & LYS_DFLTJSON) {
950 lydict_remove(module->ctx, dflt);
951 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200952 }
Radek Krejci5dd25122017-01-11 17:28:13 +0100953 yang_print_snode_common(out, level, (struct lys_node *)tpdf, module, NULL,
954 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200955
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200956 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200957 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200958}
959
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200960static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100961yang_print_identity(struct lyout *out, int level, const struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200962{
Radek Krejci018f1f52016-08-03 16:01:20 +0200963 int flag = 0, i;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +0100964 struct lys_module *mod;
Radek Krejci43e3c312017-01-11 11:34:44 +0100965 char *str;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100966
967 ly_print(out, "%*sidentity %s", LEVEL, INDENT, ident->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200968 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200969
Radek Krejci5dd25122017-01-11 17:28:13 +0100970 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
971 SNODE_COMMON_EXT | SNODE_COMMON_IFF);
972
Radek Krejci018f1f52016-08-03 16:01:20 +0200973 for (i = 0; i < ident->base_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +0100974 yang_print_open(out, &flag);
Radek Krejci018f1f52016-08-03 16:01:20 +0200975 mod = lys_main_module(ident->base[i]->module);
Radek Krejci43e3c312017-01-11 11:34:44 +0100976 if (lys_main_module(ident->module) == mod) {
977 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, ident->base[i]->name,
978 ident->module, ident->ext, ident->ext_size);
979 } else {
980 asprintf(&str, "%s:%s", transform_module_name2import_prefix(ident->module, mod->name), ident->base[i]->name);
981 yang_print_substmt(out, level, LYEXT_SUBSTMT_BASE, 0, str,
982 ident->module, ident->ext, ident->ext_size);
983 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200984 }
985 }
Radek Krejci6793db02015-05-22 17:49:54 +0200986
Radek Krejci5dd25122017-01-11 17:28:13 +0100987 yang_print_snode_common(out, level, (struct lys_node *)ident, ident->module, &flag,
988 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
989
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200990 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +0100991 yang_print_close(out, level, flag);
Radek Krejci6793db02015-05-22 17:49:54 +0200992}
993
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200994static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100995yang_print_container(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200996{
Radek Krejci32cce7c2015-12-09 16:44:13 +0100997 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +0200998 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200999 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001000
Radek Krejci32cce7c2015-12-09 16:44:13 +01001001 ly_print(out, "%*scontainer %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001002 level++;
Radek Krejci6a113852015-07-03 16:04:20 +02001003
Radek Krejci5dd25122017-01-11 17:28:13 +01001004 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001005 if (cont->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001006 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001007 yang_print_when(out, level, node->module, cont->when);
1008 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001009 for (i = 0; i < cont->iffeature_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001010 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001011 yang_print_iffeature(out, level, node->module, &cont->iffeature[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001012 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001013 for (i = 0; i < cont->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001014 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001015 yang_print_must(out, level, node->module, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001016 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001017 if (cont->presence != NULL) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001018 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001019 yang_print_substmt(out, level, LYEXT_SUBSTMT_PRESENCE, 0, cont->presence,
1020 node->module, node->ext, node->ext_size);
Michal Vasko4773b762015-07-07 12:15:10 +02001021 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001022 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG |
1023 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001024 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001025 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001026 yang_print_typedef(out, level, node->module, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001027 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001028 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001029 /* augments */
1030 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001031 continue;
1032 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001033 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +01001034 yang_print_snode(out, level, sub, LYS_GROUPING);
1035 }
1036 LY_TREE_FOR(node->child, sub) {
1037 /* augments */
1038 if (sub->parent != node) {
1039 continue;
1040 }
1041 yang_print_open(out, &flag);
1042 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1043 LYS_USES | LYS_ANYDATA );
1044 }
1045 LY_TREE_FOR(node->child, sub) {
1046 /* augments */
1047 if (sub->parent != node) {
1048 continue;
1049 }
1050 yang_print_open(out, &flag);
1051 yang_print_snode(out, level, sub, LYS_ACTION);
1052 }
1053 LY_TREE_FOR(node->child, sub) {
1054 /* augments */
1055 if (sub->parent != node) {
1056 continue;
1057 }
1058 yang_print_open(out, &flag);
Radek Krejci033983b2017-01-13 12:43:20 +01001059 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001060 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001061
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001062 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001063 yang_print_close(out, level, flag);
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001064}
1065
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001066static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001067yang_print_case(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001068{
Radek Krejci5dd25122017-01-11 17:28:13 +01001069 int flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001070 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001071 struct lys_node_case *cas = (struct lys_node_case *)node;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001072
Radek Krejci5dd25122017-01-11 17:28:13 +01001073 ly_print(out, "%*scase %s", LEVEL, INDENT, cas->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001074 level++;
Michal Vaskoc1329bc2015-06-09 13:58:18 +02001075
Radek Krejci5dd25122017-01-11 17:28:13 +01001076 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001077 if (cas->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001078 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001079 yang_print_when(out, level, node->module, cas->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001080 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001081 yang_print_snode_common(out, level, node, node->module, &flag,
1082 SNODE_COMMON_IFF | SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001083
Radek Krejci1d82ef62015-08-07 14:44:40 +02001084 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001085 /* augments */
1086 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001087 continue;
1088 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001089 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001090 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001091 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejcibf2abff2016-08-23 15:51:52 +02001092 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001093 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001094
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001095 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001096 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001097}
1098
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001099static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001100yang_print_choice(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001101{
Radek Krejci5dd25122017-01-11 17:28:13 +01001102 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001103 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001104 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001105
Radek Krejci5dd25122017-01-11 17:28:13 +01001106 ly_print(out, "%*schoice %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001107 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001108
1109 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1110 if (choice->when) {
1111 yang_print_open(out, &flag);
1112 yang_print_when(out, level, node->module, choice->when);
1113 }
1114 for (i = 0; i < choice->iffeature_size; i++) {
1115 yang_print_open(out, &flag);
1116 yang_print_iffeature(out, level, node->module, &choice->iffeature[i]);
1117 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001118 if (choice->dflt != NULL) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001119 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001120 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, choice->dflt->name,
1121 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001122 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001123 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1124 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001125
Radek Krejci1d82ef62015-08-07 14:44:40 +02001126 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001127 /* augments */
1128 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001129 continue;
1130 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001131 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001132 yang_print_snode(out, level, sub,
Radek Krejci5dd25122017-01-11 17:28:13 +01001133 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_CASE);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001134 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001135
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001136 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001137 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001138}
1139
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001140static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001141yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001142{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001143 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001144 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001145 const char *dflt;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001146
Radek Krejci76b07902015-10-09 09:11:25 +02001147 ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001148 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001149
1150 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001151 if (leaf->when) {
1152 yang_print_when(out, level, node->module, leaf->when);
1153 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001154 for (i = 0; i < leaf->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001155 yang_print_iffeature(out, level, node->module, &leaf->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001156 }
Radek Krejci76b07902015-10-09 09:11:25 +02001157 yang_print_type(out, level, node->module, &leaf->type);
Radek Krejci43e3c312017-01-11 11:34:44 +01001158 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, leaf->units,
1159 node->module, node->ext, node->ext_size);
Radek Krejci5dd25122017-01-11 17:28:13 +01001160 for (i = 0; i < leaf->must_size; i++) {
1161 yang_print_must(out, level, node->module, &leaf->must[i]);
1162 }
Michal Vaskod875e882016-05-19 10:57:30 +02001163 if (leaf->dflt) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001164 if (leaf->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001165 assert(strchr(leaf->dflt, ':'));
1166 if (!strncmp(leaf->dflt, lys_node_module(node)->name, strchr(leaf->dflt, ':') - leaf->dflt)) {
1167 /* local module */
1168 dflt = lydict_insert(node->module->ctx, strchr(leaf->dflt, ':') + 1, 0);
1169 } else {
1170 dflt = transform_json2schema(node->module, leaf->dflt);
1171 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001172 } else {
1173 dflt = leaf->dflt;
1174 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001175 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, 0, dflt,
1176 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001177 if (leaf->flags & LYS_DFLTJSON) {
1178 lydict_remove(node->module->ctx, dflt);
1179 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001180 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001181 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1182 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001183 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001184 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +02001185}
1186
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001187static void
Radek Krejcibf2abff2016-08-23 15:51:52 +02001188yang_print_anydata(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko16083662015-06-09 14:00:45 +02001189{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001190 int i, flag = 0;
Radek Krejcibf2abff2016-08-23 15:51:52 +02001191 struct lys_node_anydata *any = (struct lys_node_anydata *)node;
Michal Vasko16083662015-06-09 14:00:45 +02001192
Radek Krejcibf2abff2016-08-23 15:51:52 +02001193 ly_print(out, "%*s%s %s", LEVEL, INDENT, any->nodetype == LYS_ANYXML ? "anyxml" : "anydata", any->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001194 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001195
1196 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
1197 if (any->when) {
1198 yang_print_open(out, &flag);
1199 yang_print_when(out, level, node->module, any->when);
1200 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001201 for (i = 0; i < any->iffeature_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001202 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001203 yang_print_iffeature(out, level, node->module, &any->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001204 }
Radek Krejcibf2abff2016-08-23 15:51:52 +02001205 for (i = 0; i < any->must_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001206 yang_print_open(out, &flag);
Radek Krejcibf2abff2016-08-23 15:51:52 +02001207 yang_print_must(out, level, node->module, &any->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001208 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001209 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG | SNODE_COMMON_MAND |
1210 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001211 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001212 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001213}
1214
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001215static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001216yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001217{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001218 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001219 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
Radek Krejcibd117f02016-11-04 16:28:08 +01001220 const char *dflt;
Radek Krejci43e3c312017-01-11 11:34:44 +01001221 char *str;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001222
Radek Krejci76b07902015-10-09 09:11:25 +02001223 ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001224 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001225 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001226 if (llist->when) {
1227 yang_print_when(out, level, llist->module, llist->when);
1228 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001229 for (i = 0; i < llist->iffeature_size; i++) {
Radek Krejci9ff0a922016-07-14 13:08:05 +02001230 yang_print_iffeature(out, level, node->module, &llist->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001231 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001232 yang_print_type(out, level, node->module, &llist->type);
1233 yang_print_substmt(out, level, LYEXT_SUBSTMT_UNITS, 0, llist->units,
1234 node->module, node->ext, node->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001235 for (i = 0; i < llist->must_size; i++) {
1236 yang_print_must(out, level, node->module, &llist->must[i]);
1237 }
Pavol Vican38321d02016-08-16 14:56:02 +02001238 for (i = 0; i < llist->dflt_size; ++i) {
Radek Krejcibd117f02016-11-04 16:28:08 +01001239 if (llist->flags & LYS_DFLTJSON) {
Michal Vaskof30ea3e2016-12-06 12:16:02 +01001240 assert(strchr(llist->dflt[i], ':'));
1241 if (!strncmp(llist->dflt[i], lys_node_module(node)->name, strchr(llist->dflt[i], ':') - llist->dflt[i])) {
1242 /* local module */
1243 dflt = lydict_insert(node->module->ctx, strchr(llist->dflt[i], ':') + 1, 0);
1244 } else {
1245 dflt = transform_json2schema(node->module, llist->dflt[i]);
1246 }
Radek Krejcibd117f02016-11-04 16:28:08 +01001247 } else {
1248 dflt = llist->dflt[i];
1249 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001250 yang_print_substmt(out, level, LYEXT_SUBSTMT_DEFAULT, i, dflt,
1251 node->module, node->ext, node->ext_size);
Radek Krejcibd117f02016-11-04 16:28:08 +01001252 if (llist->flags & LYS_DFLTJSON) {
1253 lydict_remove(node->module->ctx, dflt);
1254 }
Pavol Vican38321d02016-08-16 14:56:02 +02001255 }
Radek Krejci178a0942017-01-16 15:36:35 +01001256 yang_print_snode_common(out, level, node, node->module, NULL, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001257 if (llist->min > 0) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001258 asprintf(&str, "%u", llist->min);
1259 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, str,
1260 node->module, node->ext, node->ext_size);
1261 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001262 }
1263 if (llist->max > 0) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001264 asprintf(&str, "%u", llist->max);
1265 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, str,
1266 node->module, node->ext, node->ext_size);
1267 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001268 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001269 if (llist->flags & LYS_USERORDERED) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001270 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1271 node->module, node->ext, node->ext_size);
1272 } else if (ly_print_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
1273 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1274 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001275 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001276 yang_print_snode_common(out, level, node, node->module, NULL,
1277 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001278 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001279 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001280}
1281
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001282static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001283yang_print_list(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001284{
Radek Krejci5dd25122017-01-11 17:28:13 +01001285 int i, p, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001286 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001287 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejci43e3c312017-01-11 11:34:44 +01001288 char *str;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001289
Radek Krejci5dd25122017-01-11 17:28:13 +01001290 ly_print(out, "%*slist %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001291 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001292 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Radek Krejci8d81e002015-12-10 11:18:59 +01001293 if (list->when) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001294 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001295 yang_print_when(out, level, list->module, list->when);
1296 }
Michal Vaskoc5c26b02016-06-29 11:10:29 +02001297 for (i = 0; i < list->iffeature_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001298 yang_print_open(out, &flag);
Radek Krejci9ff0a922016-07-14 13:08:05 +02001299 yang_print_iffeature(out, level, node->module, &list->iffeature[i]);
Michal Vasko4773b762015-07-07 12:15:10 +02001300 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001301 for (i = 0; i < list->must_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001302 yang_print_open(out, &flag);
Radek Krejci8d81e002015-12-10 11:18:59 +01001303 yang_print_must(out, level, list->module, &list->must[i]);
1304 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001305 if (list->keys_size) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001306 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001307 yang_print_substmt(out, level, LYEXT_SUBSTMT_KEY, 0, list->keys_str,
1308 node->module, node->ext, node->ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001309 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001310 for (i = 0; i < list->unique_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001311 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001312 yang_print_unique(out, level, &list->unique[i]);
Radek Krejci43e3c312017-01-11 11:34:44 +01001313 /* unique's extensions */
Radek Krejcicfce0292017-01-13 12:37:57 +01001314 p = -1;
Radek Krejci43e3c312017-01-11 11:34:44 +01001315 do {
Radek Krejcicfce0292017-01-13 12:37:57 +01001316 p = ly_print_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
Radek Krejci43e3c312017-01-11 11:34:44 +01001317 } while (p != -1 && list->ext[p]->substmt_index != i);
1318 if (p != -1) {
1319 ly_print(out, " {\n");
1320 do {
1321 yang_print_extension_instances(out, level + 1, list->module, LYEXT_SUBSTMT_UNIQUE, i, &list->ext[p], 1);
1322 do {
1323 p = ly_print_ext_iter(list->ext, list->ext_size, p + 1, LYEXT_SUBSTMT_UNIQUE);
1324 } while (p != -1 && list->ext[p]->substmt_index != i);
1325 } while (p != -1);
1326 ly_print(out, "%*s}\n", LEVEL, INDENT);
1327 } else {
1328 ly_print(out, ";\n");
1329 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001330 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001331 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_CONFIG);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001332 if (list->min > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001333 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001334 asprintf(&str, "%u", list->min);
1335 yang_print_substmt(out, level, LYEXT_SUBSTMT_MIN, 0, str,
1336 node->module, node->ext, node->ext_size);
1337 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001338 }
1339 if (list->max > 0) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001340 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001341 asprintf(&str, "%u", list->max);
1342 yang_print_substmt(out, level, LYEXT_SUBSTMT_MAX, 0, str,
1343 node->module, node->ext, node->ext_size);
1344 free(str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001345 }
Radek Krejci8d81e002015-12-10 11:18:59 +01001346 if (list->flags & LYS_USERORDERED) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001347 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001348 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "user",
1349 node->module, node->ext, node->ext_size);
1350 } else if (ly_print_ext_iter(node->ext, node->ext_size, 0, LYEXT_SUBSTMT_ORDEREDBY) != -1) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001351 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001352 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORDEREDBY, 0, "system",
1353 node->module, node->ext, node->ext_size);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001354 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001355 yang_print_snode_common(out, level, node, node->module, &flag,
1356 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001357 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001358 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001359 yang_print_typedef(out, level, list->module, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001360 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001361
Radek Krejci1d82ef62015-08-07 14:44:40 +02001362 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001363 /* augments */
1364 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001365 continue;
1366 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001367 yang_print_open(out, &flag);
1368 yang_print_snode(out, level, sub, LYS_GROUPING);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001369 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001370
1371 LY_TREE_FOR(node->child, sub) {
1372 /* augments */
1373 if (sub->parent != node) {
1374 continue;
1375 }
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_GROUPING | LYS_ANYDATA);
1379 }
1380
1381 LY_TREE_FOR(node->child, sub) {
1382 /* augments */
1383 if (sub->parent != node) {
1384 continue;
1385 }
1386 yang_print_open(out, &flag);
1387 yang_print_snode(out, level, sub, LYS_ACTION);
1388 }
1389
1390 LY_TREE_FOR(node->child, sub) {
1391 /* augments */
1392 if (sub->parent != node) {
1393 continue;
1394 }
1395 yang_print_open(out, &flag);
1396 yang_print_snode(out, level, sub, LYS_NOTIF);
1397 }
1398
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001399 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001400 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001401}
1402
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001403static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001404yang_print_grouping(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001405{
Radek Krejci5dd25122017-01-11 17:28:13 +01001406 int i, flag = 0;
Michal Vasko0c5e9282016-02-15 13:11:57 +01001407 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001408 struct lys_node_grp *grp = (struct lys_node_grp *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001409
Radek Krejci5dd25122017-01-11 17:28:13 +01001410 ly_print(out, "%*sgrouping %s", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001411 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001412
Radek Krejci5dd25122017-01-11 17:28:13 +01001413 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_STATUS |
1414 SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001415
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001416 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001417 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001418 yang_print_typedef(out, level, node->module, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001419 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001420
Michal Vasko0c5e9282016-02-15 13:11:57 +01001421 LY_TREE_FOR(node->child, sub) {
Radek Krejci5dd25122017-01-11 17:28:13 +01001422 yang_print_open(out, &flag);
1423 yang_print_snode(out, level, sub, LYS_GROUPING);
1424 }
1425
1426 LY_TREE_FOR(node->child, sub) {
1427 yang_print_open(out, &flag);
1428 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1429 LYS_USES | LYS_ANYDATA);
1430 }
1431
1432 LY_TREE_FOR(node->child, sub) {
1433 yang_print_open(out, &flag);
1434 yang_print_snode(out, level, sub, LYS_ACTION);
1435 }
1436
1437 LY_TREE_FOR(node->child, sub) {
1438 yang_print_open(out, &flag);
1439 yang_print_snode(out, level, sub, LYS_NOTIF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001440 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001441
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001442 level--;
Radek Krejci5dd25122017-01-11 17:28:13 +01001443 yang_print_close(out, level, flag);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001444}
1445
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001446static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001447yang_print_uses(struct lyout *out, int level, const struct lys_node *node)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001448{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001449 int i, flag = 0;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001450 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001451 struct lys_module *mod;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001452
Radek Krejci76b07902015-10-09 09:11:25 +02001453 ly_print(out, "%*suses ", LEVEL, INDENT);
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001454 if (node->child) {
Michal Vasko6c629ac2016-02-15 14:08:23 +01001455 mod = lys_node_module(node->child);
Michal Vasko1dae8ec2016-02-15 14:49:01 +01001456 if (lys_node_module(node) != mod) {
Michal Vasko1bb7a5a2016-02-05 14:28:02 +01001457 ly_print(out, "%s:", transform_module_name2import_prefix(node->module, mod->name));
1458 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +02001459 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001460 ly_print(out, "%s", uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001461 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001462
Radek Krejci5dd25122017-01-11 17:28:13 +01001463 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001464 if (uses->when) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001465 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001466 yang_print_when(out, level, node->module, uses->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +02001467 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001468 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_IFF |
1469 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001470 for (i = 0; i < uses->refine_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001471 yang_print_open(out, &flag);
Michal Vaskof9893382015-10-09 14:03:04 +02001472 yang_print_refine(out, level, node->module, &uses->refine[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001473 }
Michal Vasko6f25f212015-07-07 15:42:07 +02001474 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001475 yang_print_open(out, &flag);
Radek Krejci43e3c312017-01-11 11:34:44 +01001476 yang_print_augment(out, level, &uses->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001477 }
1478
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001479 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001480 yang_print_close(out, level, flag);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +02001481}
1482
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001483static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001484yang_print_input_output(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko5bbae102015-06-16 12:16:44 +02001485{
Michal Vaskof4d3d742015-06-16 11:51:09 +02001486 int i;
Radek Krejci76512572015-08-04 09:47:08 +02001487 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001488 struct lys_node_inout *inout = (struct lys_node_inout *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001489
Radek Krejci76b07902015-10-09 09:11:25 +02001490 ly_print(out, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LYS_INPUT ? "input" : "output"));
Michal Vaskof4d3d742015-06-16 11:51:09 +02001491 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001492
Radek Krejcie534c132016-11-23 13:32:31 +01001493 if (node->ext_size) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001494 yang_print_extension_instances(out, level, node->module, LYEXT_SUBSTMT_SELF, 0, node->ext, node->ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001495 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001496 for (i = 0; i < inout->must_size; i++) {
1497 yang_print_must(out, level, node->module, &inout->must[i]);
1498 }
Radek Krejcie534c132016-11-23 13:32:31 +01001499 for (i = 0; i < inout->tpdf_size; i++) {
1500 yang_print_typedef(out, level, node->module, &inout->tpdf[i]);
1501 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001502 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001503 /* augments */
1504 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001505 continue;
1506 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001507 yang_print_snode(out, level, sub, LYS_GROUPING);
1508 }
1509 LY_TREE_FOR(node->child, sub) {
1510 /* augments */
1511 if (sub->parent != node) {
1512 continue;
1513 }
1514 yang_print_snode(out, level, sub, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1515 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001516 }
1517
1518 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001519 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001520}
1521
1522static void
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001523yang_print_rpc_action(struct lyout *out, int level, const struct lys_node *node)
Michal Vaskof4d3d742015-06-16 11:51:09 +02001524{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001525 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001526 struct lys_node *sub;
Michal Vasko44fb6382016-06-29 11:12:27 +02001527 struct lys_node_rpc_action *rpc = (struct lys_node_rpc_action *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001528
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001529 ly_print(out, "%*s%s %s", LEVEL, INDENT, (node->nodetype == LYS_RPC ? "rpc" : "action"), node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001530
1531 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001532 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF |
1533 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
Michal Vasko4773b762015-07-07 12:15:10 +02001534
Michal Vaskof4d3d742015-06-16 11:51:09 +02001535 for (i = 0; i < rpc->tpdf_size; i++) {
Radek Krejci32cce7c2015-12-09 16:44:13 +01001536 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001537 yang_print_typedef(out, level, node->module, &rpc->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001538 }
1539
Radek Krejci1d82ef62015-08-07 14:44:40 +02001540 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001541 /* augments */
1542 if (sub->parent != node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001543 continue;
1544 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001545 yang_print_open(out, &flag);
Radek Krejci5dd25122017-01-11 17:28:13 +01001546 yang_print_snode(out, level, sub, LYS_GROUPING);
1547 }
1548
1549 LY_TREE_FOR(node->child, sub) {
1550 /* augments */
1551 if (sub->parent != node) {
1552 continue;
1553 }
1554 yang_print_open(out, &flag);
1555 yang_print_snode(out, level, sub, LYS_INPUT);
1556 }
1557
1558 LY_TREE_FOR(node->child, sub) {
1559 /* augments */
1560 if (sub->parent != node) {
1561 continue;
1562 }
1563 yang_print_open(out, &flag);
1564 yang_print_snode(out, level, sub, LYS_OUTPUT);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001565 }
1566
1567 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001568 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001569}
1570
1571static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001572yang_print_notif(struct lyout *out, int level, const struct lys_node *node)
Michal Vasko7690bc12015-06-16 12:26:05 +02001573{
Radek Krejci32cce7c2015-12-09 16:44:13 +01001574 int i, flag = 0;
Radek Krejci76512572015-08-04 09:47:08 +02001575 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001576 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +02001577
Radek Krejci32cce7c2015-12-09 16:44:13 +01001578 ly_print(out, "%*snotification %s", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001579
1580 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001581 yang_print_snode_common(out, level, node, node->module, &flag, SNODE_COMMON_EXT | SNODE_COMMON_IFF);
Radek Krejci12032a52016-07-29 15:42:56 +02001582 for (i = 0; i < notif->must_size; i++) {
1583 yang_print_open(out, &flag);
1584 yang_print_must(out, level, node->module, &notif->must[i]);
1585 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001586 yang_print_snode_common(out, level, node, node->module, &flag,
1587 SNODE_COMMON_STATUS | SNODE_COMMON_DSC | SNODE_COMMON_REF);
1588 for (i = 0; i < notif->tpdf_size; i++) {
1589 yang_print_open(out, &flag);
1590 yang_print_typedef(out, level, node->module, &notif->tpdf[i]);
1591 }
1592 LY_TREE_FOR(node->child, sub) {
1593 /* augments */
1594 if (sub->parent != node) {
1595 continue;
1596 }
1597 yang_print_open(out, &flag);
1598 yang_print_snode(out, level, sub, LYS_GROUPING);
1599 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001600 LY_TREE_FOR(node->child, sub) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001601 /* augments */
1602 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +02001603 continue;
1604 }
Radek Krejci32cce7c2015-12-09 16:44:13 +01001605 yang_print_open(out, &flag);
Radek Krejci76b07902015-10-09 09:11:25 +02001606 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +02001607 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
Radek Krejci5dd25122017-01-11 17:28:13 +01001608 LYS_USES | LYS_ANYDATA);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001609 }
1610
1611 level--;
Radek Krejci32cce7c2015-12-09 16:44:13 +01001612 yang_print_close(out, level, flag);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001613}
1614
1615static void
Michal Vasko1e62a092015-12-01 12:27:20 +01001616yang_print_snode(struct lyout *out, int level, const struct lys_node *node, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001617{
Radek Krejci2c99a622017-01-12 10:11:13 +01001618 if (node->nodetype & mask) {
1619 if ((node->nodetype & (LYS_INPUT | LYS_OUTPUT)) && (node->flags & LYS_IMPLICIT)) {
1620 /* implicit input/output node is not supposed to be printed */
1621 return;
1622 } else if (!node->parent ||
1623 (node->parent->nodetype == LYS_AUGMENT && node != node->parent->child) ||
1624 (node->parent->nodetype != LYS_AUGMENT && node->prev->next)) {
1625 /* do not print the blank line before the first data-def node */
1626 ly_print(out, "\n");
1627 }
1628 }
1629
Radek Krejci1d82ef62015-08-07 14:44:40 +02001630 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +02001631 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +02001632 yang_print_container(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001633 break;
Radek Krejci76512572015-08-04 09:47:08 +02001634 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +02001635 yang_print_choice(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001636 break;
Radek Krejci76512572015-08-04 09:47:08 +02001637 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +02001638 yang_print_leaf(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001639 break;
Radek Krejci76512572015-08-04 09:47:08 +02001640 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001641 yang_print_leaflist(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001642 break;
Radek Krejci76512572015-08-04 09:47:08 +02001643 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001644 yang_print_list(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001645 break;
Radek Krejci76512572015-08-04 09:47:08 +02001646 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +02001647 yang_print_uses(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001648 break;
Radek Krejci76512572015-08-04 09:47:08 +02001649 case LYS_GROUPING:
Radek Krejci76b07902015-10-09 09:11:25 +02001650 yang_print_grouping(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001651 break;
Radek Krejci76512572015-08-04 09:47:08 +02001652 case LYS_ANYXML:
Radek Krejcibf2abff2016-08-23 15:51:52 +02001653 case LYS_ANYDATA:
1654 yang_print_anydata(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001655 break;
Radek Krejci76512572015-08-04 09:47:08 +02001656 case LYS_CASE:
Radek Krejci76b07902015-10-09 09:11:25 +02001657 yang_print_case(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001658 break;
Radek Krejci5dd25122017-01-11 17:28:13 +01001659 case LYS_RPC:
Michal Vaskoca7cbc42016-07-01 11:36:53 +02001660 case LYS_ACTION:
1661 yang_print_rpc_action(out, level, node);
1662 break;
Radek Krejci76512572015-08-04 09:47:08 +02001663 case LYS_INPUT:
1664 case LYS_OUTPUT:
Radek Krejci2c99a622017-01-12 10:11:13 +01001665 yang_print_input_output(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001666 break;
Michal Vaskob15cae22016-09-15 09:40:56 +02001667 case LYS_NOTIF:
1668 yang_print_notif(out, level, node);
1669 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001670 default:
1671 break;
1672 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001673}
1674
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001675int
Michal Vasko1e62a092015-12-01 12:27:20 +01001676yang_print_model(struct lyout *out, const struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001677{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001678 unsigned int i;
Radek Krejci43e3c312017-01-11 11:34:44 +01001679 int level = 0, p;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001680#define LEVEL (level*2)
1681
Radek Krejci1d82ef62015-08-07 14:44:40 +02001682 struct lys_node *node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001683
Radek Krejci8d81e002015-12-10 11:18:59 +01001684 /* (sub)module-header-stmts */
Michal Vasko116172e2015-07-07 11:54:37 +02001685 if (module->type) {
Michal Vasko89563fc2016-07-28 16:19:35 +02001686 ly_print(out, "submodule %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001687 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001688 if (module->version) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001689 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0,
1690 ((struct lys_submodule *)module)->belongsto->version == 2 ? "1.1" : "1",
1691 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001692 }
Radek Krejci76b07902015-10-09 09:11:25 +02001693 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Radek Krejcicfce0292017-01-13 12:37:57 +01001694 p = -1;
1695 while ((p = ly_print_ext_iter(module->ext, module->ext_size, p + 1, LYEXT_SUBSTMT_BELONGSTO)) != -1) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001696 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_BELONGSTO, 0, &module->ext[p], 1);
1697 }
1698 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1699 module, module->ext, module->ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001700 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001701 } else {
Michal Vasko89563fc2016-07-28 16:19:35 +02001702 ly_print(out, "module %s {%s\n", module->name, (module->deviated == 1 ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001703 level++;
Radek Krejci8d81e002015-12-10 11:18:59 +01001704 if (module->version) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001705 yang_print_substmt(out, level, LYEXT_SUBSTMT_VERSION, 0, module->version == 2 ? "1.1" : "1",
1706 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001707 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001708 yang_print_substmt(out, level, LYEXT_SUBSTMT_NAMESPACE, 0, module->ns,
1709 module, module->ext, module->ext_size);
1710 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->prefix,
1711 module, module->ext, module->ext_size);
Michal Vasko116172e2015-07-07 11:54:37 +02001712 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001713
Radek Krejci8d81e002015-12-10 11:18:59 +01001714 /* linkage-stmts */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001715 for (i = 0; i < module->imp_size; i++) {
Radek Krejcie534c132016-11-23 13:32:31 +01001716 ly_print(out, "\n%*simport %s {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001717 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001718 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1719 module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci39228d22017-01-13 12:43:55 +01001720 yang_print_substmt(out, level, LYEXT_SUBSTMT_PREFIX, 0, module->imp[i].prefix,
1721 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001722 if (module->imp[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001723 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->imp[i].rev,
1724 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001725 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001726 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->imp[i].dsc,
1727 module, module->imp[i].ext, module->imp[i].ext_size);
1728 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->imp[i].ref,
1729 module, module->imp[i].ext, module->imp[i].ext_size);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001730 level--;
Michal Vaskoc8e3ce02016-02-12 14:28:35 +01001731 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001732 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001733 for (i = 0; i < module->inc_size; i++) {
Radek Krejcic071c542016-01-27 14:57:51 +01001734 if (module->inc[i].external) {
1735 continue;
1736 }
Radek Krejcie534c132016-11-23 13:32:31 +01001737 if (module->inc[i].rev[0] || module->inc[i].dsc || module->inc[i].ref || module->inc[i].ext_size) {
1738 ly_print(out, "\n%*sinclude %s {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci8d81e002015-12-10 11:18:59 +01001739 level++;
Radek Krejci5dd25122017-01-11 17:28:13 +01001740 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0,
1741 module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001742 if (module->inc[i].rev[0]) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001743 yang_print_substmt(out, level, LYEXT_SUBSTMT_REVISIONDATE, 0, module->inc[i].rev,
1744 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejcie534c132016-11-23 13:32:31 +01001745 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001746 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->inc[i].dsc,
1747 module, module->inc[i].ext, module->inc[i].ext_size);
1748 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->inc[i].ref,
1749 module, module->inc[i].ext, module->inc[i].ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001750 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001751 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001752 } else {
Radek Krejcie534c132016-11-23 13:32:31 +01001753 ly_print(out, "\n%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001754 }
1755 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001756
Radek Krejci8d81e002015-12-10 11:18:59 +01001757 /* meta-stmts */
1758 if (module->org || module->contact || module->dsc || module->ref) {
1759 ly_print(out, "\n");
1760 }
Radek Krejci43e3c312017-01-11 11:34:44 +01001761 yang_print_substmt(out, level, LYEXT_SUBSTMT_ORGANIZATION, 0, module->org,
1762 module, module->ext, module->ext_size);
1763 yang_print_substmt(out, level, LYEXT_SUBSTMT_CONTACT, 0, module->contact,
1764 module, module->ext, module->ext_size);
1765 yang_print_substmt(out, level, LYEXT_SUBSTMT_DESCRIPTION, 0, module->dsc,
1766 module, module->ext, module->ext_size);
1767 yang_print_substmt(out, level, LYEXT_SUBSTMT_REFERENCE, 0, module->ref,
1768 module, module->ext, module->ext_size);
Radek Krejci8d81e002015-12-10 11:18:59 +01001769
1770 /* revision-stmts */
1771 if (module->rev_size) {
1772 ly_print(out, "\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001773 }
1774 for (i = 0; i < module->rev_size; i++) {
Radek Krejci43e3c312017-01-11 11:34:44 +01001775 if (module->rev[i].dsc || module->rev[i].ref || module->rev[i].ext_size) {
Radek Krejci76b07902015-10-09 09:11:25 +02001776 ly_print(out, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci5dd25122017-01-11 17:28:13 +01001777 yang_print_extension_instances(out, level + 1, module, LYEXT_SUBSTMT_SELF, 0,
1778 module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci43e3c312017-01-11 11:34:44 +01001779 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_DESCRIPTION, 0, module->rev[i].dsc,
1780 module, module->rev[i].ext, module->rev[i].ext_size);
1781 yang_print_substmt(out, level + 1, LYEXT_SUBSTMT_REFERENCE, 0, module->rev[i].ref,
1782 module, module->rev[i].ext, module->rev[i].ext_size);
Radek Krejci76b07902015-10-09 09:11:25 +02001783 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001784 } else {
Michal Vasko86dfd262016-02-15 14:26:31 +01001785 ly_print(out, "%*srevision %s;\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001786 }
1787 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001788
Radek Krejci8d81e002015-12-10 11:18:59 +01001789 /* body-stmts */
Radek Krejcie534c132016-11-23 13:32:31 +01001790 for (i = 0; i < module->extensions_size; i++) {
1791 ly_print(out, "\n");
1792 yang_print_extension(out, level, &module->extensions[i]);
1793 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001794 if (module->ext_size) {
1795 ly_print(out, "\n");
1796 yang_print_extension_instances(out, level, module, LYEXT_SUBSTMT_SELF, 0, module->ext, module->ext_size);
1797 }
Radek Krejcie534c132016-11-23 13:32:31 +01001798
Michal Vasko30f6e912015-07-07 12:24:27 +02001799 for (i = 0; i < module->features_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001800 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001801 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001802 }
1803
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001804 for (i = 0; i < module->ident_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001805 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001806 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001807 }
Radek Krejci6793db02015-05-22 17:49:54 +02001808
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001809 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001810 ly_print(out, "\n");
Radek Krejci76b07902015-10-09 09:11:25 +02001811 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001812 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001813
Radek Krejci5dd25122017-01-11 17:28:13 +01001814 LY_TREE_FOR(lys_main_module(module)->data, node) {
1815 if (node->module != module) {
1816 /* data from submodules */
1817 continue;
1818 }
1819 yang_print_snode(out, level, node, LYS_GROUPING);
Radek Krejci8d81e002015-12-10 11:18:59 +01001820 }
1821
Radek Krejcic4283442016-04-22 09:19:27 +02001822 LY_TREE_FOR(lys_main_module(module)->data, node) {
Radek Krejcic071c542016-01-27 14:57:51 +01001823 if (node->module != module) {
Michal Vasko0c5e9282016-02-15 13:11:57 +01001824 /* data from submodules */
Radek Krejcic071c542016-01-27 14:57:51 +01001825 continue;
1826 }
Radek Krejci5dd25122017-01-11 17:28:13 +01001827 yang_print_snode(out, level, node, LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1828 LYS_USES | LYS_ANYDATA);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001829 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001830
Michal Vasko6f25f212015-07-07 15:42:07 +02001831 for (i = 0; i < module->augment_size; i++) {
Radek Krejci8d81e002015-12-10 11:18:59 +01001832 ly_print(out, "\n");
Radek Krejci43e3c312017-01-11 11:34:44 +01001833 yang_print_augment(out, level, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001834 }
1835
Radek Krejci5dd25122017-01-11 17:28:13 +01001836 LY_TREE_FOR(lys_main_module(module)->data, node) {
1837 if (node->module != module) {
1838 /* data from submodules */
1839 continue;
1840 }
1841 yang_print_snode(out, level, node, LYS_RPC | LYS_ACTION);
1842 }
1843
1844 LY_TREE_FOR(lys_main_module(module)->data, node) {
1845 if (node->module != module) {
1846 /* data from submodules */
1847 continue;
1848 }
1849 yang_print_snode(out, level, node, LYS_NOTIF);
1850 }
1851
1852 for (i = 0; i < module->deviation_size; ++i) {
1853 ly_print(out, "\n");
1854 yang_print_deviation(out, level, module, &module->deviation[i]);
1855 }
1856
Radek Krejci76b07902015-10-09 09:11:25 +02001857 ly_print(out, "}\n");
Michal Vasko95068c42016-03-24 14:58:11 +01001858 ly_print_flush(out);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001859
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001860 return EXIT_SUCCESS;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001861#undef LEVEL
1862}