blob: eb4a40d8806c69429120a0c33fda58db08c86810 [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 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of the Company nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 */
21
22#include <stdlib.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020023#include <string.h>
24
Radek Krejci998a0b82015-08-17 13:14:36 +020025#include "common.h"
Radek Krejci76b07902015-10-09 09:11:25 +020026#include "printer.h"
Michal Vasko2d162e12015-09-24 14:33:29 +020027#include "tree_schema.h"
Radek Krejcida04f4a2015-05-21 12:54:09 +020028
29#define INDENT ""
30#define LEVEL (level*2)
31
Radek Krejci76b07902015-10-09 09:11:25 +020032static void yang_print_snode(struct lyout *out, int level, struct lys_node *node, int mask);
Radek Krejcida04f4a2015-05-21 12:54:09 +020033
Michal Vaskoc39c4b12015-07-07 14:55:33 +020034static const char*
Radek Krejcib8048692015-08-05 13:36:34 +020035get_module_import_prefix(struct lys_module *main_mod, struct lys_module *imp_mod)
Michal Vaskoc39c4b12015-07-07 14:55:33 +020036{
37 int i, j;
38
39 for (i = 0; i < main_mod->imp_size; ++i) {
40 if (main_mod->imp[i].module == imp_mod) {
41 return main_mod->imp[i].prefix;
42 }
43 }
44
45 for (j = 0; j < main_mod->inc_size; ++j) {
46 for (i = 0; i < main_mod->inc[j].submodule->imp_size; ++i) {
47 if (main_mod->inc[j].submodule->imp[i].module == imp_mod) {
48 return main_mod->inc[j].submodule->imp[i].prefix;
49 }
50 }
51 }
52
53 return NULL;
54}
55
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020056static void
Radek Krejci76b07902015-10-09 09:11:25 +020057yang_print_text(struct lyout *out, int level, const char *name, const char *text)
Radek Krejcida04f4a2015-05-21 12:54:09 +020058{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020059 const char *s, *t;
Radek Krejcida04f4a2015-05-21 12:54:09 +020060
Radek Krejci76b07902015-10-09 09:11:25 +020061 ly_print(out, "%*s%s\n", LEVEL, INDENT, name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020062 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +020063
Radek Krejci76b07902015-10-09 09:11:25 +020064 ly_print(out, "%*s\"", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020065 t = text;
66 while ((s = strchr(t, '\n'))) {
Radek Krejci76b07902015-10-09 09:11:25 +020067 ly_write(out, t, (s - t) + 1);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020068 t = s + 1;
Radek Krejci76b07902015-10-09 09:11:25 +020069 ly_print(out, "%*s", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020070 }
Radek Krejcida04f4a2015-05-21 12:54:09 +020071
Radek Krejci76b07902015-10-09 09:11:25 +020072 ly_print(out, "%s\";\n\n", t);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020073 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +020074
75}
76
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020077static void
Radek Krejci76b07902015-10-09 09:11:25 +020078yang_print_nacmext(struct lyout *out, int level, struct lys_node *node, struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +020079{
Radek Krejci6764bb32015-07-03 15:16:04 +020080 int i, j;
Radek Krejci86909d22015-07-03 16:11:25 +020081 const char *prefix = NULL;
Radek Krejci6764bb32015-07-03 15:16:04 +020082
Radek Krejci1d82ef62015-08-07 14:44:40 +020083 if (node->nacm && (!node->parent || node->parent->nacm != node->nacm)) {
Radek Krejci6764bb32015-07-03 15:16:04 +020084 /* locate ietf-netconf-acm module in imports */
Michal Vaskodb7aa992015-07-08 09:37:38 +020085 if (!strcmp(module->name, "ietf-netconf-acm")) {
86 prefix = module->prefix;
Radek Krejci6764bb32015-07-03 15:16:04 +020087 } else {
88 /* search in imports */
Michal Vaskodb7aa992015-07-08 09:37:38 +020089 for (i = 0; i < module->imp_size; i++) {
90 if (!strcmp(module->imp[i].module->name, "ietf-netconf-acm")) {
91 prefix = module->imp[i].prefix;
Radek Krejci6764bb32015-07-03 15:16:04 +020092 break;
93 }
94 }
95 /* and in imports of includes */
96 if (!prefix) {
Michal Vaskodb7aa992015-07-08 09:37:38 +020097 for (j = 0; j < module->inc_size; j++) {
98 for (i = 0; i < module->inc[j].submodule->imp_size; i++) {
99 if (!strcmp(module->inc[j].submodule->imp[i].module->name, "ietf-netconf-acm")) {
100 prefix = module->inc[j].submodule->imp[i].prefix;
Radek Krejci6764bb32015-07-03 15:16:04 +0200101 break;
102 }
103 }
104 }
105 }
106 }
107
Radek Krejci1d82ef62015-08-07 14:44:40 +0200108 if ((node->nacm & LYS_NACM_DENYW) && (!node->parent || !(node->parent->nacm & LYS_NACM_DENYW))) {
Radek Krejci76b07902015-10-09 09:11:25 +0200109 ly_print(out, "%*s%s:default-deny-write;\n", LEVEL, INDENT, prefix);
Radek Krejci6764bb32015-07-03 15:16:04 +0200110 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200111 if ((node->nacm & LYS_NACM_DENYA) && (!node->parent || !(node->parent->nacm & LYS_NACM_DENYA))) {
Radek Krejci76b07902015-10-09 09:11:25 +0200112 ly_print(out, "%*s%s:default-deny-all;\n", LEVEL, INDENT, prefix);
Radek Krejci6764bb32015-07-03 15:16:04 +0200113 }
114 }
Radek Krejci6a113852015-07-03 16:04:20 +0200115}
116
117/*
118 * Covers:
119 * description, reference, status
120 */
121static void
Radek Krejci76b07902015-10-09 09:11:25 +0200122yang_print_snode_common(struct lyout *out, int level, struct lys_node *node)
Radek Krejci6a113852015-07-03 16:04:20 +0200123{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200124 if (node->flags & LYS_STATUS_CURR) {
Radek Krejci76b07902015-10-09 09:11:25 +0200125 ly_print(out, "%*sstatus \"current\";\n", LEVEL, INDENT);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200126 } else if (node->flags & LYS_STATUS_DEPRC) {
Radek Krejci76b07902015-10-09 09:11:25 +0200127 ly_print(out, "%*sstatus \"deprecated\";\n", LEVEL, INDENT);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200128 } else if (node->flags & LYS_STATUS_OBSLT) {
Radek Krejci76b07902015-10-09 09:11:25 +0200129 ly_print(out, "%*sstatus \"obsolete\";\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200130 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200131
Radek Krejci1d82ef62015-08-07 14:44:40 +0200132 if (node->dsc) {
Radek Krejci76b07902015-10-09 09:11:25 +0200133 yang_print_text(out, level, "description", node->dsc);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200134 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200135 if (node->ref) {
Radek Krejci76b07902015-10-09 09:11:25 +0200136 yang_print_text(out, level, "reference", node->ref);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200137 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200138}
139
140/*
141 * Covers:
Michal Vasko2b8faed2015-06-09 12:51:20 +0200142 * config, mandatory
Radek Krejcida04f4a2015-05-21 12:54:09 +0200143 * description, reference, status
144 */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200145static void
Radek Krejci76b07902015-10-09 09:11:25 +0200146yang_print_snode_common2(struct lyout *out, int level, struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200147{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200148 if (!node->parent || (node->parent->flags & LYS_CONFIG_MASK) != (node->flags & LYS_CONFIG_MASK)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200149 /* print config only when it differs from the parent or in root */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200150 if (node->flags & LYS_CONFIG_W) {
Radek Krejci76b07902015-10-09 09:11:25 +0200151 ly_print(out, "%*sconfig \"true\";\n", LEVEL, INDENT);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200152 } else if (node->flags & LYS_CONFIG_R) {
Radek Krejci76b07902015-10-09 09:11:25 +0200153 ly_print(out, "%*sconfig \"false\";\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200154 }
155 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200156
Radek Krejci1d82ef62015-08-07 14:44:40 +0200157 if (node->flags & LYS_MAND_TRUE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200158 ly_print(out, "%*smandatory \"true\";\n", LEVEL, INDENT);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200159 } else if (node->flags & LYS_MAND_FALSE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200160 ly_print(out, "%*smandatory \"false\";\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200161 }
Michal Vasko2b8faed2015-06-09 12:51:20 +0200162
Radek Krejci76b07902015-10-09 09:11:25 +0200163 yang_print_snode_common(out, level, node);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200164}
165
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200166static void
Radek Krejci76b07902015-10-09 09:11:25 +0200167yang_print_iffeature(struct lyout *out, int level, struct lys_module *module, struct lys_feature *feat)
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200168{
Radek Krejci76b07902015-10-09 09:11:25 +0200169 ly_print(out, "%*sif-feature ", LEVEL, INDENT);
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200170 if ((feat->module != module) && !feat->module->type) {
Radek Krejci76b07902015-10-09 09:11:25 +0200171 ly_print(out, "%s:", get_module_import_prefix(module, feat->module));
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200172 }
Radek Krejci76b07902015-10-09 09:11:25 +0200173 ly_print(out, "%s;\n", feat->name);
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200174}
175
176static void
Radek Krejci76b07902015-10-09 09:11:25 +0200177yang_print_feature(struct lyout *out, int level, struct lys_feature *feat)
Michal Vasko4773b762015-07-07 12:15:10 +0200178{
Michal Vasko30f6e912015-07-07 12:24:27 +0200179 int i;
180
Radek Krejci76b07902015-10-09 09:11:25 +0200181 ly_print(out, "%*sfeature %s {\n", LEVEL, INDENT, feat->name);
Michal Vasko4773b762015-07-07 12:15:10 +0200182 level++;
183
Radek Krejci76b07902015-10-09 09:11:25 +0200184 yang_print_snode_common(out, level, (struct lys_node *)feat);
Michal Vasko30f6e912015-07-07 12:24:27 +0200185 for (i = 0; i < feat->features_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200186 yang_print_iffeature(out, level, feat->module, feat->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +0200187 }
Michal Vasko4773b762015-07-07 12:15:10 +0200188
189 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200190 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko4773b762015-07-07 12:15:10 +0200191}
192
193static void
Radek Krejci76b07902015-10-09 09:11:25 +0200194yang_print_restr(struct lyout *out, int level, struct lys_restr *restr)
Radek Krejci41726f92015-06-19 13:11:05 +0200195{
Radek Krejci0bd5db42015-06-19 13:30:07 +0200196 if (restr->dsc != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200197 yang_print_text(out, level, "description", restr->dsc);
Radek Krejci41726f92015-06-19 13:11:05 +0200198 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200199 if (restr->ref != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200200 yang_print_text(out, level, "reference", restr->ref);
Radek Krejci41726f92015-06-19 13:11:05 +0200201 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200202 if (restr->eapptag != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200203 ly_print(out, "%*serror-app-tag \"%s\";\n", LEVEL, INDENT, restr->eapptag);
Radek Krejci41726f92015-06-19 13:11:05 +0200204 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200205 if (restr->emsg != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200206 yang_print_text(out, level, "error-message", restr->emsg);
Radek Krejci41726f92015-06-19 13:11:05 +0200207 }
208}
209
210static void
Michal Vaskof9893382015-10-09 14:03:04 +0200211yang_print_when(struct lyout *out, int level, struct lys_module *module, struct lys_when *when)
Michal Vasko1f0428a2015-07-07 14:55:04 +0200212{
Michal Vaskof9893382015-10-09 14:03:04 +0200213 const char *xml_expr;
214
215 xml_expr = transform_expr_json2xml(module, when->cond, NULL, NULL, NULL);
216 if (!xml_expr) {
217 ly_print(out, "(!error!)");
218 return;
219 }
220
221 ly_print(out, "%*swhen \"%s\" {\n", LEVEL, INDENT, xml_expr);
222 lydict_remove(module->ctx, xml_expr);
223
Michal Vasko1f0428a2015-07-07 14:55:04 +0200224 level++;
225 if (when->dsc) {
Radek Krejci76b07902015-10-09 09:11:25 +0200226 yang_print_text(out, level, "description", when->dsc);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200227 }
228 if (when->ref) {
Radek Krejci76b07902015-10-09 09:11:25 +0200229 yang_print_text(out, level, "reference", when->ref);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200230 }
231 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200232 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200233}
234
235static void
Radek Krejci76b07902015-10-09 09:11:25 +0200236yang_print_type(struct lyout *out, int level, struct lys_module *module, struct lys_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200237{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200238 int i;
Michal Vasko0fb82c62015-10-20 13:41:53 +0200239 const char *str;
Radek Krejci25d782a2015-05-22 15:03:23 +0200240
Michal Vasko0fb82c62015-10-20 13:41:53 +0200241 if (type->module_name) {
242 str = transform_expr_json2xml(module, type->module_name, NULL, NULL, NULL);
243 ly_print(out, "%*stype %s:%s {\n", LEVEL, INDENT, str, type->der->name);
244 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200245 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200246 ly_print(out, "%*stype %s {\n", LEVEL, INDENT, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200247 }
248 level++;
249 switch (type->base) {
250 case LY_TYPE_BINARY:
251 if (type->info.binary.length != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200252 ly_print(out, "%*slength \"%s\" {\n", LEVEL, INDENT, type->info.binary.length->expr);
253 yang_print_restr(out, level + 1, type->info.binary.length);
254 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200255 }
256 break;
257 case LY_TYPE_BITS:
258 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200259 ly_print(out, "%*sbit %s {\n", LEVEL, INDENT, type->info.bits.bit[i].name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200260 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200261 yang_print_snode_common(out, level, (struct lys_node *)&type->info.bits.bit[i]);
262 ly_print(out, "%*sposition %u;\n", LEVEL, INDENT, type->info.bits.bit[i].pos);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200263 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200264 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200265 }
266 break;
267 case LY_TYPE_DEC64:
Radek Krejci76b07902015-10-09 09:11:25 +0200268 ly_print(out, "%*sfraction-digits %d;\n", LEVEL, INDENT, type->info.dec64.dig);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200269 if (type->info.dec64.range != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200270 ly_print(out, "%*srange \"%s\" {\n", LEVEL, INDENT, type->info.dec64.range->expr);
271 yang_print_restr(out, level + 1, type->info.dec64.range);
272 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200273 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200274 break;
275 case LY_TYPE_ENUM:
276 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200277 ly_print(out, "%*senum %s {\n", LEVEL, INDENT, type->info.enums.enm[i].name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200278 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200279 yang_print_snode_common(out, level, (struct lys_node *)&type->info.enums.enm[i]);
280 ly_print(out, "%*svalue %d;\n", LEVEL, INDENT, type->info.enums.enm[i].value);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200281 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200282 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200283 }
284 break;
285 case LY_TYPE_IDENT:
286 if (module == type->info.ident.ref->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200287 ly_print(out, "%*sbase %s;\n", LEVEL, INDENT, type->info.ident.ref->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200288 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200289 ly_print(out, "%*sbase %s:%s;\n", LEVEL, INDENT, type->info.ident.ref->module->prefix,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200290 type->info.ident.ref->name);
291 }
292 break;
293 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200294 if (type->info.inst.req == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200295 ly_print(out, "%*srequire-instance \"true\";\n", LEVEL, INDENT);
Radek Krejciaf351422015-06-19 14:49:38 +0200296 } else if (type->info.inst.req == -1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200297 ly_print(out, "%*srequire-instance \"false\";\n", LEVEL, INDENT);
Radek Krejciaf351422015-06-19 14:49:38 +0200298 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200299 break;
300 case LY_TYPE_INT8:
301 case LY_TYPE_INT16:
302 case LY_TYPE_INT32:
303 case LY_TYPE_INT64:
304 case LY_TYPE_UINT8:
305 case LY_TYPE_UINT16:
306 case LY_TYPE_UINT32:
307 case LY_TYPE_UINT64:
Radek Krejcif2860132015-06-20 12:37:20 +0200308 if (type->info.num.range != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200309 ly_print(out, "%*srange \"%s\" {\n", LEVEL, INDENT, type->info.num.range->expr);
310 yang_print_restr(out, level + 1, type->info.num.range);
311 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcif2860132015-06-20 12:37:20 +0200312 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200313 break;
314 case LY_TYPE_LEAFREF:
Michal Vasko514c4f32015-10-20 13:43:25 +0200315 str = transform_expr_json2xml(module, type->info.lref.path, NULL, NULL, NULL);
316 ly_print(out, "%*spath \"%s\";\n", LEVEL, INDENT, str);
317 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200318 break;
319 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200320 if (type->info.str.length) {
Radek Krejci76b07902015-10-09 09:11:25 +0200321 ly_print(out, "%*slength \"%s\" {\n", LEVEL, INDENT, type->info.str.length->expr);
322 yang_print_restr(out, level + 1, type->info.str.length);
323 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci061bd522015-06-19 13:45:16 +0200324 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200325 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200326 ly_print(out, "%*spattern \"%s\" {\n", LEVEL, INDENT, type->info.str.patterns[i].expr);
327 yang_print_restr(out, level + 1, &type->info.str.patterns[i]);
328 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200329 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200330 break;
331 case LY_TYPE_UNION:
332 for (i = 0; i < type->info.uni.count; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200333 yang_print_type(out, level, module, &type->info.uni.types[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200334 }
335 break;
336 default:
337 /* other types do not have substatements */
338 break;
339 }
340 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200341 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200342}
343
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200344static void
Michal Vaskof9893382015-10-09 14:03:04 +0200345yang_print_must(struct lyout *out, int level, struct lys_module *module, struct lys_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200346{
Michal Vaskof9893382015-10-09 14:03:04 +0200347 const char *xml_expr;
348
349 xml_expr = transform_expr_json2xml(module, must->expr, NULL, NULL, NULL);
350 if (!xml_expr) {
351 ly_print(out, "(!error!)");
352 return;
353 }
354
355 ly_print(out, "%*smust \"%s\" {\n", LEVEL, INDENT, xml_expr);
356 lydict_remove(module->ctx, xml_expr);
357
Radek Krejci76b07902015-10-09 09:11:25 +0200358 yang_print_restr(out, level + 1, must);
359 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200360}
361
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200362static void
Radek Krejci76b07902015-10-09 09:11:25 +0200363yang_print_unique(struct lyout *out, int level, struct lys_unique *uniq)
Michal Vasko1ef07972015-07-07 14:01:35 +0200364{
365 int i;
366
Radek Krejci76b07902015-10-09 09:11:25 +0200367 ly_print(out, "%*sunique \"", LEVEL, INDENT);
Michal Vasko1ef07972015-07-07 14:01:35 +0200368 for (i = 0; i < uniq->leafs_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200369 ly_print(out, "%s%s", uniq->leafs[i]->name, i + 1 < uniq->leafs_size ? " " : "");
Michal Vasko1ef07972015-07-07 14:01:35 +0200370 }
Radek Krejci76b07902015-10-09 09:11:25 +0200371 ly_print(out, "\";\n");
Michal Vasko1ef07972015-07-07 14:01:35 +0200372}
373
374static void
Michal Vaskof9893382015-10-09 14:03:04 +0200375yang_print_refine(struct lyout *out, int level, struct lys_module *module, struct lys_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200376{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200377 int i;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200378 const char *str;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200379
Michal Vaskoa8b25952015-10-20 15:30:25 +0200380 str = transform_expr_json2xml(module, refine->target_name, NULL, NULL, NULL);
381 ly_print(out, "%*srefine \"%s\" {\n", LEVEL, INDENT, str);
382 lydict_remove(module->ctx, str);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200383 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200384
Radek Krejci1574a8d2015-08-03 14:16:52 +0200385 if (refine->flags & LYS_CONFIG_W) {
Radek Krejci76b07902015-10-09 09:11:25 +0200386 ly_print(out, "%*sconfig \"true\";\n", LEVEL, INDENT);
Radek Krejci1574a8d2015-08-03 14:16:52 +0200387 } else if (refine->flags & LYS_CONFIG_R) {
Radek Krejci76b07902015-10-09 09:11:25 +0200388 ly_print(out, "%*sconfig \"false\";\n", LEVEL, INDENT);
Radek Krejci6a113852015-07-03 16:04:20 +0200389 }
390
Radek Krejci1574a8d2015-08-03 14:16:52 +0200391 if (refine->flags & LYS_MAND_TRUE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200392 ly_print(out, "%*smandatory \"true\";\n", LEVEL, INDENT);
Radek Krejci1574a8d2015-08-03 14:16:52 +0200393 } else if (refine->flags & LYS_MAND_FALSE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200394 ly_print(out, "%*smandatory \"false\";\n", LEVEL, INDENT);
Radek Krejci6a113852015-07-03 16:04:20 +0200395 }
396
Radek Krejci76b07902015-10-09 09:11:25 +0200397 yang_print_snode_common(out, level, (struct lys_node *)refine);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200398
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200399 for (i = 0; i < refine->must_size; ++i) {
Michal Vaskof9893382015-10-09 14:03:04 +0200400 yang_print_must(out, level, module, &refine->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200401 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200402
Radek Krejci76512572015-08-04 09:47:08 +0200403 if (refine->target_type & (LYS_LEAF | LYS_CHOICE)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200404 if (refine->mod.dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200405 ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, refine->mod.dflt);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200406 }
Radek Krejci76512572015-08-04 09:47:08 +0200407 } else if (refine->target_type == LYS_CONTAINER) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200408 if (refine->mod.presence != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200409 yang_print_text(out, level, "presence", refine->mod.presence);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200410 }
Radek Krejci76512572015-08-04 09:47:08 +0200411 } else if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200412 if (refine->mod.list.min > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200413 ly_print(out, "%*smin-elements %u;\n", LEVEL, INDENT, refine->mod.list.min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200414 }
415 if (refine->mod.list.max > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200416 ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, refine->mod.list.max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200417 }
418 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200419
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200420 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200421 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200422}
423
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200424static void
Radek Krejci76b07902015-10-09 09:11:25 +0200425yang_print_deviation(struct lyout *out, int level, struct lys_module *module, struct lys_deviation *deviation)
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200426{
427 int i, j;
Michal Vaskoa8b25952015-10-20 15:30:25 +0200428 const char *str;
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200429
Michal Vaskoa8b25952015-10-20 15:30:25 +0200430 str = transform_expr_json2xml(module, deviation->target_name, NULL, NULL, NULL);
431 ly_print(out, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, str);
432 lydict_remove(module->ctx, str);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200433 level++;
434
435 if (deviation->dsc) {
Radek Krejci76b07902015-10-09 09:11:25 +0200436 yang_print_text(out, level, "description", deviation->dsc);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200437 }
438 if (deviation->ref) {
Radek Krejci76b07902015-10-09 09:11:25 +0200439 yang_print_text(out, level, "reference", deviation->ref);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200440 }
441
442 for (i = 0; i < deviation->deviate_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +0200443 ly_print(out, "%*sdeviate ", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200444 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
Radek Krejci76b07902015-10-09 09:11:25 +0200445 ly_print(out, "not-supported {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200446 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
Radek Krejci76b07902015-10-09 09:11:25 +0200447 ly_print(out, "add {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200448 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200449 ly_print(out, "replace {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200450 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200451 ly_print(out, "delete {\n");
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200452 }
453 level++;
454
Radek Krejci1574a8d2015-08-03 14:16:52 +0200455 if (deviation->deviate[i].flags & LYS_CONFIG_W) {
Radek Krejci76b07902015-10-09 09:11:25 +0200456 ly_print(out, "%*sconfig \"true\";\n", LEVEL, INDENT);
Radek Krejci1574a8d2015-08-03 14:16:52 +0200457 } else if (deviation->deviate[i].flags & LYS_CONFIG_R) {
Radek Krejci76b07902015-10-09 09:11:25 +0200458 ly_print(out, "%*sconfig \"false\";\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200459 }
460
Radek Krejci1574a8d2015-08-03 14:16:52 +0200461 if (deviation->deviate[i].flags & LYS_MAND_TRUE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200462 ly_print(out, "%*smandatory \"true\";\n", LEVEL, INDENT);
Radek Krejci1574a8d2015-08-03 14:16:52 +0200463 } else if (deviation->deviate[i].flags & LYS_MAND_FALSE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200464 ly_print(out, "%*smandatory \"false\";\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200465 }
466
467 if (deviation->deviate[i].dflt) {
Radek Krejci76b07902015-10-09 09:11:25 +0200468 ly_print(out, "%*sdefault %s;\n", LEVEL, INDENT, deviation->deviate[i].dflt);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200469 }
470
471 if (deviation->deviate[i].min) {
Radek Krejci76b07902015-10-09 09:11:25 +0200472 ly_print(out, "%*smin-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].min);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200473 }
474 if (deviation->deviate[i].max) {
Radek Krejci76b07902015-10-09 09:11:25 +0200475 ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].max);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200476 }
477
478 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
Michal Vaskof9893382015-10-09 14:03:04 +0200479 yang_print_must(out, level, module, &deviation->deviate[i].must[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200480 }
481
482 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
Radek Krejci76b07902015-10-09 09:11:25 +0200483 yang_print_unique(out, level, &deviation->deviate[i].unique[j]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200484 }
485
486 if (deviation->deviate[i].type) {
Radek Krejci76b07902015-10-09 09:11:25 +0200487 yang_print_type(out, level, module, deviation->deviate[i].type);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200488 }
489
490 if (deviation->deviate[i].units) {
Radek Krejci76b07902015-10-09 09:11:25 +0200491 ly_print(out, "%*sunits %s;\n", LEVEL, INDENT, deviation->deviate[i].units);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200492 }
493
494 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200495 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200496 }
497
498 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200499 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200500}
501
502static void
Radek Krejci76b07902015-10-09 09:11:25 +0200503yang_print_augment(struct lyout *out, int level, struct lys_module *module, struct lys_node_augment *augment)
Michal Vasko6f25f212015-07-07 15:42:07 +0200504{
505 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200506 struct lys_node *sub;
Michal Vasko488c19e2015-10-20 15:21:00 +0200507 const char *str;
Michal Vasko6f25f212015-07-07 15:42:07 +0200508
Michal Vasko488c19e2015-10-20 15:21:00 +0200509 str = transform_expr_json2xml(module, augment->target_name, NULL, NULL, NULL);
510 ly_print(out, "%*saugment \"%s\" {\n", LEVEL, INDENT, str);
511 lydict_remove(module->ctx, str);
Michal Vasko6f25f212015-07-07 15:42:07 +0200512 level++;
513
Radek Krejci76b07902015-10-09 09:11:25 +0200514 yang_print_nacmext(out, level, (struct lys_node *)augment, module);
515 yang_print_snode_common(out, level, (struct lys_node *)augment);
Michal Vasko6f25f212015-07-07 15:42:07 +0200516
517 for (i = 0; i < augment->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200518 yang_print_iffeature(out, level, module, augment->features[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +0200519 }
520
521 if (augment->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200522 yang_print_when(out, level, module, augment->when);
Michal Vasko6f25f212015-07-07 15:42:07 +0200523 }
524
525 LY_TREE_FOR(augment->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200526 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200527 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
528 LYS_USES | LYS_ANYXML | LYS_CASE);
Michal Vasko6f25f212015-07-07 15:42:07 +0200529 }
530
531 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200532 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko6f25f212015-07-07 15:42:07 +0200533}
534
535static void
Radek Krejci76b07902015-10-09 09:11:25 +0200536yang_print_typedef(struct lyout *out, int level, struct lys_module *module, struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200537{
Radek Krejci76b07902015-10-09 09:11:25 +0200538 ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200539 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200540
Radek Krejci76b07902015-10-09 09:11:25 +0200541 yang_print_snode_common(out, level, (struct lys_node *)tpdf);
542 yang_print_type(out, level, module, &tpdf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200543 if (tpdf->units != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200544 ly_print(out, "%*sunits \"%s\";\n", LEVEL, INDENT, tpdf->units);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200545 }
546 if (tpdf->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200547 ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, tpdf->dflt);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200548 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200549
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200550 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200551 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200552}
553
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200554static void
Radek Krejci76b07902015-10-09 09:11:25 +0200555yang_print_identity(struct lyout *out, int level, struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200556{
Radek Krejci76b07902015-10-09 09:11:25 +0200557 ly_print(out, "%*sidentity %s {\n", LEVEL, INDENT, ident->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200558 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200559
Radek Krejci76b07902015-10-09 09:11:25 +0200560 yang_print_snode_common(out, level, (struct lys_node *)ident);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200561 if (ident->base) {
Radek Krejci76b07902015-10-09 09:11:25 +0200562 ly_print(out, "%*sbase ", LEVEL, INDENT);
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200563 if ((ident->module != ident->base->module) && !ident->base->module->type) {
Radek Krejci76b07902015-10-09 09:11:25 +0200564 ly_print(out, "%s:", get_module_import_prefix(ident->module, ident->base->module));
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200565 }
Radek Krejci76b07902015-10-09 09:11:25 +0200566 ly_print(out, "%s;\n", ident->base->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200567 }
Radek Krejci6793db02015-05-22 17:49:54 +0200568
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200569 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200570 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6793db02015-05-22 17:49:54 +0200571
572}
573
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200574static void
Radek Krejci76b07902015-10-09 09:11:25 +0200575yang_print_container(struct lyout *out, int level, struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200576{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200577 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200578 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200579 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200580
Radek Krejci76b07902015-10-09 09:11:25 +0200581 ly_print(out, "%*scontainer %s {\n", LEVEL, INDENT, node->name);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200582
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200583 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200584
Radek Krejci76b07902015-10-09 09:11:25 +0200585 yang_print_nacmext(out, level, node, node->module);
Radek Krejci6a113852015-07-03 16:04:20 +0200586
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200587 if (cont->presence != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200588 yang_print_text(out, level, "presence", cont->presence);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200589 }
Michal Vasko7f976ee2015-06-09 13:55:41 +0200590
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200591 for (i = 0; i < cont->must_size; i++) {
Michal Vaskof9893382015-10-09 14:03:04 +0200592 yang_print_must(out, level, node->module, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200593 }
Michal Vasko7f976ee2015-06-09 13:55:41 +0200594
Radek Krejci76b07902015-10-09 09:11:25 +0200595 yang_print_snode_common2(out, level, node);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200596
Michal Vasko4773b762015-07-07 12:15:10 +0200597 for (i = 0; i < cont->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200598 yang_print_iffeature(out, level, node->module, cont->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200599 }
600
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200601 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200602 yang_print_typedef(out, level, node->module, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200603 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200604
Michal Vasko1f0428a2015-07-07 14:55:04 +0200605 if (cont->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200606 yang_print_when(out, level, node->module, cont->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200607 }
608
Radek Krejci1d82ef62015-08-07 14:44:40 +0200609 LY_TREE_FOR(node->child, sub) {
Michal Vasko15b48702015-07-07 15:49:34 +0200610 /* augment */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200611 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200612 continue;
613 }
Radek Krejci76b07902015-10-09 09:11:25 +0200614 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200615 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
616 LYS_USES | LYS_GROUPING | LYS_ANYXML);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200617 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200618
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200619 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200620 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200621}
622
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200623static void
Radek Krejci76b07902015-10-09 09:11:25 +0200624yang_print_case(struct lyout *out, int level, struct lys_node *node)
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200625{
Michal Vasko4773b762015-07-07 12:15:10 +0200626 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200627 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200628 struct lys_node_case *cas = (struct lys_node_case *)node;
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200629
Radek Krejci76b07902015-10-09 09:11:25 +0200630 ly_print(out, "%*scase %s {\n", LEVEL, INDENT, cas->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200631 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200632 yang_print_nacmext(out, level, node, node->module);
633 yang_print_snode_common2(out, level, node);
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200634
Michal Vasko4773b762015-07-07 12:15:10 +0200635 for (i = 0; i < cas->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200636 yang_print_iffeature(out, level, node->module, cas->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200637 }
638
Michal Vasko1f0428a2015-07-07 14:55:04 +0200639 if (cas->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200640 yang_print_when(out, level, node->module, cas->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200641 }
642
Radek Krejci1d82ef62015-08-07 14:44:40 +0200643 LY_TREE_FOR(node->child, sub) {
Michal Vasko15b48702015-07-07 15:49:34 +0200644 /* augment */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200645 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200646 continue;
647 }
Radek Krejci76b07902015-10-09 09:11:25 +0200648 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200649 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
650 LYS_USES | LYS_ANYXML);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200651 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200652
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200653 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200654 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200655}
656
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200657static void
Radek Krejci76b07902015-10-09 09:11:25 +0200658yang_print_choice(struct lyout *out, int level, struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200659{
Michal Vasko4773b762015-07-07 12:15:10 +0200660 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200661 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200662 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200663
Radek Krejci76b07902015-10-09 09:11:25 +0200664 ly_print(out, "%*schoice %s {\n", LEVEL, INDENT, node->name);
Michal Vasko16083662015-06-09 14:00:45 +0200665
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200666 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200667 yang_print_nacmext(out, level, node, node->module);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200668 if (choice->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200669 ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, choice->dflt->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200670 }
Michal Vasko16083662015-06-09 14:00:45 +0200671
Radek Krejci76b07902015-10-09 09:11:25 +0200672 yang_print_snode_common2(out, level, node);
Michal Vasko4773b762015-07-07 12:15:10 +0200673
674 for (i = 0; i < choice->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200675 yang_print_iffeature(out, level, node->module, choice->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200676 }
677
Michal Vasko1f0428a2015-07-07 14:55:04 +0200678 if (choice->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200679 yang_print_when(out, level, node->module, choice->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200680 }
681
Radek Krejci1d82ef62015-08-07 14:44:40 +0200682 LY_TREE_FOR(node->child, sub) {
Michal Vasko15b48702015-07-07 15:49:34 +0200683 /* augment */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200684 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200685 continue;
686 }
Radek Krejci76b07902015-10-09 09:11:25 +0200687 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200688 LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_CASE);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200689 }
690 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200691 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200692}
693
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200694static void
Radek Krejci76b07902015-10-09 09:11:25 +0200695yang_print_leaf(struct lyout *out, int level, struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200696{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200697 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200698 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200699
Radek Krejci76b07902015-10-09 09:11:25 +0200700 ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
Michal Vasko16083662015-06-09 14:00:45 +0200701
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200702 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200703 yang_print_nacmext(out, level, node, node->module);
704 yang_print_snode_common2(out, level, node);
Michal Vasko4773b762015-07-07 12:15:10 +0200705 for (i = 0; i < leaf->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200706 yang_print_iffeature(out, level, node->module, leaf->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200707 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200708 for (i = 0; i < leaf->must_size; i++) {
Michal Vaskof9893382015-10-09 14:03:04 +0200709 yang_print_must(out, level, node->module, &leaf->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200710 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200711 if (leaf->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200712 yang_print_when(out, level, node->module, leaf->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200713 }
Radek Krejci76b07902015-10-09 09:11:25 +0200714 yang_print_type(out, level, node->module, &leaf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200715 if (leaf->units != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200716 ly_print(out, "%*sunits \"%s\";\n", LEVEL, INDENT, leaf->units);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200717 }
718 if (leaf->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200719 ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, leaf->dflt);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200720 }
721 level--;
Michal Vasko16083662015-06-09 14:00:45 +0200722
Radek Krejci76b07902015-10-09 09:11:25 +0200723 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +0200724}
725
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200726static void
Radek Krejci76b07902015-10-09 09:11:25 +0200727yang_print_anyxml(struct lyout *out, int level, struct lys_node *node)
Michal Vasko16083662015-06-09 14:00:45 +0200728{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200729 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200730 struct lys_node_anyxml *anyxml = (struct lys_node_anyxml *)node;
Michal Vasko16083662015-06-09 14:00:45 +0200731
Radek Krejci76b07902015-10-09 09:11:25 +0200732 ly_print(out, "%*sanyxml %s {\n", LEVEL, INDENT, anyxml->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200733 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200734 yang_print_nacmext(out, level, node, node->module);
735 yang_print_snode_common2(out, level, node);
Michal Vasko4773b762015-07-07 12:15:10 +0200736 for (i = 0; i < anyxml->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200737 yang_print_iffeature(out, level, node->module, anyxml->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200738 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200739 for (i = 0; i < anyxml->must_size; i++) {
Michal Vaskof9893382015-10-09 14:03:04 +0200740 yang_print_must(out, level, node->module, &anyxml->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200741 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200742 if (anyxml->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200743 yang_print_when(out, level, node->module, anyxml->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200744 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200745 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200746 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200747}
748
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200749static void
Radek Krejci76b07902015-10-09 09:11:25 +0200750yang_print_leaflist(struct lyout *out, int level, struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200751{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200752 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200753 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200754
Radek Krejci76b07902015-10-09 09:11:25 +0200755 ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
Michal Vasko16083662015-06-09 14:00:45 +0200756
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200757 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200758 yang_print_nacmext(out, level, node, node->module);
759 yang_print_snode_common2(out, level, node);
Michal Vasko4773b762015-07-07 12:15:10 +0200760 for (i = 0; i < llist->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200761 yang_print_iffeature(out, level, node->module, llist->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200762 }
Radek Krejci1574a8d2015-08-03 14:16:52 +0200763 if (llist->flags & LYS_USERORDERED) {
Radek Krejci76b07902015-10-09 09:11:25 +0200764 ly_print(out, "%*sordered-by user;\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200765 }
766 if (llist->min > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200767 ly_print(out, "%*smin-elements %u;\n", LEVEL, INDENT, llist->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200768 }
769 if (llist->max > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200770 ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, llist->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200771 }
772 for (i = 0; i < llist->must_size; i++) {
Michal Vaskof9893382015-10-09 14:03:04 +0200773 yang_print_must(out, level, node->module, &llist->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200774 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200775 if (llist->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200776 yang_print_when(out, level, llist->module, llist->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200777 }
Radek Krejci76b07902015-10-09 09:11:25 +0200778 yang_print_type(out, level, node->module, &llist->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200779 if (llist->units != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200780 ly_print(out, "%*sunits \"%s\";\n", LEVEL, INDENT, llist->units);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200781 }
782 level--;
Michal Vasko16083662015-06-09 14:00:45 +0200783
Radek Krejci76b07902015-10-09 09:11:25 +0200784 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200785}
786
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200787static void
Radek Krejci76b07902015-10-09 09:11:25 +0200788yang_print_list(struct lyout *out, int level, struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200789{
Michal Vasko1ef07972015-07-07 14:01:35 +0200790 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200791 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200792 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200793
Radek Krejci76b07902015-10-09 09:11:25 +0200794 ly_print(out, "%*slist %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200795 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200796 yang_print_nacmext(out, level, node, node->module);
797 yang_print_snode_common2(out, level, node);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200798
Michal Vasko4773b762015-07-07 12:15:10 +0200799 for (i = 0; i < list->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200800 yang_print_iffeature(out, level, node->module, list->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200801 }
802
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200803 if (list->keys_size) {
Radek Krejci76b07902015-10-09 09:11:25 +0200804 ly_print(out, "%*skey \"", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200805 for (i = 0; i < list->keys_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200806 ly_print(out, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200807 }
Radek Krejci76b07902015-10-09 09:11:25 +0200808 ly_print(out, "\";\n");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200809 }
Radek Krejcid7f0d012015-05-25 15:04:52 +0200810
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200811 for (i = 0; i < list->unique_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200812 yang_print_unique(out, level, &list->unique[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200813 }
Michal Vaskodff818b2015-06-09 14:01:12 +0200814
Radek Krejci1574a8d2015-08-03 14:16:52 +0200815 if (list->flags & LYS_USERORDERED) {
Radek Krejci76b07902015-10-09 09:11:25 +0200816 ly_print(out, "%*sordered-by user;\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200817 }
818 if (list->min > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200819 ly_print(out, "%*smin-elements %u;\n", LEVEL, INDENT, list->min);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200820 }
821 if (list->max > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200822 ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, list->max);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200823 }
824 for (i = 0; i < list->must_size; i++) {
Michal Vaskof9893382015-10-09 14:03:04 +0200825 yang_print_must(out, level, list->module, &list->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200826 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200827 if (list->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200828 yang_print_when(out, level, list->module, list->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200829 }
Michal Vaskodff818b2015-06-09 14:01:12 +0200830
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200831 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200832 yang_print_typedef(out, level, list->module, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200833 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200834
Radek Krejci1d82ef62015-08-07 14:44:40 +0200835 LY_TREE_FOR(node->child, sub) {
Michal Vasko15b48702015-07-07 15:49:34 +0200836 /* augment */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200837 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200838 continue;
839 }
Radek Krejci76b07902015-10-09 09:11:25 +0200840 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200841 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
842 LYS_USES | LYS_GROUPING | LYS_ANYXML);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200843 }
844 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200845 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200846}
847
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200848static void
Radek Krejci76b07902015-10-09 09:11:25 +0200849yang_print_grouping(struct lyout *out, int level, struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200850{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200851 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200852 struct lys_node *child;
853 struct lys_node_grp *grp = (struct lys_node_grp *)node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200854
Radek Krejci76b07902015-10-09 09:11:25 +0200855 ly_print(out, "%*sgrouping %s {\n", LEVEL, INDENT, node->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200856 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200857
Radek Krejci76b07902015-10-09 09:11:25 +0200858 yang_print_snode_common(out, level, node);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200859
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200860 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200861 yang_print_typedef(out, level, node->module, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200862 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200863
Radek Krejci1d82ef62015-08-07 14:44:40 +0200864 LY_TREE_FOR(node->child, child) {
Radek Krejci76b07902015-10-09 09:11:25 +0200865 yang_print_snode(out, level, child,
Radek Krejci76512572015-08-04 09:47:08 +0200866 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
867 LYS_USES | LYS_GROUPING | LYS_ANYXML);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200868 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200869
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200870 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200871 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200872}
873
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200874static void
Radek Krejci76b07902015-10-09 09:11:25 +0200875yang_print_uses(struct lyout *out, int level, struct lys_node *node)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200876{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200877 int i;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200878 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200879
Radek Krejci76b07902015-10-09 09:11:25 +0200880 ly_print(out, "%*suses ", LEVEL, INDENT);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200881 if (node->child && (node->module != node->child->module) && !node->child->module->type) {
Radek Krejci76b07902015-10-09 09:11:25 +0200882 ly_print(out, "%s:", get_module_import_prefix(node->module, node->child->module));
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200883 }
Radek Krejci76b07902015-10-09 09:11:25 +0200884 ly_print(out, "%s {\n",uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200885 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200886
Radek Krejci76b07902015-10-09 09:11:25 +0200887 yang_print_nacmext(out, level, node, node->module);
888 yang_print_snode_common(out, level, node);
Michal Vasko4773b762015-07-07 12:15:10 +0200889 for (i = 0; i < uses->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200890 yang_print_iffeature(out, level, node->module, uses->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200891 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200892 if (uses->when) {
Michal Vaskof9893382015-10-09 14:03:04 +0200893 yang_print_when(out, level, node->module, uses->when);
Michal Vasko1f0428a2015-07-07 14:55:04 +0200894 }
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200895
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200896 for (i = 0; i < uses->refine_size; i++) {
Michal Vaskof9893382015-10-09 14:03:04 +0200897 yang_print_refine(out, level, node->module, &uses->refine[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200898 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200899
Michal Vasko6f25f212015-07-07 15:42:07 +0200900 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200901 yang_print_augment(out, level, node->module, &uses->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +0200902 }
903
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200904 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200905 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200906}
907
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200908static void
Radek Krejci76b07902015-10-09 09:11:25 +0200909yang_print_input_output(struct lyout *out, int level, struct lys_node *node)
Michal Vasko5bbae102015-06-16 12:16:44 +0200910{
Michal Vaskof4d3d742015-06-16 11:51:09 +0200911 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200912 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200913 struct lys_node_rpc_inout *inout = (struct lys_node_rpc_inout *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +0200914
Radek Krejci76b07902015-10-09 09:11:25 +0200915 ly_print(out, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LYS_INPUT ? "input" : "output"));
Michal Vaskof4d3d742015-06-16 11:51:09 +0200916
917 level++;
918 for (i = 0; i < inout->tpdf_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200919 yang_print_typedef(out, level, node->module, &inout->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200920 }
921
Radek Krejci1d82ef62015-08-07 14:44:40 +0200922 LY_TREE_FOR(node->child, sub) {
Michal Vasko15b48702015-07-07 15:49:34 +0200923 /* augment */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200924 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200925 continue;
926 }
Radek Krejci76b07902015-10-09 09:11:25 +0200927 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200928 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
929 LYS_USES | LYS_GROUPING | LYS_ANYXML);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200930 }
931
932 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200933 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200934}
935
936static void
Radek Krejci76b07902015-10-09 09:11:25 +0200937yang_print_rpc(struct lyout *out, int level, struct lys_node *node)
Michal Vaskof4d3d742015-06-16 11:51:09 +0200938{
939 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200940 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200941 struct lys_node_rpc *rpc = (struct lys_node_rpc *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +0200942
Radek Krejci76b07902015-10-09 09:11:25 +0200943 ly_print(out, "%*srpc %s {\n", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200944
945 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200946 yang_print_snode_common(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200947
Michal Vasko4773b762015-07-07 12:15:10 +0200948 for (i = 0; i < rpc->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200949 yang_print_iffeature(out, level, node->module, rpc->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200950 }
951
Michal Vaskof4d3d742015-06-16 11:51:09 +0200952 for (i = 0; i < rpc->tpdf_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200953 yang_print_typedef(out, level, node->module, &rpc->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200954 }
955
Radek Krejci1d82ef62015-08-07 14:44:40 +0200956 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200957 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200958 LYS_GROUPING | LYS_INPUT | LYS_OUTPUT);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200959 }
960
961 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200962 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200963}
964
965static void
Radek Krejci76b07902015-10-09 09:11:25 +0200966yang_print_notif(struct lyout *out, int level, struct lys_node *node)
Michal Vasko7690bc12015-06-16 12:26:05 +0200967{
Michal Vaskof4d3d742015-06-16 11:51:09 +0200968 int i;
Radek Krejci76512572015-08-04 09:47:08 +0200969 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200970 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Michal Vaskof4d3d742015-06-16 11:51:09 +0200971
Radek Krejci76b07902015-10-09 09:11:25 +0200972 ly_print(out, "%*snotification %s {\n", LEVEL, INDENT, node->name);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200973
974 level++;
Radek Krejci76b07902015-10-09 09:11:25 +0200975 yang_print_snode_common(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200976
Michal Vasko4773b762015-07-07 12:15:10 +0200977 for (i = 0; i < notif->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200978 yang_print_iffeature(out, level, node->module, notif->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200979 }
980
Michal Vaskof4d3d742015-06-16 11:51:09 +0200981 for (i = 0; i < notif->tpdf_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +0200982 yang_print_typedef(out, level, node->module, &notif->tpdf[i]);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200983 }
984
Radek Krejci1d82ef62015-08-07 14:44:40 +0200985 LY_TREE_FOR(node->child, sub) {
Michal Vasko15b48702015-07-07 15:49:34 +0200986 /* augment */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200987 if (sub->parent != node) {
Michal Vasko15b48702015-07-07 15:49:34 +0200988 continue;
989 }
Radek Krejci76b07902015-10-09 09:11:25 +0200990 yang_print_snode(out, level, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200991 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
992 LYS_USES | LYS_GROUPING | LYS_ANYXML);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200993 }
994
995 level--;
Radek Krejci76b07902015-10-09 09:11:25 +0200996 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vaskof4d3d742015-06-16 11:51:09 +0200997}
998
999static void
Radek Krejci76b07902015-10-09 09:11:25 +02001000yang_print_snode(struct lyout *out, int level, struct lys_node *node, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001001{
Radek Krejci1d82ef62015-08-07 14:44:40 +02001002 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +02001003 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +02001004 yang_print_container(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001005 break;
Radek Krejci76512572015-08-04 09:47:08 +02001006 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +02001007 yang_print_choice(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001008 break;
Radek Krejci76512572015-08-04 09:47:08 +02001009 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +02001010 yang_print_leaf(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001011 break;
Radek Krejci76512572015-08-04 09:47:08 +02001012 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001013 yang_print_leaflist(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001014 break;
Radek Krejci76512572015-08-04 09:47:08 +02001015 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +02001016 yang_print_list(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001017 break;
Radek Krejci76512572015-08-04 09:47:08 +02001018 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +02001019 yang_print_uses(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001020 break;
Radek Krejci76512572015-08-04 09:47:08 +02001021 case LYS_GROUPING:
Radek Krejci76b07902015-10-09 09:11:25 +02001022 yang_print_grouping(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001023 break;
Radek Krejci76512572015-08-04 09:47:08 +02001024 case LYS_ANYXML:
Radek Krejci76b07902015-10-09 09:11:25 +02001025 yang_print_anyxml(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001026 break;
Radek Krejci76512572015-08-04 09:47:08 +02001027 case LYS_CASE:
Radek Krejci76b07902015-10-09 09:11:25 +02001028 yang_print_case(out, level, node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001029 break;
Radek Krejci76512572015-08-04 09:47:08 +02001030 case LYS_INPUT:
1031 case LYS_OUTPUT:
Radek Krejci76b07902015-10-09 09:11:25 +02001032 yang_print_input_output(out, level, node);
Michal Vaskof4d3d742015-06-16 11:51:09 +02001033 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001034 default:
1035 break;
1036 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001037}
1038
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001039int
Radek Krejci76b07902015-10-09 09:11:25 +02001040yang_print_model(struct lyout *out, struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001041{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001042 unsigned int i;
1043 int level = 0;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001044#define LEVEL (level*2)
1045
Radek Krejci1d82ef62015-08-07 14:44:40 +02001046 struct lys_node *node;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001047
Michal Vasko116172e2015-07-07 11:54:37 +02001048 if (module->type) {
Radek Krejci76b07902015-10-09 09:11:25 +02001049 ly_print(out, "submodule %s {%s\n", module->name, (module->deviated ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001050 level++;
Radek Krejci76b07902015-10-09 09:11:25 +02001051 ly_print(out, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct lys_submodule *)module)->belongsto->name);
Michal Vasko116172e2015-07-07 11:54:37 +02001052 level++;
Radek Krejci76b07902015-10-09 09:11:25 +02001053 ly_print(out, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
Michal Vasko116172e2015-07-07 11:54:37 +02001054 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001055 ly_print(out, "%*s}\n", LEVEL, INDENT);
Michal Vasko116172e2015-07-07 11:54:37 +02001056 } else {
Radek Krejci76b07902015-10-09 09:11:25 +02001057 ly_print(out, "module %s {%s\n", module->name, (module->deviated ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +02001058 level++;
Radek Krejci76b07902015-10-09 09:11:25 +02001059 ly_print(out, "%*snamespace \"%s\";\n", LEVEL, INDENT, module->ns);
1060 ly_print(out, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
Michal Vasko116172e2015-07-07 11:54:37 +02001061 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001062
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001063 if (module->version) {
Radek Krejci76b07902015-10-09 09:11:25 +02001064 ly_print(out, "%*syang-version %s;\n", LEVEL, INDENT, module->version == 1 ? "1" : "1.1");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001065 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001066
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001067 for (i = 0; i < module->imp_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +02001068 ly_print(out, "%*simport \"%s\" {\n", LEVEL, INDENT, module->imp[i].module->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001069 level++;
Radek Krejci76b07902015-10-09 09:11:25 +02001070 ly_print(out, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->imp[i].prefix);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001071 if (module->imp[i].rev[0]) {
Radek Krejci76b07902015-10-09 09:11:25 +02001072 yang_print_text(out, level, "revision-date", module->imp[i].rev);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001073 }
1074 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001075 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001076 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001077
Michal Vaskoe0af1e22015-07-07 14:02:02 +02001078 for (i = 0; i < module->deviation_size; ++i) {
Radek Krejci76b07902015-10-09 09:11:25 +02001079 yang_print_deviation(out, level, module, &module->deviation[i]);
Michal Vaskoe0af1e22015-07-07 14:02:02 +02001080 }
1081
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001082 for (i = 0; i < module->inc_size; i++) {
1083 if (module->inc[i].rev[0]) {
Radek Krejci76b07902015-10-09 09:11:25 +02001084 ly_print(out, "%*sinclude \"%s\" {\n", LEVEL, INDENT, module->inc[i].submodule->name);
1085 yang_print_text(out, level + 1, "revision-date", module->inc[i].rev);
1086 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001087 } else {
Radek Krejci76b07902015-10-09 09:11:25 +02001088 ly_print(out, "%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001089 }
1090 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001091
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001092 if (module->org) {
Radek Krejci76b07902015-10-09 09:11:25 +02001093 yang_print_text(out, level, "organization", module->org);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001094 }
1095 if (module->contact) {
Radek Krejci76b07902015-10-09 09:11:25 +02001096 yang_print_text(out, level, "contact", module->contact);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001097 }
1098 if (module->dsc) {
Radek Krejci76b07902015-10-09 09:11:25 +02001099 yang_print_text(out, level, "description", module->dsc);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001100 }
1101 if (module->ref) {
Radek Krejci76b07902015-10-09 09:11:25 +02001102 yang_print_text(out, level, "reference", module->ref);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001103 }
1104 for (i = 0; i < module->rev_size; i++) {
1105 if (module->rev[i].dsc || module->rev[i].ref) {
Radek Krejci76b07902015-10-09 09:11:25 +02001106 ly_print(out, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001107 level++;
1108 if (module->rev[i].dsc) {
Radek Krejci76b07902015-10-09 09:11:25 +02001109 yang_print_text(out, level, "description", module->rev[i].dsc);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001110 }
1111 if (module->rev[i].ref) {
Radek Krejci76b07902015-10-09 09:11:25 +02001112 yang_print_text(out, level, "reference", module->rev[i].ref);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001113 }
1114 level--;
Radek Krejci76b07902015-10-09 09:11:25 +02001115 ly_print(out, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001116 } else {
Radek Krejci76b07902015-10-09 09:11:25 +02001117 yang_print_text(out, level, "revision", module->rev[i].date);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001118 }
1119 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001120
Michal Vasko30f6e912015-07-07 12:24:27 +02001121 for (i = 0; i < module->features_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +02001122 yang_print_feature(out, level, &module->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +02001123 }
1124
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001125 for (i = 0; i < module->ident_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +02001126 yang_print_identity(out, level, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001127 }
Radek Krejci6793db02015-05-22 17:49:54 +02001128
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001129 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +02001130 yang_print_typedef(out, level, module, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001131 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001132
Radek Krejci1d82ef62015-08-07 14:44:40 +02001133 LY_TREE_FOR(module->data, node) {
Radek Krejci92720552015-10-05 15:28:27 +02001134 switch(node->nodetype) {
1135 case LYS_RPC:
Radek Krejcibac81762015-10-09 10:19:52 +02001136 yang_print_rpc(out, level, node);
Radek Krejci92720552015-10-05 15:28:27 +02001137 break;
1138 case LYS_NOTIF:
Radek Krejcibac81762015-10-09 10:19:52 +02001139 yang_print_notif(out, level, node);
Radek Krejci92720552015-10-05 15:28:27 +02001140 break;
1141 default:
Radek Krejcibac81762015-10-09 10:19:52 +02001142 yang_print_snode(out, level, node,
Radek Krejci92720552015-10-05 15:28:27 +02001143 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST |
1144 LYS_USES | LYS_GROUPING | LYS_ANYXML);
1145 break;
1146 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001147 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001148
Michal Vasko6f25f212015-07-07 15:42:07 +02001149 for (i = 0; i < module->augment_size; i++) {
Radek Krejci76b07902015-10-09 09:11:25 +02001150 yang_print_augment(out, level, module, &module->augment[i]);
Michal Vasko6f25f212015-07-07 15:42:07 +02001151 }
1152
Radek Krejci76b07902015-10-09 09:11:25 +02001153 ly_print(out, "}\n");
Radek Krejcida04f4a2015-05-21 12:54:09 +02001154
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001155 return EXIT_SUCCESS;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001156#undef LEVEL
1157}