blob: dd1fa0a58744f68e738060094d24c777a435d202 [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 Vaskof0bc7172015-06-09 13:57:05 +0200271 if (cont->presence != NULL) {
272 yang_print_text(f, level, "presence", cont->presence);
273 }
Michal Vasko7f976ee2015-06-09 13:55:41 +0200274
275 for (i = 0; i < cont->must_size; i++) {
276 yang_print_must(f, level, &cont->must[i]);
277 }
278
Radek Krejcida04f4a2015-05-21 12:54:09 +0200279 yang_print_mnode_common2(f, level, mnode);
280
281 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200282 yang_print_typedef(f, level, mnode->module, &cont->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200283 }
284
285 LY_TREE_FOR(mnode->child, sub) {
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200286 yang_print_mnode(f, level, sub, LY_NODE_CHOICE | LY_NODE_CONTAINER |
287 LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
288 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
289 }
290
291 level--;
292 fprintf(f, "%*s}\n", LEVEL, INDENT);
293}
294
295static void yang_print_case(FILE *f, int level, struct ly_mnode *mnode)
296{
297 struct ly_mnode *sub;
298 struct ly_mnode_case *cas = (struct ly_mnode_case *)mnode;
299
300 fprintf(f, "%*scase %s {\n", LEVEL, INDENT, cas->name);
301 level++;
302 yang_print_mnode_common2(f, level, mnode);
303
304 LY_TREE_FOR(mnode->child, sub) {
305 yang_print_mnode(f, level, sub, LY_NODE_CHOICE | LY_NODE_CONTAINER |
306 LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
307 LY_NODE_USES | LY_NODE_ANYXML);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200308 }
309
310 level--;
311 fprintf(f, "%*s}\n", LEVEL, INDENT);
312}
313
314static void yang_print_choice(FILE *f, int level, struct ly_mnode *mnode)
315{
316 struct ly_mnode *sub;
Michal Vasko16083662015-06-09 14:00:45 +0200317 struct ly_mnode_choice *choice = (struct ly_mnode_choice *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200318
319 fprintf(f, "%*schoice %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200320
Radek Krejcida04f4a2015-05-21 12:54:09 +0200321 level++;
Michal Vasko16083662015-06-09 14:00:45 +0200322 if (choice->dflt != NULL) {
323 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, choice->dflt->name);
324 }
325
Radek Krejcida04f4a2015-05-21 12:54:09 +0200326 yang_print_mnode_common2(f, level, mnode);
327 LY_TREE_FOR(mnode->child, sub) {
328 yang_print_mnode(f, level, sub,
329 LY_NODE_CONTAINER | LY_NODE_LEAF |
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200330 LY_NODE_LEAFLIST | LY_NODE_LIST |
331 LY_NODE_ANYXML | LY_NODE_CASE);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200332 }
333 level--;
334 fprintf(f, "%*s}\n", LEVEL, INDENT);
335}
336
337static void yang_print_leaf(FILE *f, int level, struct ly_mnode *mnode)
338{
Michal Vasko16083662015-06-09 14:00:45 +0200339 int i;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200340 struct ly_mnode_leaf *leaf = (struct ly_mnode_leaf *)mnode;
341
342 fprintf(f, "%*sleaf %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200343
Radek Krejcida04f4a2015-05-21 12:54:09 +0200344 level++;
345 yang_print_mnode_common2(f, level, mnode);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200346 for (i = 0; i < leaf->must_size; i++) {
347 yang_print_must(f, level, &leaf->must[i]);
348 }
Radek Krejci04581c62015-05-22 21:24:00 +0200349 yang_print_type(f, level, mnode->module, &leaf->type);
Michal Vasko16083662015-06-09 14:00:45 +0200350 if (leaf->units != NULL) {
351 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, leaf->units);
352 }
353 if (leaf->dflt != NULL) {
354 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, leaf->dflt);
355 }
356 level--;
357
358 fprintf(f, "%*s}\n", LEVEL, INDENT);
359}
360
361static void yang_print_anyxml(FILE *f, int level, struct ly_mnode *mnode)
362{
363 int i;
364 struct ly_mnode_anyxml *anyxml = (struct ly_mnode_anyxml *)mnode;
365
366 fprintf(f, "%*sanyxml %s {\n", LEVEL, INDENT, anyxml->name);
367 level++;
368 yang_print_mnode_common2(f, level, mnode);
369 for (i = 0; i < anyxml->must_size; i++) {
370 yang_print_must(f, level, &anyxml->must[i]);
371 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200372 level--;
373 fprintf(f, "%*s}\n", LEVEL, INDENT);
374}
375
376static void yang_print_leaflist(FILE *f, int level, struct ly_mnode *mnode)
377{
Michal Vasko16083662015-06-09 14:00:45 +0200378 int i;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200379 struct ly_mnode_leaflist *llist = (struct ly_mnode_leaflist *)mnode;
380
381 fprintf(f, "%*sleaf-list %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200382
Radek Krejcida04f4a2015-05-21 12:54:09 +0200383 level++;
384 yang_print_mnode_common2(f, level, mnode);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200385 for (i = 0; i < llist->must_size; i++) {
386 yang_print_must(f, level, &llist->must[i]);
387 }
Radek Krejci04581c62015-05-22 21:24:00 +0200388 yang_print_type(f, level, mnode->module, &llist->type);
Michal Vasko16083662015-06-09 14:00:45 +0200389 if (llist->units != NULL) {
390 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, llist->units);
391 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200392 level--;
Michal Vasko16083662015-06-09 14:00:45 +0200393
Radek Krejcida04f4a2015-05-21 12:54:09 +0200394 fprintf(f, "%*s}\n", LEVEL, INDENT);
395}
396
397static void yang_print_list(FILE *f, int level, struct ly_mnode *mnode)
398{
Michal Vasko16083662015-06-09 14:00:45 +0200399 int i, j;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200400 struct ly_mnode *sub;
Michal Vasko16083662015-06-09 14:00:45 +0200401 struct ly_unique *uniq;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200402 struct ly_mnode_list *list = (struct ly_mnode_list *)mnode;
403
404 fprintf(f, "%*slist %s {\n", LEVEL, INDENT, mnode->name);
405 level++;
406 yang_print_mnode_common2(f, level, mnode);
407
Radek Krejcid7f0d012015-05-25 15:04:52 +0200408 if (list->keys_size) {
409 fprintf(f, "%*skey \"", LEVEL, INDENT);
410 for (i = 0; i < list->keys_size; i++) {
411 fprintf(f, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "");
412 }
413 fprintf(f, "\";\n");
414 }
415
Radek Krejcida04f4a2015-05-21 12:54:09 +0200416 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200417 yang_print_typedef(f, level, list->module, &list->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200418 }
419
420 LY_TREE_FOR(mnode->child, sub) {
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200421 yang_print_mnode(f, level, sub, LY_NODE_CHOICE | LY_NODE_CONTAINER |
422 LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
423 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200424 }
425 level--;
426 fprintf(f, "%*s}\n", LEVEL, INDENT);
427}
428
429static void yang_print_grouping(FILE *f, int level, struct ly_mnode *mnode)
430{
431 int i;
432 struct ly_mnode *node;
433 struct ly_mnode_grp *grp = (struct ly_mnode_grp *)mnode;
434
435 fprintf(f, "%*sgrouping %s {\n", LEVEL, INDENT, mnode->name);
436 level++;
437
438 yang_print_mnode_common(f, level, mnode);
439
440 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200441 yang_print_typedef(f, level, mnode->module, &grp->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200442 }
443
444 LY_TREE_FOR(mnode->child, node) {
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200445 yang_print_mnode(f, level, node, LY_NODE_CHOICE | LY_NODE_CONTAINER |
446 LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
447 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200448 }
449
450 level--;
451 fprintf(f, "%*s}\n", LEVEL, INDENT);
452}
453
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200454static void yang_print_uses(FILE *f, int level, struct ly_mnode *mnode)
455{
Michal Vasko16083662015-06-09 14:00:45 +0200456 int i;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200457 struct ly_mnode_uses *uses = (struct ly_mnode_uses *)mnode;
458
459 fprintf(f, "%*suses %s {\n", LEVEL, INDENT, uses->name);
460 level++;
461
462 yang_print_mnode_common(f, level, mnode);
463
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200464 for (i = 0; i < uses->refine_size; i++) {
465 yang_print_refine(f, level, &uses->refine[i]);
466 }
467
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200468 level--;
469 fprintf(f, "%*s}\n", LEVEL, INDENT);
470}
471
Radek Krejcida04f4a2015-05-21 12:54:09 +0200472static void yang_print_mnode(FILE *f, int level, struct ly_mnode *mnode,
473 int mask)
474{
475 switch(mnode->nodetype & mask) {
476 case LY_NODE_CONTAINER:
477 yang_print_container(f, level, mnode);
478 break;
479 case LY_NODE_CHOICE:
480 yang_print_choice(f, level, mnode);
481 break;
482 case LY_NODE_LEAF:
483 yang_print_leaf(f, level, mnode);
484 break;
485 case LY_NODE_LEAFLIST:
486 yang_print_leaflist(f, level, mnode);
487 break;
488 case LY_NODE_LIST:
489 yang_print_list(f, level, mnode);
490 break;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200491 case LY_NODE_USES:
492 yang_print_uses(f, level, mnode);
493 break;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200494 case LY_NODE_GROUPING:
495 yang_print_grouping(f, level, mnode);
496 break;
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200497 case LY_NODE_ANYXML:
498 yang_print_anyxml(f, level, mnode);
499 break;
500 case LY_NODE_CASE:
501 yang_print_case(f, level, mnode);
502 break;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200503 default: break;
504 }
505}
506
Radek Krejciefdd0ce2015-05-26 16:48:29 +0200507int yang_print_model(FILE *f, struct ly_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200508{
Radek Krejcice7fb782015-05-29 16:52:34 +0200509 unsigned int i;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200510 int level = 0;
511#define LEVEL (level*2)
512
513 struct ly_mnode *mnode;
514
Radek Krejcida04f4a2015-05-21 12:54:09 +0200515 fprintf(f, "module %s {\n", module->name);
516 level++;
Radek Krejcib0594bf2015-05-21 23:51:27 +0200517
Radek Krejcida04f4a2015-05-21 12:54:09 +0200518 fprintf(f, "%*snamespace \"%s\";\n", LEVEL, INDENT, module->ns);
519 fprintf(f, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
Radek Krejcib0594bf2015-05-21 23:51:27 +0200520
521 if (module->version) {
522 fprintf(f, "%*syang-version \"%s\";\n", LEVEL, INDENT, module->version == 1 ? "1.0" : "1.1");
523 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200524
525 for (i = 0; i < module->imp_size; i++) {
526 fprintf(f, "%*simport \"%s\" {\n", LEVEL, INDENT,
527 module->imp[i].module->name);
528 level++;
529 yang_print_text(f, level, "prefix", module->imp[i].prefix);
530 if (module->imp[i].rev[0]) {
531 yang_print_text(f, level, "revision-date", module->imp[i].rev);
532 }
533 level--;
534 fprintf(f, "%*s}\n", LEVEL, INDENT);
535 }
536
Radek Krejciefaeba32015-05-27 14:30:57 +0200537 for (i = 0; i < module->inc_size; i++) {
538 if (module->inc[i].rev[0]) {
539 fprintf(f, "%*sinclude \"%s\" {\n", LEVEL, INDENT,
540 module->inc[i].submodule->name);
541 yang_print_text(f, level + 1, "revision-date", module->imp[i].rev);
542 fprintf(f, "%*s}\n", LEVEL, INDENT);
543 } else {
544 fprintf(f, "%*sinclude \"%s\";\n", LEVEL, INDENT,
545 module->inc[i].submodule->name);
546 }
547 }
548
Radek Krejcida04f4a2015-05-21 12:54:09 +0200549 if (module->org) {
550 yang_print_text(f, level, "organization", module->org);
551 }
552 if (module->contact) {
553 yang_print_text(f, level, "contact", module->contact);
554 }
555 if (module->dsc) {
556 yang_print_text(f, level, "description", module->dsc);
557 }
558 if (module->ref) {
559 yang_print_text(f, level, "reference", module->ref);
560 }
561 for (i = 0; i < module->rev_size; i++) {
562 if (module->rev[i].dsc || module->rev[i].ref) {
563 fprintf(f, "%*srevision \"%s\" {\n", LEVEL, INDENT,
564 module->rev[i].date);
565 level++;
566 if (module->rev[i].dsc) {
567 yang_print_text(f, level, "description", module->rev[i].dsc);
568 }
569 if (module->rev[i].ref) {
570 yang_print_text(f, level, "reference", module->rev[i].ref);
571 }
572 level--;
573 fprintf(f, "%*s}\n", LEVEL, INDENT);
574 } else {
575 yang_print_text(f, level, "revision", module->rev[i].date);
576 }
577 }
578
Radek Krejci6793db02015-05-22 17:49:54 +0200579 for (i = 0; i < module->ident_size; i++) {
580 yang_print_identity(f, level, &module->ident[i]);
581 }
582
Radek Krejcida04f4a2015-05-21 12:54:09 +0200583 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci04581c62015-05-22 21:24:00 +0200584 yang_print_typedef(f, level, module, &module->tpdf[i]);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200585 }
586
587 LY_TREE_FOR(module->data, mnode) {
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200588 yang_print_mnode(f, level, mnode, LY_NODE_CHOICE | LY_NODE_CONTAINER |
589 LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
590 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200591 }
592
593 fprintf(f, "}\n");
594
595 return EXIT_SUCCESS;
596#undef LEVEL
597}