blob: 8bebbfae1e60dfde691dbbbfd5db61e18e4efa11 [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
32static void yang_print_mnode(FILE *f, int level, struct ly_mnode *mnode,
33 int mask);
34
35static void yang_print_text(FILE *f, int level, const char *name,
36 const char *text)
37{
38 const char *s, *t;
39
40 fprintf(f, "%*s%s\n", LEVEL, INDENT, name);
41 level++;
42
43 fprintf(f, "%*s\"", LEVEL, INDENT);
44 t = text;
45 while((s = strchr(t, '\n'))) {
46 fwrite(t, sizeof *t, s - t + 1, f);
47 t = s + 1;
48 fprintf(f, "%*s", LEVEL, INDENT);
49 }
50
51 fprintf(f, "%s\";\n\n", t);
52 level--;
53
54}
55
56/*
57 * Covers:
58 * description, reference, status
59 */
60static void yang_print_mnode_common(FILE *f, int level, struct ly_mnode *mnode)
61{
62 if (mnode->flags & LY_NODE_STATUS_CURR) {
63 fprintf(f, "%*sstatus \"current\";\n", LEVEL, INDENT);
64 } else if (mnode->flags & LY_NODE_STATUS_DEPRC) {
65 fprintf(f, "%*sstatus \"deprecated\";\n", LEVEL, INDENT);
66 } else if (mnode->flags & LY_NODE_STATUS_OBSLT) {
67 fprintf(f, "%*sstatus \"obsolete\";\n", LEVEL, INDENT);
68 }
69
70 if (mnode->dsc) {
71 yang_print_text(f, level, "description", mnode->dsc);
72 }
73 if (mnode->ref) {
74 yang_print_text(f, level, "reference", mnode->ref);
75 }
76}
77
78/*
79 * Covers:
Michal Vasko2b8faed2015-06-09 12:51:20 +020080 * config, mandatory
Radek Krejcida04f4a2015-05-21 12:54:09 +020081 * description, reference, status
82 */
83static void yang_print_mnode_common2(FILE *f, int level, struct ly_mnode *mnode)
84{
85 if (!mnode->parent || (mnode->parent->flags & LY_NODE_CONFIG_MASK) != (mnode->flags & LY_NODE_CONFIG_MASK)) {
86 /* print config only when it differs from the parent or in root */
87 if (mnode->flags & LY_NODE_CONFIG_W) {
88 fprintf(f, "%*sconfig \"true\";\n", LEVEL, INDENT);
89 } else if (mnode->flags & LY_NODE_CONFIG_R) {
90 fprintf(f, "%*sconfig \"false\";\n", LEVEL, INDENT);
91 }
92 }
93
Michal Vasko2b8faed2015-06-09 12:51:20 +020094 if (mnode->flags & LY_NODE_MAND_TRUE) {
95 fprintf(f, "%*smandatory \"true\";\n", LEVEL, INDENT);
96 } else if (mnode->flags & LY_NODE_MAND_FALSE) {
97 fprintf(f, "%*smandatory \"false\";\n", LEVEL, INDENT);
98 }
99
Radek Krejcida04f4a2015-05-21 12:54:09 +0200100 yang_print_mnode_common(f, level, mnode);
101}
102
Radek Krejci04581c62015-05-22 21:24:00 +0200103static void yang_print_type(FILE *f, int level, struct ly_module *module, struct ly_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200104{
Radek Krejci25d782a2015-05-22 15:03:23 +0200105 int i;
106
107 if (type->prefix) {
108 fprintf(f, "%*stype %s:%s {\n", LEVEL, INDENT, type->prefix, type->der->name);
109 } else {
110 fprintf(f, "%*stype %s {\n", LEVEL, INDENT, type->der->name);
111 }
112 level++;
113 switch (type->base) {
Michal Vaskoc822f3d2015-06-09 12:52:12 +0200114 case LY_TYPE_BINARY:
115 if (type->info.binary.length != NULL) {
116 fprintf(f, "%*slength \"%s\";\n", LEVEL, INDENT, type->info.binary.length);
117 }
118 break;
119 case LY_TYPE_BITS:
120 /* TODO */
121 break;
122 case LY_TYPE_DEC64:
123 /* TODO */
124 break;
Radek Krejci25d782a2015-05-22 15:03:23 +0200125 case LY_TYPE_ENUM:
126 for (i = 0; i < type->info.enums.count; i++) {
127 fprintf(f, "%*senum %s {\n", LEVEL, INDENT, type->info.enums.list[i].name);
128 level++;
129 yang_print_mnode_common(f, level, (struct ly_mnode *)&type->info.enums.list[i]);
130 fprintf(f, "%*svalue %d;\n", LEVEL, INDENT, type->info.enums.list[i].value);
131 level--;
132 fprintf(f, "%*s}\n", LEVEL, INDENT);
133 }
134 break;
Radek Krejci04581c62015-05-22 21:24:00 +0200135 case LY_TYPE_IDENT:
136 if (module == type->info.ident.ref->module) {
137 fprintf(f, "%*sbase %s;\n", LEVEL, INDENT, type->info.ident.ref->name);
138 } else {
139 fprintf(f, "%*sbase %s:%s;\n", LEVEL, INDENT, type->info.ident.ref->module->prefix, type->info.ident.ref->name);
140 }
141 break;
Michal Vaskoc822f3d2015-06-09 12:52:12 +0200142 case LY_TYPE_INST:
143 /* TODO */
144 break;
145 case LY_TYPE_INT8:
146 case LY_TYPE_INT16:
147 case LY_TYPE_INT32:
148 case LY_TYPE_INT64:
149 case LY_TYPE_UINT8:
150 case LY_TYPE_UINT16:
151 case LY_TYPE_UINT32:
152 case LY_TYPE_UINT64:
153 if (type->info.num.range != NULL) {
154 fprintf(f, "%*srange \"%s\";\n", LEVEL, INDENT, type->info.num.range);
155 }
156 break;
157 case LY_TYPE_LEAFREF:
158 /* TODO */
159 break;
160 case LY_TYPE_STRING:
161 /* TODO */
162 break;
163 case LY_TYPE_UNION:
164 /* TODO */
165 break;
Radek Krejci25d782a2015-05-22 15:03:23 +0200166 default:
Michal Vaskoc822f3d2015-06-09 12:52:12 +0200167 /* other types do not have substatements */
Radek Krejci25d782a2015-05-22 15:03:23 +0200168 break;
169 }
170 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200171 fprintf(f, "%*s}\n", LEVEL, INDENT);
172}
173
Michal Vasko7f976ee2015-06-09 13:55:41 +0200174static void yang_print_must(FILE *f, int level, struct ly_must *must)
175{
176 fprintf(f, "%*smust \"%s\" {\n", LEVEL, INDENT, must->cond);
177 level++;
178
179 if (must->eapptag != NULL) {
180 fprintf(f, "%*serror-app-tag \"%s\";\n", LEVEL, INDENT, must->eapptag);
181 }
182
183 if (must->emsg != NULL) {
184 yang_print_text(f, level, "error-message", must->emsg);
185 }
186 if (must->dsc != NULL) {
187 yang_print_text(f, level, "description", must->dsc);
188 }
189 if (must->ref != NULL) {
190 yang_print_text(f, level, "reference", must->ref);
191 }
192
193 level--;
194 fprintf(f, "%*s}\n", LEVEL, INDENT);
195}
196
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200197static void yang_print_refine(FILE *f, int level, struct ly_refine *refine)
198{
199 int i;
200
201 fprintf(f, "%*srefine \"%s\" {\n", LEVEL, INDENT, refine->target);
202 level++;
203
204 yang_print_mnode_common2(f, level, (struct ly_mnode *)refine);
205
206 for (i = 0; i < refine->must_size; ++i) {
207 yang_print_must(f, level, &refine->must[i]);
208 }
209
210 if (refine->target_type & (LY_NODE_LEAF | LY_NODE_CHOICE)) {
211 if (refine->mod.dflt != NULL) {
212 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, refine->mod.dflt);
213 }
214 } else if (refine->target_type == LY_NODE_CONTAINER) {
215 if (refine->mod.presence != NULL) {
216 yang_print_text(f, level, "presence", refine->mod.presence);
217 }
218 } else if (refine->target_type & (LY_NODE_LIST | LY_NODE_LEAFLIST)) {
219 if (refine->mod.list.min > 0) {
220 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, refine->mod.list.min);
221 }
222 if (refine->mod.list.max > 0) {
223 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, refine->mod.list.max);
224 }
225 }
226
227 level--;
228 fprintf(f, "%*s}\n", LEVEL, INDENT);
229}
230
Radek Krejci04581c62015-05-22 21:24:00 +0200231static void yang_print_typedef(FILE *f, int level, struct ly_module *module, struct ly_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200232{
233 fprintf(f, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
234 level++;
235
236 yang_print_mnode_common(f, level, (struct ly_mnode *)tpdf);
Radek Krejci04581c62015-05-22 21:24:00 +0200237 yang_print_type(f, level, module, &tpdf->type);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200238
239 level--;
240 fprintf(f, "%*s}\n", LEVEL, INDENT);
241}
242
Radek Krejci6793db02015-05-22 17:49:54 +0200243static void yang_print_identity(FILE *f, int level, struct ly_ident *ident)
244{
245 fprintf(f, "%*sidentity %s {\n", LEVEL, INDENT, ident->name);
246 level++;
247
248 yang_print_mnode_common(f, level, (struct ly_mnode *)ident);
249 if (ident->base) {
250 if (ident->base->module == ident->module) {
251 fprintf(f, "%*sbase %s;\n", LEVEL, INDENT, ident->base->name);
252 } else {
253 fprintf(f, "%*sbase %s:%s;\n", LEVEL, INDENT, ident->base->module->prefix, ident->base->name);
254 }
255 }
256
257 level--;
258 fprintf(f, "%*s}\n", LEVEL, INDENT);
259
260}
261
Radek Krejcida04f4a2015-05-21 12:54:09 +0200262static void yang_print_container(FILE *f, int level, struct ly_mnode *mnode)
263{
264 int i;
265 struct ly_mnode *sub;
266 struct ly_mnode_container *cont = (struct ly_mnode_container *)mnode;
267
268 fprintf(f, "%*scontainer %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200269
Radek Krejcida04f4a2015-05-21 12:54:09 +0200270 level++;
Michal Vasko7f976ee2015-06-09 13:55:41 +0200271
272 for (i = 0; i < cont->must_size; i++) {
273 yang_print_must(f, level, &cont->must[i]);
274 }
275
Radek Krejcida04f4a2015-05-21 12:54:09 +0200276 yang_print_mnode_common2(f, level, mnode);
277
278 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200279 yang_print_typedef(f, level, mnode->module, &cont->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200280 }
281
282 LY_TREE_FOR(mnode->child, sub) {
283 yang_print_mnode(f, level, sub, LY_NODE_CHOICE |LY_NODE_CONTAINER |
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200284 LY_NODE_LEAF |LY_NODE_LEAFLIST | LY_NODE_LIST |
285 LY_NODE_USES | LY_NODE_GROUPING);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200286 }
287
288 level--;
289 fprintf(f, "%*s}\n", LEVEL, INDENT);
290}
291
292static void yang_print_choice(FILE *f, int level, struct ly_mnode *mnode)
293{
294 struct ly_mnode *sub;
295
296 fprintf(f, "%*schoice %s {\n", LEVEL, INDENT, mnode->name);
297 level++;
298 yang_print_mnode_common2(f, level, mnode);
299 LY_TREE_FOR(mnode->child, sub) {
300 yang_print_mnode(f, level, sub,
301 LY_NODE_CONTAINER | LY_NODE_LEAF |
302 LY_NODE_LEAFLIST | LY_NODE_LIST);
303 }
304 level--;
305 fprintf(f, "%*s}\n", LEVEL, INDENT);
306}
307
308static void yang_print_leaf(FILE *f, int level, struct ly_mnode *mnode)
309{
310 struct ly_mnode_leaf *leaf = (struct ly_mnode_leaf *)mnode;
311
312 fprintf(f, "%*sleaf %s {\n", LEVEL, INDENT, mnode->name);
313 level++;
314 yang_print_mnode_common2(f, level, mnode);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200315 for (i = 0; i < leaf->must_size; i++) {
316 yang_print_must(f, level, &leaf->must[i]);
317 }
Radek Krejci04581c62015-05-22 21:24:00 +0200318 yang_print_type(f, level, mnode->module, &leaf->type);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200319 level--;
320 fprintf(f, "%*s}\n", LEVEL, INDENT);
321}
322
323static void yang_print_leaflist(FILE *f, int level, struct ly_mnode *mnode)
324{
325 struct ly_mnode_leaflist *llist = (struct ly_mnode_leaflist *)mnode;
326
327 fprintf(f, "%*sleaf-list %s {\n", LEVEL, INDENT, mnode->name);
328 level++;
329 yang_print_mnode_common2(f, level, mnode);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200330 for (i = 0; i < llist->must_size; i++) {
331 yang_print_must(f, level, &llist->must[i]);
332 }
Radek Krejci04581c62015-05-22 21:24:00 +0200333 yang_print_type(f, level, mnode->module, &llist->type);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200334 level--;
335 fprintf(f, "%*s}\n", LEVEL, INDENT);
336}
337
338static void yang_print_list(FILE *f, int level, struct ly_mnode *mnode)
339{
340 int i;
341 struct ly_mnode *sub;
342 struct ly_mnode_list *list = (struct ly_mnode_list *)mnode;
343
344 fprintf(f, "%*slist %s {\n", LEVEL, INDENT, mnode->name);
345 level++;
346 yang_print_mnode_common2(f, level, mnode);
347
Radek Krejcid7f0d012015-05-25 15:04:52 +0200348 if (list->keys_size) {
349 fprintf(f, "%*skey \"", LEVEL, INDENT);
350 for (i = 0; i < list->keys_size; i++) {
351 fprintf(f, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "");
352 }
353 fprintf(f, "\";\n");
354 }
355
Radek Krejcida04f4a2015-05-21 12:54:09 +0200356 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200357 yang_print_typedef(f, level, list->module, &list->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200358 }
359
360 LY_TREE_FOR(mnode->child, sub) {
361 yang_print_mnode(f, level, sub, LY_NODE_CHOICE |LY_NODE_CONTAINER |
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200362 LY_NODE_LEAF |LY_NODE_LEAFLIST | LY_NODE_LIST |
363 LY_NODE_USES | LY_NODE_GROUPING);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200364 }
365 level--;
366 fprintf(f, "%*s}\n", LEVEL, INDENT);
367}
368
369static void yang_print_grouping(FILE *f, int level, struct ly_mnode *mnode)
370{
371 int i;
372 struct ly_mnode *node;
373 struct ly_mnode_grp *grp = (struct ly_mnode_grp *)mnode;
374
375 fprintf(f, "%*sgrouping %s {\n", LEVEL, INDENT, mnode->name);
376 level++;
377
378 yang_print_mnode_common(f, level, mnode);
379
380 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200381 yang_print_typedef(f, level, mnode->module, &grp->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200382 }
383
384 LY_TREE_FOR(mnode->child, node) {
385 yang_print_mnode(f, level, node, LY_NODE_CHOICE |LY_NODE_CONTAINER |
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200386 LY_NODE_LEAF |LY_NODE_LEAFLIST | LY_NODE_LIST |
387 LY_NODE_USES | LY_NODE_GROUPING);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200388 }
389
390 level--;
391 fprintf(f, "%*s}\n", LEVEL, INDENT);
392}
393
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200394static void yang_print_uses(FILE *f, int level, struct ly_mnode *mnode)
395{
396 struct ly_mnode_uses *uses = (struct ly_mnode_uses *)mnode;
397
398 fprintf(f, "%*suses %s {\n", LEVEL, INDENT, uses->name);
399 level++;
400
401 yang_print_mnode_common(f, level, mnode);
402
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200403 for (i = 0; i < uses->refine_size; i++) {
404 yang_print_refine(f, level, &uses->refine[i]);
405 }
406
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200407 level--;
408 fprintf(f, "%*s}\n", LEVEL, INDENT);
409}
410
Radek Krejcida04f4a2015-05-21 12:54:09 +0200411static void yang_print_mnode(FILE *f, int level, struct ly_mnode *mnode,
412 int mask)
413{
414 switch(mnode->nodetype & mask) {
415 case LY_NODE_CONTAINER:
416 yang_print_container(f, level, mnode);
417 break;
418 case LY_NODE_CHOICE:
419 yang_print_choice(f, level, mnode);
420 break;
421 case LY_NODE_LEAF:
422 yang_print_leaf(f, level, mnode);
423 break;
424 case LY_NODE_LEAFLIST:
425 yang_print_leaflist(f, level, mnode);
426 break;
427 case LY_NODE_LIST:
428 yang_print_list(f, level, mnode);
429 break;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200430 case LY_NODE_USES:
431 yang_print_uses(f, level, mnode);
432 break;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200433 case LY_NODE_GROUPING:
434 yang_print_grouping(f, level, mnode);
435 break;
436 default: break;
437 }
438}
439
Radek Krejciefdd0ce2015-05-26 16:48:29 +0200440int yang_print_model(FILE *f, struct ly_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200441{
Radek Krejcice7fb782015-05-29 16:52:34 +0200442 unsigned int i;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200443 int level = 0;
444#define LEVEL (level*2)
445
446 struct ly_mnode *mnode;
447
Radek Krejcida04f4a2015-05-21 12:54:09 +0200448 fprintf(f, "module %s {\n", module->name);
449 level++;
Radek Krejcib0594bf2015-05-21 23:51:27 +0200450
Radek Krejcida04f4a2015-05-21 12:54:09 +0200451 fprintf(f, "%*snamespace \"%s\";\n", LEVEL, INDENT, module->ns);
452 fprintf(f, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
Radek Krejcib0594bf2015-05-21 23:51:27 +0200453
454 if (module->version) {
455 fprintf(f, "%*syang-version \"%s\";\n", LEVEL, INDENT, module->version == 1 ? "1.0" : "1.1");
456 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200457
458 for (i = 0; i < module->imp_size; i++) {
459 fprintf(f, "%*simport \"%s\" {\n", LEVEL, INDENT,
460 module->imp[i].module->name);
461 level++;
462 yang_print_text(f, level, "prefix", module->imp[i].prefix);
463 if (module->imp[i].rev[0]) {
464 yang_print_text(f, level, "revision-date", module->imp[i].rev);
465 }
466 level--;
467 fprintf(f, "%*s}\n", LEVEL, INDENT);
468 }
469
Radek Krejciefaeba32015-05-27 14:30:57 +0200470 for (i = 0; i < module->inc_size; i++) {
471 if (module->inc[i].rev[0]) {
472 fprintf(f, "%*sinclude \"%s\" {\n", LEVEL, INDENT,
473 module->inc[i].submodule->name);
474 yang_print_text(f, level + 1, "revision-date", module->imp[i].rev);
475 fprintf(f, "%*s}\n", LEVEL, INDENT);
476 } else {
477 fprintf(f, "%*sinclude \"%s\";\n", LEVEL, INDENT,
478 module->inc[i].submodule->name);
479 }
480 }
481
Radek Krejcida04f4a2015-05-21 12:54:09 +0200482 if (module->org) {
483 yang_print_text(f, level, "organization", module->org);
484 }
485 if (module->contact) {
486 yang_print_text(f, level, "contact", module->contact);
487 }
488 if (module->dsc) {
489 yang_print_text(f, level, "description", module->dsc);
490 }
491 if (module->ref) {
492 yang_print_text(f, level, "reference", module->ref);
493 }
494 for (i = 0; i < module->rev_size; i++) {
495 if (module->rev[i].dsc || module->rev[i].ref) {
496 fprintf(f, "%*srevision \"%s\" {\n", LEVEL, INDENT,
497 module->rev[i].date);
498 level++;
499 if (module->rev[i].dsc) {
500 yang_print_text(f, level, "description", module->rev[i].dsc);
501 }
502 if (module->rev[i].ref) {
503 yang_print_text(f, level, "reference", module->rev[i].ref);
504 }
505 level--;
506 fprintf(f, "%*s}\n", LEVEL, INDENT);
507 } else {
508 yang_print_text(f, level, "revision", module->rev[i].date);
509 }
510 }
511
Radek Krejci6793db02015-05-22 17:49:54 +0200512 for (i = 0; i < module->ident_size; i++) {
513 yang_print_identity(f, level, &module->ident[i]);
514 }
515
Radek Krejcida04f4a2015-05-21 12:54:09 +0200516 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200517 yang_print_typedef(f, level, module, &module->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200518 }
519
520 LY_TREE_FOR(module->data, mnode) {
521 yang_print_mnode(f, level, mnode, LY_NODE_CHOICE |LY_NODE_CONTAINER |
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200522 LY_NODE_LEAF |LY_NODE_LEAFLIST | LY_NODE_LIST |
523 LY_NODE_USES | LY_NODE_GROUPING);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200524 }
525
526 fprintf(f, "}\n");
527
528 return EXIT_SUCCESS;
529#undef LEVEL
530}