blob: d9e963119204d23a50a5876559ab7183598e5942 [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>
23#include <stdio.h>
24#include <string.h>
25
Radek Krejciefdd0ce2015-05-26 16:48:29 +020026#include "../common.h"
27#include "../tree.h"
Radek Krejcida04f4a2015-05-21 12:54:09 +020028
29#define INDENT ""
30#define LEVEL (level*2)
31
Michal Vasko5bbae102015-06-16 12:16:44 +020032static void yang_print_mnode(FILE *f, int level, struct ly_mnode *mnode, int mask);
Radek Krejcida04f4a2015-05-21 12:54:09 +020033
Michal Vaskoc39c4b12015-07-07 14:55:33 +020034static const char*
35get_module_import_prefix(struct ly_module *main_mod, struct ly_module *imp_mod)
36{
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
Michal Vasko5bbae102015-06-16 12:16:44 +020057yang_print_text(FILE *f, 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 Krejci6e4ffbb2015-06-16 10:34:41 +020061 fprintf(f, "%*s%s\n", LEVEL, INDENT, name);
62 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +020063
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020064 fprintf(f, "%*s\"", LEVEL, INDENT);
65 t = text;
66 while ((s = strchr(t, '\n'))) {
Michal Vasko5bbae102015-06-16 12:16:44 +020067 fwrite(t, sizeof *t, (s - t) + 1, f);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020068 t = s + 1;
69 fprintf(f, "%*s", LEVEL, INDENT);
70 }
Radek Krejcida04f4a2015-05-21 12:54:09 +020071
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020072 fprintf(f, "%s\";\n\n", t);
73 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +020074
75}
76
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020077static void
Radek Krejci6a113852015-07-03 16:04:20 +020078yang_print_nacmext(FILE *f, int level, struct ly_mnode *mnode)
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
83 if (mnode->nacm && (!mnode->parent || mnode->parent->nacm != mnode->nacm)) {
84 /* locate ietf-netconf-acm module in imports */
85 if (!strcmp(mnode->module->name, "ietf-netconf-acm")) {
86 prefix = mnode->module->prefix;
87 } else {
88 /* search in imports */
89 for (i = 0; i < mnode->module->imp_size; i++) {
90 if (!strcmp(mnode->module->imp[i].module->name, "ietf-netconf-acm")) {
91 prefix = mnode->module->imp[i].prefix;
92 break;
93 }
94 }
95 /* and in imports of includes */
96 if (!prefix) {
97 for (j = 0; j < mnode->module->inc_size; j++) {
98 for (i = 0; i < mnode->module->inc[j].submodule->imp_size; i++) {
99 if (!strcmp(mnode->module->inc[j].submodule->imp[i].module->name, "ietf-netconf-acm")) {
100 prefix = mnode->module->inc[j].submodule->imp[i].prefix;
101 break;
102 }
103 }
104 }
105 }
106 }
107
108 if ((mnode->nacm & LY_NACM_DENYW) && (!mnode->parent || !(mnode->parent->nacm & LY_NACM_DENYW))) {
109 fprintf(f, "%*s%s:default-deny-write;\n", LEVEL, INDENT, prefix);
110 }
111 if ((mnode->nacm & LY_NACM_DENYA) && (!mnode->parent || !(mnode->parent->nacm & LY_NACM_DENYA))) {
112 fprintf(f, "%*s%s:default-deny-all;\n", LEVEL, INDENT, prefix);
113 }
114 }
Radek Krejci6a113852015-07-03 16:04:20 +0200115}
116
117/*
118 * Covers:
119 * description, reference, status
120 */
121static void
122yang_print_mnode_common(FILE *f, int level, struct ly_mnode *mnode)
123{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200124 if (mnode->flags & LY_NODE_STATUS_CURR) {
125 fprintf(f, "%*sstatus \"current\";\n", LEVEL, INDENT);
126 } else if (mnode->flags & LY_NODE_STATUS_DEPRC) {
127 fprintf(f, "%*sstatus \"deprecated\";\n", LEVEL, INDENT);
128 } else if (mnode->flags & LY_NODE_STATUS_OBSLT) {
129 fprintf(f, "%*sstatus \"obsolete\";\n", LEVEL, INDENT);
130 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200131
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200132 if (mnode->dsc) {
133 yang_print_text(f, level, "description", mnode->dsc);
134 }
135 if (mnode->ref) {
136 yang_print_text(f, level, "reference", mnode->ref);
137 }
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
Michal Vasko5bbae102015-06-16 12:16:44 +0200146yang_print_mnode_common2(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200147{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200148 if (!mnode->parent || (mnode->parent->flags & LY_NODE_CONFIG_MASK) != (mnode->flags & LY_NODE_CONFIG_MASK)) {
149 /* print config only when it differs from the parent or in root */
150 if (mnode->flags & LY_NODE_CONFIG_W) {
151 fprintf(f, "%*sconfig \"true\";\n", LEVEL, INDENT);
152 } else if (mnode->flags & LY_NODE_CONFIG_R) {
153 fprintf(f, "%*sconfig \"false\";\n", LEVEL, INDENT);
154 }
155 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200156
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200157 if (mnode->flags & LY_NODE_MAND_TRUE) {
158 fprintf(f, "%*smandatory \"true\";\n", LEVEL, INDENT);
159 } else if (mnode->flags & LY_NODE_MAND_FALSE) {
160 fprintf(f, "%*smandatory \"false\";\n", LEVEL, INDENT);
161 }
Michal Vasko2b8faed2015-06-09 12:51:20 +0200162
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200163 yang_print_mnode_common(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200164}
165
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200166static void
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200167yang_print_iffeature(FILE *f, int level, struct ly_module *module, struct ly_feature *feat)
168{
169 fprintf(f, "%*sif-feature ", LEVEL, INDENT);
170 if ((feat->module != module) && !feat->module->type) {
171 fprintf(f, "%s:", get_module_import_prefix(module, feat->module));
172 }
173 fprintf(f, "%s;\n", feat->name);
174}
175
176static void
Michal Vasko4773b762015-07-07 12:15:10 +0200177yang_print_feature(FILE *f, int level, struct ly_feature *feat)
178{
Michal Vasko30f6e912015-07-07 12:24:27 +0200179 int i;
180
Michal Vasko4773b762015-07-07 12:15:10 +0200181 fprintf(f, "%*sfeature %s {\n", LEVEL, INDENT, feat->name);
182 level++;
183
Michal Vasko30f6e912015-07-07 12:24:27 +0200184 yang_print_mnode_common(f, level, (struct ly_mnode *)feat);
185 for (i = 0; i < feat->features_size; ++i) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200186 yang_print_iffeature(f, level, feat->module, feat->features[i]);
Michal Vasko30f6e912015-07-07 12:24:27 +0200187 }
Michal Vasko4773b762015-07-07 12:15:10 +0200188
189 level--;
190 fprintf(f, "%*s}\n", LEVEL, INDENT);
191}
192
193static void
Radek Krejci0bd5db42015-06-19 13:30:07 +0200194yang_print_restr(FILE *f, int level, struct ly_restr *restr)
Radek Krejci41726f92015-06-19 13:11:05 +0200195{
Radek Krejci0bd5db42015-06-19 13:30:07 +0200196 if (restr->dsc != NULL) {
197 yang_print_text(f, level, "description", restr->dsc);
Radek Krejci41726f92015-06-19 13:11:05 +0200198 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200199 if (restr->ref != NULL) {
200 yang_print_text(f, level, "reference", restr->ref);
Radek Krejci41726f92015-06-19 13:11:05 +0200201 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200202 if (restr->eapptag != NULL) {
203 fprintf(f, "%*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) {
206 yang_print_text(f, level, "error-message", restr->emsg);
Radek Krejci41726f92015-06-19 13:11:05 +0200207 }
208}
209
210static void
Michal Vasko1f0428a2015-07-07 14:55:04 +0200211yang_print_when(FILE *f, int level, struct ly_when *when)
212{
213 fprintf(f, "%*swhen \"%s\" {\n", LEVEL, INDENT, when->cond);
214 level++;
215 if (when->dsc) {
216 yang_print_text(f, level, "description", when->dsc);
217 }
218 if (when->ref) {
219 yang_print_text(f, level, "reference", when->ref);
220 }
221 level--;
222 fprintf(f, "%*s}\n", LEVEL, INDENT);
223}
224
225static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200226yang_print_type(FILE *f, int level, struct ly_module *module, struct ly_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200227{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200228 int i;
Radek Krejci25d782a2015-05-22 15:03:23 +0200229
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200230 if (type->prefix) {
231 fprintf(f, "%*stype %s:%s {\n", LEVEL, INDENT, type->prefix, type->der->name);
232 } else {
233 fprintf(f, "%*stype %s {\n", LEVEL, INDENT, type->der->name);
234 }
235 level++;
236 switch (type->base) {
237 case LY_TYPE_BINARY:
238 if (type->info.binary.length != NULL) {
Radek Krejci41726f92015-06-19 13:11:05 +0200239 fprintf(f, "%*slength \"%s\" {\n", LEVEL, INDENT, type->info.binary.length->expr);
Radek Krejci0bd5db42015-06-19 13:30:07 +0200240 yang_print_restr(f, level + 1, type->info.binary.length);
Radek Krejci41726f92015-06-19 13:11:05 +0200241 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200242 }
243 break;
244 case LY_TYPE_BITS:
245 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci994b6f62015-06-18 16:47:27 +0200246 fprintf(f, "%*sbit %s {\n", LEVEL, INDENT, type->info.bits.bit[i].name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200247 level++;
248 yang_print_mnode_common(f, level, (struct ly_mnode *)&type->info.bits.bit[i]);
249 fprintf(f, "%*sposition %u;\n", LEVEL, INDENT, type->info.bits.bit[i].pos);
250 level--;
251 fprintf(f, "%*s}\n", LEVEL, INDENT);
252 }
253 break;
254 case LY_TYPE_DEC64:
255 fprintf(f, "%*sfraction-digits %d;\n", LEVEL, INDENT, type->info.dec64.dig);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200256 if (type->info.dec64.range != NULL) {
257 fprintf(f, "%*srange \"%s\" {\n", LEVEL, INDENT, type->info.dec64.range->expr);
258 yang_print_restr(f, level + 1, type->info.dec64.range);
259 fprintf(f, "%*s}\n", LEVEL, INDENT);
260 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200261 break;
262 case LY_TYPE_ENUM:
263 for (i = 0; i < type->info.enums.count; i++) {
264 fprintf(f, "%*senum %s {\n", LEVEL, INDENT, type->info.enums.list[i].name);
265 level++;
266 yang_print_mnode_common(f, level, (struct ly_mnode *)&type->info.enums.list[i]);
267 fprintf(f, "%*svalue %d;\n", LEVEL, INDENT, type->info.enums.list[i].value);
268 level--;
269 fprintf(f, "%*s}\n", LEVEL, INDENT);
270 }
271 break;
272 case LY_TYPE_IDENT:
273 if (module == type->info.ident.ref->module) {
274 fprintf(f, "%*sbase %s;\n", LEVEL, INDENT, type->info.ident.ref->name);
275 } else {
276 fprintf(f, "%*sbase %s:%s;\n", LEVEL, INDENT, type->info.ident.ref->module->prefix,
277 type->info.ident.ref->name);
278 }
279 break;
280 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200281 if (type->info.inst.req == 1) {
282 fprintf(f, "%*srequire-instance \"true\";\n", LEVEL, INDENT);
283 } else if (type->info.inst.req == -1) {
284 fprintf(f, "%*srequire-instance \"false\";\n", LEVEL, INDENT);
285 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200286 break;
287 case LY_TYPE_INT8:
288 case LY_TYPE_INT16:
289 case LY_TYPE_INT32:
290 case LY_TYPE_INT64:
291 case LY_TYPE_UINT8:
292 case LY_TYPE_UINT16:
293 case LY_TYPE_UINT32:
294 case LY_TYPE_UINT64:
Radek Krejcif2860132015-06-20 12:37:20 +0200295 if (type->info.num.range != NULL) {
296 fprintf(f, "%*srange \"%s\" {\n", LEVEL, INDENT, type->info.num.range->expr);
297 yang_print_restr(f, level + 1, type->info.num.range);
298 fprintf(f, "%*s}\n", LEVEL, INDENT);
299 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200300 break;
301 case LY_TYPE_LEAFREF:
302 fprintf(f, "%*spath \"%s\";\n", LEVEL, INDENT, type->info.lref.path);
303 break;
304 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200305 if (type->info.str.length) {
Radek Krejci061bd522015-06-19 13:45:16 +0200306 fprintf(f, "%*slength \"%s\" {\n", LEVEL, INDENT, type->info.str.length->expr);
307 yang_print_restr(f, level + 1, type->info.str.length);
308 fprintf(f, "%*s}\n", LEVEL, INDENT);
309 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200310 for (i = 0; i < type->info.str.pat_count; i++) {
311 fprintf(f, "%*spattern \"%s\" {\n", LEVEL, INDENT, type->info.str.patterns[i].expr);
312 yang_print_restr(f, level + 1, &type->info.str.patterns[i]);
313 fprintf(f, "%*s}\n", LEVEL, INDENT);
314 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200315 break;
316 case LY_TYPE_UNION:
317 for (i = 0; i < type->info.uni.count; ++i) {
318 yang_print_type(f, level, module, &type->info.uni.type[i]);
319 }
320 break;
321 default:
322 /* other types do not have substatements */
323 break;
324 }
325 level--;
326 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200327}
328
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200329static void
Radek Krejci0bd5db42015-06-19 13:30:07 +0200330yang_print_must(FILE *f, int level, struct ly_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200331{
Radek Krejci0bd5db42015-06-19 13:30:07 +0200332 fprintf(f, "%*smust \"%s\" {\n", LEVEL, INDENT, must->expr);
Radek Krejci41726f92015-06-19 13:11:05 +0200333 yang_print_restr(f, level + 1, must);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200334 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200335}
336
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200337static void
Michal Vasko1ef07972015-07-07 14:01:35 +0200338yang_print_unique(FILE *f, int level, struct ly_unique *uniq)
339{
340 int i;
341
342 fprintf(f, "%*sunique \"", LEVEL, INDENT);
343 for (i = 0; i < uniq->leafs_size; i++) {
344 fprintf(f, "%s%s", uniq->leafs[i]->name, i + 1 < uniq->leafs_size ? " " : "");
345 }
346 fprintf(f, "\";\n");
347}
348
349static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200350yang_print_refine(FILE *f, int level, struct ly_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200351{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200352 int i;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200353
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200354 fprintf(f, "%*srefine \"%s\" {\n", LEVEL, INDENT, refine->target);
355 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200356
Radek Krejci6a113852015-07-03 16:04:20 +0200357 if (refine->flags & LY_NODE_CONFIG_W) {
358 fprintf(f, "%*sconfig \"true\";\n", LEVEL, INDENT);
359 } else if (refine->flags & LY_NODE_CONFIG_R) {
360 fprintf(f, "%*sconfig \"false\";\n", LEVEL, INDENT);
361 }
362
363 if (refine->flags & LY_NODE_MAND_TRUE) {
364 fprintf(f, "%*smandatory \"true\";\n", LEVEL, INDENT);
365 } else if (refine->flags & LY_NODE_MAND_FALSE) {
366 fprintf(f, "%*smandatory \"false\";\n", LEVEL, INDENT);
367 }
368
369 yang_print_mnode_common(f, level, (struct ly_mnode *)refine);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200370
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200371 for (i = 0; i < refine->must_size; ++i) {
372 yang_print_must(f, level, &refine->must[i]);
373 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200374
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200375 if (refine->target_type & (LY_NODE_LEAF | LY_NODE_CHOICE)) {
376 if (refine->mod.dflt != NULL) {
377 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, refine->mod.dflt);
378 }
379 } else if (refine->target_type == LY_NODE_CONTAINER) {
380 if (refine->mod.presence != NULL) {
381 yang_print_text(f, level, "presence", refine->mod.presence);
382 }
383 } else if (refine->target_type & (LY_NODE_LIST | LY_NODE_LEAFLIST)) {
384 if (refine->mod.list.min > 0) {
385 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, refine->mod.list.min);
386 }
387 if (refine->mod.list.max > 0) {
388 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, refine->mod.list.max);
389 }
390 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200391
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200392 level--;
393 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200394}
395
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200396static void
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200397yang_print_deviation(FILE *f, int level, struct ly_module *module, struct ly_deviation *deviation)
398{
399 int i, j;
400
401 fprintf(f, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, deviation->target_name);
402 level++;
403
404 if (deviation->dsc) {
405 yang_print_text(f, level, "description", deviation->dsc);
406 }
407 if (deviation->ref) {
408 yang_print_text(f, level, "reference", deviation->ref);
409 }
410
411 for (i = 0; i < deviation->deviate_size; ++i) {
412 fprintf(f, "%*sdeviate ", LEVEL, INDENT);
413 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
414 fprintf(f, "not-supported {\n");
415 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
416 fprintf(f, "add {\n");
417 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
418 fprintf(f, "replace {\n");
419 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
420 fprintf(f, "delete {\n");
421 }
422 level++;
423
424 if (deviation->deviate[i].flags & LY_NODE_CONFIG_W) {
425 fprintf(f, "%*sconfig \"true\";\n", LEVEL, INDENT);
426 } else if (deviation->deviate[i].flags & LY_NODE_CONFIG_R) {
427 fprintf(f, "%*sconfig \"false\";\n", LEVEL, INDENT);
428 }
429
430 if (deviation->deviate[i].flags & LY_NODE_MAND_TRUE) {
431 fprintf(f, "%*smandatory \"true\";\n", LEVEL, INDENT);
432 } else if (deviation->deviate[i].flags & LY_NODE_MAND_FALSE) {
433 fprintf(f, "%*smandatory \"false\";\n", LEVEL, INDENT);
434 }
435
436 if (deviation->deviate[i].dflt) {
437 fprintf(f, "%*sdefault %s;\n", LEVEL, INDENT, deviation->deviate[i].dflt);
438 }
439
440 if (deviation->deviate[i].min) {
441 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].min);
442 }
443 if (deviation->deviate[i].max) {
444 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].max);
445 }
446
447 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
448 yang_print_must(f, level, &deviation->deviate[i].must[j]);
449 }
450
451 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
452 yang_print_unique(f, level, &deviation->deviate[i].unique[j]);
453 }
454
455 if (deviation->deviate[i].type) {
456 yang_print_type(f, level, module, deviation->deviate[i].type);
457 }
458
459 if (deviation->deviate[i].units) {
460 fprintf(f, "%*sunits %s;\n", LEVEL, INDENT, deviation->deviate[i].units);
461 }
462
463 level--;
464 fprintf(f, "%*s}\n", LEVEL, INDENT);
465 }
466
467 level--;
468 fprintf(f, "%*s}\n", LEVEL, INDENT);
469}
470
471static void
Michal Vasko6f25f212015-07-07 15:42:07 +0200472yang_print_augment(FILE *f, int level, struct ly_module *module, struct ly_augment *augment)
473{
474 int i;
475 struct ly_mnode *sub;
476
477 fprintf(f, "%*saugment \"%s\" {\n", LEVEL, INDENT, augment->target_name);
478 level++;
479
480 yang_print_mnode_common(f, level, (struct ly_mnode *)augment);
481
482 for (i = 0; i < augment->features_size; i++) {
483 yang_print_iffeature(f, level, module, augment->features[i]);
484 }
485
486 if (augment->when) {
487 yang_print_when(f, level, augment->when);
488 }
489
490 LY_TREE_FOR(augment->child, sub) {
491 yang_print_mnode(f, level, sub,
492 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
493 LY_NODE_USES | LY_NODE_ANYXML | LY_NODE_CASE);
494 }
495
496 level--;
497 fprintf(f, "%*s}\n", LEVEL, INDENT);
498}
499
500static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200501yang_print_typedef(FILE *f, int level, struct ly_module *module, struct ly_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200502{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200503 fprintf(f, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
504 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200505
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200506 yang_print_mnode_common(f, level, (struct ly_mnode *)tpdf);
507 yang_print_type(f, level, module, &tpdf->type);
508 if (tpdf->units != NULL) {
509 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, tpdf->units);
510 }
511 if (tpdf->dflt != NULL) {
512 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, tpdf->dflt);
513 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200514
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200515 level--;
516 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200517}
518
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200519static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200520yang_print_identity(FILE *f, int level, struct ly_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200521{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200522 fprintf(f, "%*sidentity %s {\n", LEVEL, INDENT, ident->name);
523 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200524
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200525 yang_print_mnode_common(f, level, (struct ly_mnode *)ident);
526 if (ident->base) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200527 fprintf(f, "%*sbase ", LEVEL, INDENT);
528 if ((ident->module != ident->base->module) && !ident->base->module->type) {
529 fprintf(f, "%s:", get_module_import_prefix(ident->module, ident->base->module));
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200530 }
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200531 fprintf(f, "%s;\n", ident->base->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200532 }
Radek Krejci6793db02015-05-22 17:49:54 +0200533
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200534 level--;
535 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejci6793db02015-05-22 17:49:54 +0200536
537}
538
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200539static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200540yang_print_container(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200541{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200542 int i;
543 struct ly_mnode *sub;
544 struct ly_mnode_container *cont = (struct ly_mnode_container *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200545
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200546 fprintf(f, "%*scontainer %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200547
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200548 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200549
550 yang_print_nacmext(f, level, mnode);
551
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200552 if (cont->presence != NULL) {
553 yang_print_text(f, level, "presence", cont->presence);
554 }
Michal Vasko7f976ee2015-06-09 13:55:41 +0200555
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200556 for (i = 0; i < cont->must_size; i++) {
557 yang_print_must(f, level, &cont->must[i]);
558 }
Michal Vasko7f976ee2015-06-09 13:55:41 +0200559
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200560 yang_print_mnode_common2(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200561
Michal Vasko4773b762015-07-07 12:15:10 +0200562 for (i = 0; i < cont->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200563 yang_print_iffeature(f, level, mnode->module, cont->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200564 }
565
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200566 for (i = 0; i < cont->tpdf_size; i++) {
567 yang_print_typedef(f, level, mnode->module, &cont->tpdf[i]);
568 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200569
Michal Vasko1f0428a2015-07-07 14:55:04 +0200570 if (cont->when) {
571 yang_print_when(f, level, cont->when);
572 }
573
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200574 LY_TREE_FOR(mnode->child, sub) {
575 yang_print_mnode(f, level, sub,
576 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
577 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
578 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200579
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200580 level--;
581 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200582}
583
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200584static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200585yang_print_case(FILE *f, int level, struct ly_mnode *mnode)
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200586{
Michal Vasko4773b762015-07-07 12:15:10 +0200587 int i;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200588 struct ly_mnode *sub;
589 struct ly_mnode_case *cas = (struct ly_mnode_case *)mnode;
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200590
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200591 fprintf(f, "%*scase %s {\n", LEVEL, INDENT, cas->name);
592 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200593 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200594 yang_print_mnode_common2(f, level, mnode);
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200595
Michal Vasko4773b762015-07-07 12:15:10 +0200596 for (i = 0; i < cas->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200597 yang_print_iffeature(f, level, mnode->module, cas->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200598 }
599
Michal Vasko1f0428a2015-07-07 14:55:04 +0200600 if (cas->when) {
601 yang_print_when(f, level, cas->when);
602 }
603
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200604 LY_TREE_FOR(mnode->child, sub) {
605 yang_print_mnode(f, level, sub,
606 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
607 LY_NODE_USES | LY_NODE_ANYXML);
608 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200609
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200610 level--;
611 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200612}
613
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200614static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200615yang_print_choice(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200616{
Michal Vasko4773b762015-07-07 12:15:10 +0200617 int i;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200618 struct ly_mnode *sub;
619 struct ly_mnode_choice *choice = (struct ly_mnode_choice *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200620
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200621 fprintf(f, "%*schoice %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200622
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200623 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200624 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200625 if (choice->dflt != NULL) {
626 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, choice->dflt->name);
627 }
Michal Vasko16083662015-06-09 14:00:45 +0200628
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200629 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200630
631 for (i = 0; i < choice->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200632 yang_print_iffeature(f, level, mnode->module, choice->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200633 }
634
Michal Vasko1f0428a2015-07-07 14:55:04 +0200635 if (choice->when) {
636 yang_print_when(f, level, choice->when);
637 }
638
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200639 LY_TREE_FOR(mnode->child, sub) {
640 yang_print_mnode(f, level, sub,
641 LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_CASE);
642 }
643 level--;
644 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200645}
646
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200647static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200648yang_print_leaf(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200649{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200650 int i;
651 struct ly_mnode_leaf *leaf = (struct ly_mnode_leaf *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200652
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200653 fprintf(f, "%*sleaf %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200654
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200655 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200656 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200657 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200658 for (i = 0; i < leaf->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200659 yang_print_iffeature(f, level, mnode->module, leaf->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200660 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200661 for (i = 0; i < leaf->must_size; i++) {
662 yang_print_must(f, level, &leaf->must[i]);
663 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200664 if (leaf->when) {
665 yang_print_when(f, level, leaf->when);
666 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200667 yang_print_type(f, level, mnode->module, &leaf->type);
668 if (leaf->units != NULL) {
669 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, leaf->units);
670 }
671 if (leaf->dflt != NULL) {
672 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, leaf->dflt);
673 }
674 level--;
Michal Vasko16083662015-06-09 14:00:45 +0200675
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200676 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +0200677}
678
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200679static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200680yang_print_anyxml(FILE *f, int level, struct ly_mnode *mnode)
Michal Vasko16083662015-06-09 14:00:45 +0200681{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200682 int i;
683 struct ly_mnode_anyxml *anyxml = (struct ly_mnode_anyxml *)mnode;
Michal Vasko16083662015-06-09 14:00:45 +0200684
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200685 fprintf(f, "%*sanyxml %s {\n", LEVEL, INDENT, anyxml->name);
686 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200687 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200688 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200689 for (i = 0; i < anyxml->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200690 yang_print_iffeature(f, level, mnode->module, anyxml->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200691 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200692 for (i = 0; i < anyxml->must_size; i++) {
693 yang_print_must(f, level, &anyxml->must[i]);
694 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200695 if (anyxml->when) {
696 yang_print_when(f, level, anyxml->when);
697 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200698 level--;
699 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200700}
701
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200702static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200703yang_print_leaflist(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200704{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200705 int i;
706 struct ly_mnode_leaflist *llist = (struct ly_mnode_leaflist *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200707
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200708 fprintf(f, "%*sleaf-list %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200709
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200710 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200711 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200712 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200713 for (i = 0; i < llist->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200714 yang_print_iffeature(f, level, mnode->module, llist->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200715 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200716 if (llist->flags & LY_NODE_USERORDERED) {
717 fprintf(f, "%*sordered-by user;\n", LEVEL, INDENT);
718 }
719 if (llist->min > 0) {
720 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, llist->min);
721 }
722 if (llist->max > 0) {
723 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, llist->max);
724 }
725 for (i = 0; i < llist->must_size; i++) {
726 yang_print_must(f, level, &llist->must[i]);
727 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200728 if (llist->when) {
729 yang_print_when(f, level, llist->when);
730 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200731 yang_print_type(f, level, mnode->module, &llist->type);
732 if (llist->units != NULL) {
733 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, llist->units);
734 }
735 level--;
Michal Vasko16083662015-06-09 14:00:45 +0200736
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200737 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200738}
739
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200740static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200741yang_print_list(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200742{
Michal Vasko1ef07972015-07-07 14:01:35 +0200743 int i;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200744 struct ly_mnode *sub;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200745 struct ly_mnode_list *list = (struct ly_mnode_list *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200746
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200747 fprintf(f, "%*slist %s {\n", LEVEL, INDENT, mnode->name);
748 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200749 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200750 yang_print_mnode_common2(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200751
Michal Vasko4773b762015-07-07 12:15:10 +0200752 for (i = 0; i < list->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200753 yang_print_iffeature(f, level, mnode->module, list->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200754 }
755
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200756 if (list->keys_size) {
757 fprintf(f, "%*skey \"", LEVEL, INDENT);
758 for (i = 0; i < list->keys_size; i++) {
759 fprintf(f, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "");
760 }
761 fprintf(f, "\";\n");
762 }
Radek Krejcid7f0d012015-05-25 15:04:52 +0200763
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200764 for (i = 0; i < list->unique_size; i++) {
Michal Vasko1ef07972015-07-07 14:01:35 +0200765 yang_print_unique(f, level, &list->unique[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200766 }
Michal Vaskodff818b2015-06-09 14:01:12 +0200767
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200768 if (list->flags & LY_NODE_USERORDERED) {
769 fprintf(f, "%*sordered-by user;\n", LEVEL, INDENT);
770 }
771 if (list->min > 0) {
772 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, list->min);
773 }
774 if (list->max > 0) {
775 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, list->max);
776 }
777 for (i = 0; i < list->must_size; i++) {
778 yang_print_must(f, level, &list->must[i]);
779 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200780 if (list->when) {
781 yang_print_when(f, level, list->when);
782 }
Michal Vaskodff818b2015-06-09 14:01:12 +0200783
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200784 for (i = 0; i < list->tpdf_size; i++) {
785 yang_print_typedef(f, level, list->module, &list->tpdf[i]);
786 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200787
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200788 LY_TREE_FOR(mnode->child, sub) {
789 yang_print_mnode(f, level, sub,
790 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
791 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
792 }
793 level--;
794 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200795}
796
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200797static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200798yang_print_grouping(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200799{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200800 int i;
801 struct ly_mnode *node;
802 struct ly_mnode_grp *grp = (struct ly_mnode_grp *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200803
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200804 fprintf(f, "%*sgrouping %s {\n", LEVEL, INDENT, mnode->name);
805 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200806
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200807 yang_print_mnode_common(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200808
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200809 for (i = 0; i < grp->tpdf_size; i++) {
810 yang_print_typedef(f, level, mnode->module, &grp->tpdf[i]);
811 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200812
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200813 LY_TREE_FOR(mnode->child, node) {
814 yang_print_mnode(f, level, node,
815 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
816 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
817 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200818
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200819 level--;
820 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200821}
822
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200823static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200824yang_print_uses(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200825{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200826 int i;
827 struct ly_mnode_uses *uses = (struct ly_mnode_uses *)mnode;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200828
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200829 fprintf(f, "%*suses ", LEVEL, INDENT);
830 if (mnode->child && (mnode->module != mnode->child->module) && !mnode->child->module->type) {
831 fprintf(f, "%s:", get_module_import_prefix(mnode->module, mnode->child->module));
832 }
833 fprintf(f, "%s {\n",uses->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200834 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200835
Radek Krejci6a113852015-07-03 16:04:20 +0200836 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200837 yang_print_mnode_common(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200838 for (i = 0; i < uses->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200839 yang_print_iffeature(f, level, mnode->module, uses->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200840 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200841 if (uses->when) {
842 yang_print_when(f, level, uses->when);
843 }
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200844
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200845 for (i = 0; i < uses->refine_size; i++) {
846 yang_print_refine(f, level, &uses->refine[i]);
847 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200848
Michal Vasko6f25f212015-07-07 15:42:07 +0200849 for (i = 0; i < uses->augment_size; i++) {
850 yang_print_augment(f, level, mnode->module, &uses->augment[i]);
851 }
852
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200853 level--;
854 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200855}
856
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200857static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200858yang_print_input_output(FILE *f, int level, struct ly_mnode *mnode)
859{
Michal Vaskof4d3d742015-06-16 11:51:09 +0200860 int i;
861 struct ly_mnode *sub;
Michal Vaskofb69a842015-06-16 12:07:40 +0200862 struct ly_mnode_input_output *inout = (struct ly_mnode_input_output *)mnode;
Michal Vaskof4d3d742015-06-16 11:51:09 +0200863
864 fprintf(f, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LY_NODE_INPUT ? "input" : "output"));
865
866 level++;
867 for (i = 0; i < inout->tpdf_size; i++) {
868 yang_print_typedef(f, level, mnode->module, &inout->tpdf[i]);
869 }
870
871 LY_TREE_FOR(mnode->child, sub) {
872 yang_print_mnode(f, level, sub,
873 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
874 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
875 }
876
877 level--;
878 fprintf(f, "%*s}\n", LEVEL, INDENT);
879}
880
881static void
882yang_print_rpc(FILE *f, int level, struct ly_mnode *mnode)
883{
884 int i;
885 struct ly_mnode *sub;
886 struct ly_mnode_rpc *rpc = (struct ly_mnode_rpc *)mnode;
887
888 fprintf(f, "%*srpc %s {\n", LEVEL, INDENT, mnode->name);
889
890 level++;
891 yang_print_mnode_common(f, level, mnode);
892
Michal Vasko4773b762015-07-07 12:15:10 +0200893 for (i = 0; i < rpc->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200894 yang_print_iffeature(f, level, mnode->module, rpc->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200895 }
896
Michal Vaskof4d3d742015-06-16 11:51:09 +0200897 for (i = 0; i < rpc->tpdf_size; i++) {
898 yang_print_typedef(f, level, mnode->module, &rpc->tpdf[i]);
899 }
900
901 LY_TREE_FOR(mnode->child, sub) {
902 yang_print_mnode(f, level, sub,
903 LY_NODE_GROUPING | LY_NODE_INPUT | LY_NODE_OUTPUT);
904 }
905
906 level--;
907 fprintf(f, "%*s}\n", LEVEL, INDENT);
908}
909
910static void
Michal Vasko7690bc12015-06-16 12:26:05 +0200911yang_print_notif(FILE *f, int level, struct ly_mnode *mnode)
912{
Michal Vaskof4d3d742015-06-16 11:51:09 +0200913 int i;
914 struct ly_mnode *sub;
915 struct ly_mnode_notif *notif = (struct ly_mnode_notif *)mnode;
916
917 fprintf(f, "%*snotification %s {\n", LEVEL, INDENT, mnode->name);
918
919 level++;
920 yang_print_mnode_common(f, level, mnode);
921
Michal Vasko4773b762015-07-07 12:15:10 +0200922 for (i = 0; i < notif->features_size; i++) {
Michal Vaskoc39c4b12015-07-07 14:55:33 +0200923 yang_print_iffeature(f, level, mnode->module, notif->features[i]);
Michal Vasko4773b762015-07-07 12:15:10 +0200924 }
925
Michal Vaskof4d3d742015-06-16 11:51:09 +0200926 for (i = 0; i < notif->tpdf_size; i++) {
927 yang_print_typedef(f, level, mnode->module, &notif->tpdf[i]);
928 }
929
930 LY_TREE_FOR(mnode->child, sub) {
931 yang_print_mnode(f, level, sub,
932 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
933 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
934 }
935
936 level--;
937 fprintf(f, "%*s}\n", LEVEL, INDENT);
938}
939
940static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200941yang_print_mnode(FILE *f, int level, struct ly_mnode *mnode, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200942{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200943 switch (mnode->nodetype & mask) {
944 case LY_NODE_CONTAINER:
945 yang_print_container(f, level, mnode);
946 break;
947 case LY_NODE_CHOICE:
948 yang_print_choice(f, level, mnode);
949 break;
950 case LY_NODE_LEAF:
951 yang_print_leaf(f, level, mnode);
952 break;
953 case LY_NODE_LEAFLIST:
954 yang_print_leaflist(f, level, mnode);
955 break;
956 case LY_NODE_LIST:
957 yang_print_list(f, level, mnode);
958 break;
959 case LY_NODE_USES:
960 yang_print_uses(f, level, mnode);
961 break;
962 case LY_NODE_GROUPING:
963 yang_print_grouping(f, level, mnode);
964 break;
965 case LY_NODE_ANYXML:
966 yang_print_anyxml(f, level, mnode);
967 break;
968 case LY_NODE_CASE:
969 yang_print_case(f, level, mnode);
970 break;
Michal Vaskof4d3d742015-06-16 11:51:09 +0200971 case LY_NODE_INPUT:
972 case LY_NODE_OUTPUT:
973 yang_print_input_output(f, level, mnode);
974 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200975 default:
976 break;
977 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200978}
979
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200980int
Michal Vasko5bbae102015-06-16 12:16:44 +0200981yang_print_model(FILE *f, struct ly_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200982{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200983 unsigned int i;
984 int level = 0;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200985#define LEVEL (level*2)
986
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200987 struct ly_mnode *mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200988
Michal Vasko116172e2015-07-07 11:54:37 +0200989 if (module->type) {
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200990 fprintf(f, "submodule %s {%s\n", module->name, (module->deviated ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +0200991 level++;
992 fprintf(f, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct ly_submodule *)module)->belongsto->name);
993 level++;
994 fprintf(f, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
995 level--;
996 fprintf(f, "%*s}\n", LEVEL, INDENT);
997 } else {
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200998 fprintf(f, "module %s {%s\n", module->name, (module->deviated ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +0200999 level++;
1000 fprintf(f, "%*snamespace \"%s\";\n", LEVEL, INDENT, module->ns);
1001 fprintf(f, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
1002 }
Radek Krejcib0594bf2015-05-21 23:51:27 +02001003
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001004 if (module->version) {
Michal Vasko6c722a62015-07-07 11:54:57 +02001005 fprintf(f, "%*syang-version %s;\n", LEVEL, INDENT, module->version == 1 ? "1" : "1.1");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001006 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001007
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001008 for (i = 0; i < module->imp_size; i++) {
1009 fprintf(f, "%*simport \"%s\" {\n", LEVEL, INDENT, module->imp[i].module->name);
1010 level++;
Michal Vaskoc39c4b12015-07-07 14:55:33 +02001011 fprintf(f, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->imp[i].prefix);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001012 if (module->imp[i].rev[0]) {
1013 yang_print_text(f, level, "revision-date", module->imp[i].rev);
1014 }
1015 level--;
1016 fprintf(f, "%*s}\n", LEVEL, INDENT);
1017 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001018
Michal Vaskoe0af1e22015-07-07 14:02:02 +02001019 for (i = 0; i < module->deviation_size; ++i) {
1020 yang_print_deviation(f, level, module, &module->deviation[i]);
1021 }
1022
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001023 for (i = 0; i < module->inc_size; i++) {
1024 if (module->inc[i].rev[0]) {
1025 fprintf(f, "%*sinclude \"%s\" {\n", LEVEL, INDENT, module->inc[i].submodule->name);
Michal Vasko3d7b8562015-07-07 15:40:34 +02001026 yang_print_text(f, level + 1, "revision-date", module->inc[i].rev);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001027 fprintf(f, "%*s}\n", LEVEL, INDENT);
1028 } else {
1029 fprintf(f, "%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
1030 }
1031 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001032
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001033 if (module->org) {
1034 yang_print_text(f, level, "organization", module->org);
1035 }
1036 if (module->contact) {
1037 yang_print_text(f, level, "contact", module->contact);
1038 }
1039 if (module->dsc) {
1040 yang_print_text(f, level, "description", module->dsc);
1041 }
1042 if (module->ref) {
1043 yang_print_text(f, level, "reference", module->ref);
1044 }
1045 for (i = 0; i < module->rev_size; i++) {
1046 if (module->rev[i].dsc || module->rev[i].ref) {
1047 fprintf(f, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
1048 level++;
1049 if (module->rev[i].dsc) {
1050 yang_print_text(f, level, "description", module->rev[i].dsc);
1051 }
1052 if (module->rev[i].ref) {
1053 yang_print_text(f, level, "reference", module->rev[i].ref);
1054 }
1055 level--;
1056 fprintf(f, "%*s}\n", LEVEL, INDENT);
1057 } else {
1058 yang_print_text(f, level, "revision", module->rev[i].date);
1059 }
1060 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001061
Michal Vasko30f6e912015-07-07 12:24:27 +02001062 for (i = 0; i < module->features_size; i++) {
1063 yang_print_feature(f, level, &module->features[i]);
1064 }
1065
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001066 for (i = 0; i < module->ident_size; i++) {
1067 yang_print_identity(f, level, &module->ident[i]);
1068 }
Radek Krejci6793db02015-05-22 17:49:54 +02001069
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001070 for (i = 0; i < module->tpdf_size; i++) {
1071 yang_print_typedef(f, level, module, &module->tpdf[i]);
1072 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001073
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001074 LY_TREE_FOR(module->data, mnode) {
1075 yang_print_mnode(f, level, mnode,
1076 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
1077 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
1078 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001079
Michal Vasko6f25f212015-07-07 15:42:07 +02001080 for (i = 0; i < module->augment_size; i++) {
1081 yang_print_augment(f, level, module, &module->augment[i]);
1082 }
1083
Michal Vaskof4d3d742015-06-16 11:51:09 +02001084 LY_TREE_FOR(module->rpc, mnode) {
1085 yang_print_rpc(f, level, mnode);
1086 }
1087
1088 LY_TREE_FOR(module->notif, mnode) {
1089 yang_print_notif(f, level, mnode);
1090 }
1091
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001092 fprintf(f, "}\n");
Radek Krejcida04f4a2015-05-21 12:54:09 +02001093
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001094 return EXIT_SUCCESS;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001095#undef LEVEL
1096}