blob: e832249a62cf4c1b9f0b695354ae1bf35a803cc0 [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
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020034static void
Michal Vasko5bbae102015-06-16 12:16:44 +020035yang_print_text(FILE *f, int level, const char *name, const char *text)
Radek Krejcida04f4a2015-05-21 12:54:09 +020036{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020037 const char *s, *t;
Radek Krejcida04f4a2015-05-21 12:54:09 +020038
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020039 fprintf(f, "%*s%s\n", LEVEL, INDENT, name);
40 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +020041
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020042 fprintf(f, "%*s\"", LEVEL, INDENT);
43 t = text;
44 while ((s = strchr(t, '\n'))) {
Michal Vasko5bbae102015-06-16 12:16:44 +020045 fwrite(t, sizeof *t, (s - t) + 1, f);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020046 t = s + 1;
47 fprintf(f, "%*s", LEVEL, INDENT);
48 }
Radek Krejcida04f4a2015-05-21 12:54:09 +020049
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020050 fprintf(f, "%s\";\n\n", t);
51 level--;
Radek Krejcida04f4a2015-05-21 12:54:09 +020052
53}
54
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020055static void
Radek Krejci6a113852015-07-03 16:04:20 +020056yang_print_nacmext(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +020057{
Radek Krejci6764bb32015-07-03 15:16:04 +020058 int i, j;
Radek Krejci86909d22015-07-03 16:11:25 +020059 const char *prefix = NULL;
Radek Krejci6764bb32015-07-03 15:16:04 +020060
61 if (mnode->nacm && (!mnode->parent || mnode->parent->nacm != mnode->nacm)) {
62 /* locate ietf-netconf-acm module in imports */
63 if (!strcmp(mnode->module->name, "ietf-netconf-acm")) {
64 prefix = mnode->module->prefix;
65 } else {
66 /* search in imports */
67 for (i = 0; i < mnode->module->imp_size; i++) {
68 if (!strcmp(mnode->module->imp[i].module->name, "ietf-netconf-acm")) {
69 prefix = mnode->module->imp[i].prefix;
70 break;
71 }
72 }
73 /* and in imports of includes */
74 if (!prefix) {
75 for (j = 0; j < mnode->module->inc_size; j++) {
76 for (i = 0; i < mnode->module->inc[j].submodule->imp_size; i++) {
77 if (!strcmp(mnode->module->inc[j].submodule->imp[i].module->name, "ietf-netconf-acm")) {
78 prefix = mnode->module->inc[j].submodule->imp[i].prefix;
79 break;
80 }
81 }
82 }
83 }
84 }
85
86 if ((mnode->nacm & LY_NACM_DENYW) && (!mnode->parent || !(mnode->parent->nacm & LY_NACM_DENYW))) {
87 fprintf(f, "%*s%s:default-deny-write;\n", LEVEL, INDENT, prefix);
88 }
89 if ((mnode->nacm & LY_NACM_DENYA) && (!mnode->parent || !(mnode->parent->nacm & LY_NACM_DENYA))) {
90 fprintf(f, "%*s%s:default-deny-all;\n", LEVEL, INDENT, prefix);
91 }
92 }
Radek Krejci6a113852015-07-03 16:04:20 +020093}
94
95/*
96 * Covers:
97 * description, reference, status
98 */
99static void
100yang_print_mnode_common(FILE *f, int level, struct ly_mnode *mnode)
101{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200102 if (mnode->flags & LY_NODE_STATUS_CURR) {
103 fprintf(f, "%*sstatus \"current\";\n", LEVEL, INDENT);
104 } else if (mnode->flags & LY_NODE_STATUS_DEPRC) {
105 fprintf(f, "%*sstatus \"deprecated\";\n", LEVEL, INDENT);
106 } else if (mnode->flags & LY_NODE_STATUS_OBSLT) {
107 fprintf(f, "%*sstatus \"obsolete\";\n", LEVEL, INDENT);
108 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200109
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200110 if (mnode->dsc) {
111 yang_print_text(f, level, "description", mnode->dsc);
112 }
113 if (mnode->ref) {
114 yang_print_text(f, level, "reference", mnode->ref);
115 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200116}
117
118/*
119 * Covers:
Michal Vasko2b8faed2015-06-09 12:51:20 +0200120 * config, mandatory
Radek Krejcida04f4a2015-05-21 12:54:09 +0200121 * description, reference, status
122 */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200123static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200124yang_print_mnode_common2(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200125{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200126 if (!mnode->parent || (mnode->parent->flags & LY_NODE_CONFIG_MASK) != (mnode->flags & LY_NODE_CONFIG_MASK)) {
127 /* print config only when it differs from the parent or in root */
128 if (mnode->flags & LY_NODE_CONFIG_W) {
129 fprintf(f, "%*sconfig \"true\";\n", LEVEL, INDENT);
130 } else if (mnode->flags & LY_NODE_CONFIG_R) {
131 fprintf(f, "%*sconfig \"false\";\n", LEVEL, INDENT);
132 }
133 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200134
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200135 if (mnode->flags & LY_NODE_MAND_TRUE) {
136 fprintf(f, "%*smandatory \"true\";\n", LEVEL, INDENT);
137 } else if (mnode->flags & LY_NODE_MAND_FALSE) {
138 fprintf(f, "%*smandatory \"false\";\n", LEVEL, INDENT);
139 }
Michal Vasko2b8faed2015-06-09 12:51:20 +0200140
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200141 yang_print_mnode_common(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200142}
143
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200144static void
Michal Vasko4773b762015-07-07 12:15:10 +0200145yang_print_feature(FILE *f, int level, struct ly_feature *feat)
146{
Michal Vasko30f6e912015-07-07 12:24:27 +0200147 int i;
148
Michal Vasko4773b762015-07-07 12:15:10 +0200149 fprintf(f, "%*sfeature %s {\n", LEVEL, INDENT, feat->name);
150 level++;
151
Michal Vasko30f6e912015-07-07 12:24:27 +0200152 yang_print_mnode_common(f, level, (struct ly_mnode *)feat);
153 for (i = 0; i < feat->features_size; ++i) {
154 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, feat->features[i]->name);
155 }
Michal Vasko4773b762015-07-07 12:15:10 +0200156
157 level--;
158 fprintf(f, "%*s}\n", LEVEL, INDENT);
159}
160
161static void
Radek Krejci0bd5db42015-06-19 13:30:07 +0200162yang_print_restr(FILE *f, int level, struct ly_restr *restr)
Radek Krejci41726f92015-06-19 13:11:05 +0200163{
Radek Krejci0bd5db42015-06-19 13:30:07 +0200164 if (restr->dsc != NULL) {
165 yang_print_text(f, level, "description", restr->dsc);
Radek Krejci41726f92015-06-19 13:11:05 +0200166 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200167 if (restr->ref != NULL) {
168 yang_print_text(f, level, "reference", restr->ref);
Radek Krejci41726f92015-06-19 13:11:05 +0200169 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200170 if (restr->eapptag != NULL) {
171 fprintf(f, "%*serror-app-tag \"%s\";\n", LEVEL, INDENT, restr->eapptag);
Radek Krejci41726f92015-06-19 13:11:05 +0200172 }
Radek Krejci0bd5db42015-06-19 13:30:07 +0200173 if (restr->emsg != NULL) {
174 yang_print_text(f, level, "error-message", restr->emsg);
Radek Krejci41726f92015-06-19 13:11:05 +0200175 }
176}
177
178static void
Michal Vasko1f0428a2015-07-07 14:55:04 +0200179yang_print_when(FILE *f, int level, struct ly_when *when)
180{
181 fprintf(f, "%*swhen \"%s\" {\n", LEVEL, INDENT, when->cond);
182 level++;
183 if (when->dsc) {
184 yang_print_text(f, level, "description", when->dsc);
185 }
186 if (when->ref) {
187 yang_print_text(f, level, "reference", when->ref);
188 }
189 level--;
190 fprintf(f, "%*s}\n", LEVEL, INDENT);
191}
192
193static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200194yang_print_type(FILE *f, int level, struct ly_module *module, struct ly_type *type)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200195{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200196 int i;
Radek Krejci25d782a2015-05-22 15:03:23 +0200197
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200198 if (type->prefix) {
199 fprintf(f, "%*stype %s:%s {\n", LEVEL, INDENT, type->prefix, type->der->name);
200 } else {
201 fprintf(f, "%*stype %s {\n", LEVEL, INDENT, type->der->name);
202 }
203 level++;
204 switch (type->base) {
205 case LY_TYPE_BINARY:
206 if (type->info.binary.length != NULL) {
Radek Krejci41726f92015-06-19 13:11:05 +0200207 fprintf(f, "%*slength \"%s\" {\n", LEVEL, INDENT, type->info.binary.length->expr);
Radek Krejci0bd5db42015-06-19 13:30:07 +0200208 yang_print_restr(f, level + 1, type->info.binary.length);
Radek Krejci41726f92015-06-19 13:11:05 +0200209 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200210 }
211 break;
212 case LY_TYPE_BITS:
213 for (i = 0; i < type->info.bits.count; ++i) {
Radek Krejci994b6f62015-06-18 16:47:27 +0200214 fprintf(f, "%*sbit %s {\n", LEVEL, INDENT, type->info.bits.bit[i].name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200215 level++;
216 yang_print_mnode_common(f, level, (struct ly_mnode *)&type->info.bits.bit[i]);
217 fprintf(f, "%*sposition %u;\n", LEVEL, INDENT, type->info.bits.bit[i].pos);
218 level--;
219 fprintf(f, "%*s}\n", LEVEL, INDENT);
220 }
221 break;
222 case LY_TYPE_DEC64:
223 fprintf(f, "%*sfraction-digits %d;\n", LEVEL, INDENT, type->info.dec64.dig);
Michal Vaskoea505ee2015-07-07 14:01:00 +0200224 if (type->info.dec64.range != NULL) {
225 fprintf(f, "%*srange \"%s\" {\n", LEVEL, INDENT, type->info.dec64.range->expr);
226 yang_print_restr(f, level + 1, type->info.dec64.range);
227 fprintf(f, "%*s}\n", LEVEL, INDENT);
228 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200229 break;
230 case LY_TYPE_ENUM:
231 for (i = 0; i < type->info.enums.count; i++) {
232 fprintf(f, "%*senum %s {\n", LEVEL, INDENT, type->info.enums.list[i].name);
233 level++;
234 yang_print_mnode_common(f, level, (struct ly_mnode *)&type->info.enums.list[i]);
235 fprintf(f, "%*svalue %d;\n", LEVEL, INDENT, type->info.enums.list[i].value);
236 level--;
237 fprintf(f, "%*s}\n", LEVEL, INDENT);
238 }
239 break;
240 case LY_TYPE_IDENT:
241 if (module == type->info.ident.ref->module) {
242 fprintf(f, "%*sbase %s;\n", LEVEL, INDENT, type->info.ident.ref->name);
243 } else {
244 fprintf(f, "%*sbase %s:%s;\n", LEVEL, INDENT, type->info.ident.ref->module->prefix,
245 type->info.ident.ref->name);
246 }
247 break;
248 case LY_TYPE_INST:
Radek Krejciaf351422015-06-19 14:49:38 +0200249 if (type->info.inst.req == 1) {
250 fprintf(f, "%*srequire-instance \"true\";\n", LEVEL, INDENT);
251 } else if (type->info.inst.req == -1) {
252 fprintf(f, "%*srequire-instance \"false\";\n", LEVEL, INDENT);
253 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200254 break;
255 case LY_TYPE_INT8:
256 case LY_TYPE_INT16:
257 case LY_TYPE_INT32:
258 case LY_TYPE_INT64:
259 case LY_TYPE_UINT8:
260 case LY_TYPE_UINT16:
261 case LY_TYPE_UINT32:
262 case LY_TYPE_UINT64:
Radek Krejcif2860132015-06-20 12:37:20 +0200263 if (type->info.num.range != NULL) {
264 fprintf(f, "%*srange \"%s\" {\n", LEVEL, INDENT, type->info.num.range->expr);
265 yang_print_restr(f, level + 1, type->info.num.range);
266 fprintf(f, "%*s}\n", LEVEL, INDENT);
267 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200268 break;
269 case LY_TYPE_LEAFREF:
270 fprintf(f, "%*spath \"%s\";\n", LEVEL, INDENT, type->info.lref.path);
271 break;
272 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200273 if (type->info.str.length) {
Radek Krejci061bd522015-06-19 13:45:16 +0200274 fprintf(f, "%*slength \"%s\" {\n", LEVEL, INDENT, type->info.str.length->expr);
275 yang_print_restr(f, level + 1, type->info.str.length);
276 fprintf(f, "%*s}\n", LEVEL, INDENT);
277 }
Radek Krejci5fbc9162015-06-19 14:11:11 +0200278 for (i = 0; i < type->info.str.pat_count; i++) {
279 fprintf(f, "%*spattern \"%s\" {\n", LEVEL, INDENT, type->info.str.patterns[i].expr);
280 yang_print_restr(f, level + 1, &type->info.str.patterns[i]);
281 fprintf(f, "%*s}\n", LEVEL, INDENT);
282 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200283 break;
284 case LY_TYPE_UNION:
285 for (i = 0; i < type->info.uni.count; ++i) {
286 yang_print_type(f, level, module, &type->info.uni.type[i]);
287 }
288 break;
289 default:
290 /* other types do not have substatements */
291 break;
292 }
293 level--;
294 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200295}
296
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200297static void
Radek Krejci0bd5db42015-06-19 13:30:07 +0200298yang_print_must(FILE *f, int level, struct ly_restr *must)
Michal Vasko7f976ee2015-06-09 13:55:41 +0200299{
Radek Krejci0bd5db42015-06-19 13:30:07 +0200300 fprintf(f, "%*smust \"%s\" {\n", LEVEL, INDENT, must->expr);
Radek Krejci41726f92015-06-19 13:11:05 +0200301 yang_print_restr(f, level + 1, must);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200302 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200303}
304
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200305static void
Michal Vasko1ef07972015-07-07 14:01:35 +0200306yang_print_unique(FILE *f, int level, struct ly_unique *uniq)
307{
308 int i;
309
310 fprintf(f, "%*sunique \"", LEVEL, INDENT);
311 for (i = 0; i < uniq->leafs_size; i++) {
312 fprintf(f, "%s%s", uniq->leafs[i]->name, i + 1 < uniq->leafs_size ? " " : "");
313 }
314 fprintf(f, "\";\n");
315}
316
317static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200318yang_print_refine(FILE *f, int level, struct ly_refine *refine)
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200319{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200320 int i;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200321
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200322 fprintf(f, "%*srefine \"%s\" {\n", LEVEL, INDENT, refine->target);
323 level++;
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200324
Radek Krejci6a113852015-07-03 16:04:20 +0200325 if (refine->flags & LY_NODE_CONFIG_W) {
326 fprintf(f, "%*sconfig \"true\";\n", LEVEL, INDENT);
327 } else if (refine->flags & LY_NODE_CONFIG_R) {
328 fprintf(f, "%*sconfig \"false\";\n", LEVEL, INDENT);
329 }
330
331 if (refine->flags & LY_NODE_MAND_TRUE) {
332 fprintf(f, "%*smandatory \"true\";\n", LEVEL, INDENT);
333 } else if (refine->flags & LY_NODE_MAND_FALSE) {
334 fprintf(f, "%*smandatory \"false\";\n", LEVEL, INDENT);
335 }
336
337 yang_print_mnode_common(f, level, (struct ly_mnode *)refine);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200338
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200339 for (i = 0; i < refine->must_size; ++i) {
340 yang_print_must(f, level, &refine->must[i]);
341 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200342
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200343 if (refine->target_type & (LY_NODE_LEAF | LY_NODE_CHOICE)) {
344 if (refine->mod.dflt != NULL) {
345 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, refine->mod.dflt);
346 }
347 } else if (refine->target_type == LY_NODE_CONTAINER) {
348 if (refine->mod.presence != NULL) {
349 yang_print_text(f, level, "presence", refine->mod.presence);
350 }
351 } else if (refine->target_type & (LY_NODE_LIST | LY_NODE_LEAFLIST)) {
352 if (refine->mod.list.min > 0) {
353 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, refine->mod.list.min);
354 }
355 if (refine->mod.list.max > 0) {
356 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, refine->mod.list.max);
357 }
358 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200359
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200360 level--;
361 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200362}
363
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200364static void
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200365yang_print_deviation(FILE *f, int level, struct ly_module *module, struct ly_deviation *deviation)
366{
367 int i, j;
368
369 fprintf(f, "%*sdeviation \"%s\" {\n", LEVEL, INDENT, deviation->target_name);
370 level++;
371
372 if (deviation->dsc) {
373 yang_print_text(f, level, "description", deviation->dsc);
374 }
375 if (deviation->ref) {
376 yang_print_text(f, level, "reference", deviation->ref);
377 }
378
379 for (i = 0; i < deviation->deviate_size; ++i) {
380 fprintf(f, "%*sdeviate ", LEVEL, INDENT);
381 if (deviation->deviate[i].mod == LY_DEVIATE_NO) {
382 fprintf(f, "not-supported {\n");
383 } else if (deviation->deviate[i].mod == LY_DEVIATE_ADD) {
384 fprintf(f, "add {\n");
385 } else if (deviation->deviate[i].mod == LY_DEVIATE_RPL) {
386 fprintf(f, "replace {\n");
387 } else if (deviation->deviate[i].mod == LY_DEVIATE_DEL) {
388 fprintf(f, "delete {\n");
389 }
390 level++;
391
392 if (deviation->deviate[i].flags & LY_NODE_CONFIG_W) {
393 fprintf(f, "%*sconfig \"true\";\n", LEVEL, INDENT);
394 } else if (deviation->deviate[i].flags & LY_NODE_CONFIG_R) {
395 fprintf(f, "%*sconfig \"false\";\n", LEVEL, INDENT);
396 }
397
398 if (deviation->deviate[i].flags & LY_NODE_MAND_TRUE) {
399 fprintf(f, "%*smandatory \"true\";\n", LEVEL, INDENT);
400 } else if (deviation->deviate[i].flags & LY_NODE_MAND_FALSE) {
401 fprintf(f, "%*smandatory \"false\";\n", LEVEL, INDENT);
402 }
403
404 if (deviation->deviate[i].dflt) {
405 fprintf(f, "%*sdefault %s;\n", LEVEL, INDENT, deviation->deviate[i].dflt);
406 }
407
408 if (deviation->deviate[i].min) {
409 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].min);
410 }
411 if (deviation->deviate[i].max) {
412 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].max);
413 }
414
415 for (j = 0; j < deviation->deviate[i].must_size; ++j) {
416 yang_print_must(f, level, &deviation->deviate[i].must[j]);
417 }
418
419 for (j = 0; j < deviation->deviate[i].unique_size; ++j) {
420 yang_print_unique(f, level, &deviation->deviate[i].unique[j]);
421 }
422
423 if (deviation->deviate[i].type) {
424 yang_print_type(f, level, module, deviation->deviate[i].type);
425 }
426
427 if (deviation->deviate[i].units) {
428 fprintf(f, "%*sunits %s;\n", LEVEL, INDENT, deviation->deviate[i].units);
429 }
430
431 level--;
432 fprintf(f, "%*s}\n", LEVEL, INDENT);
433 }
434
435 level--;
436 fprintf(f, "%*s}\n", LEVEL, INDENT);
437}
438
439static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200440yang_print_typedef(FILE *f, int level, struct ly_module *module, struct ly_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200441{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200442 fprintf(f, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
443 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200444
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200445 yang_print_mnode_common(f, level, (struct ly_mnode *)tpdf);
446 yang_print_type(f, level, module, &tpdf->type);
447 if (tpdf->units != NULL) {
448 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, tpdf->units);
449 }
450 if (tpdf->dflt != NULL) {
451 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, tpdf->dflt);
452 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200453
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200454 level--;
455 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200456}
457
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200458static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200459yang_print_identity(FILE *f, int level, struct ly_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200460{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200461 fprintf(f, "%*sidentity %s {\n", LEVEL, INDENT, ident->name);
462 level++;
Radek Krejci6793db02015-05-22 17:49:54 +0200463
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200464 yang_print_mnode_common(f, level, (struct ly_mnode *)ident);
465 if (ident->base) {
466 if (ident->base->module == ident->module) {
467 fprintf(f, "%*sbase %s;\n", LEVEL, INDENT, ident->base->name);
468 } else {
469 fprintf(f, "%*sbase %s:%s;\n", LEVEL, INDENT, ident->base->module->prefix, ident->base->name);
470 }
471 }
Radek Krejci6793db02015-05-22 17:49:54 +0200472
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200473 level--;
474 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejci6793db02015-05-22 17:49:54 +0200475
476}
477
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200478static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200479yang_print_container(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200480{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200481 int i;
482 struct ly_mnode *sub;
483 struct ly_mnode_container *cont = (struct ly_mnode_container *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200484
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200485 fprintf(f, "%*scontainer %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko7f976ee2015-06-09 13:55:41 +0200486
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200487 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200488
489 yang_print_nacmext(f, level, mnode);
490
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200491 if (cont->presence != NULL) {
492 yang_print_text(f, level, "presence", cont->presence);
493 }
Michal Vasko7f976ee2015-06-09 13:55:41 +0200494
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200495 for (i = 0; i < cont->must_size; i++) {
496 yang_print_must(f, level, &cont->must[i]);
497 }
Michal Vasko7f976ee2015-06-09 13:55:41 +0200498
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200499 yang_print_mnode_common2(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200500
Michal Vasko4773b762015-07-07 12:15:10 +0200501 for (i = 0; i < cont->features_size; i++) {
502 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, cont->features[i]->name);
503 }
504
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200505 for (i = 0; i < cont->tpdf_size; i++) {
506 yang_print_typedef(f, level, mnode->module, &cont->tpdf[i]);
507 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200508
Michal Vasko1f0428a2015-07-07 14:55:04 +0200509 if (cont->when) {
510 yang_print_when(f, level, cont->when);
511 }
512
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200513 LY_TREE_FOR(mnode->child, sub) {
514 yang_print_mnode(f, level, sub,
515 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
516 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
517 }
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200518
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200519 level--;
520 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200521}
522
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200523static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200524yang_print_case(FILE *f, int level, struct ly_mnode *mnode)
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200525{
Michal Vasko4773b762015-07-07 12:15:10 +0200526 int i;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200527 struct ly_mnode *sub;
528 struct ly_mnode_case *cas = (struct ly_mnode_case *)mnode;
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200529
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200530 fprintf(f, "%*scase %s {\n", LEVEL, INDENT, cas->name);
531 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200532 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200533 yang_print_mnode_common2(f, level, mnode);
Michal Vaskoc1329bc2015-06-09 13:58:18 +0200534
Michal Vasko4773b762015-07-07 12:15:10 +0200535 for (i = 0; i < cas->features_size; i++) {
536 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, cas->features[i]->name);
537 }
538
Michal Vasko1f0428a2015-07-07 14:55:04 +0200539 if (cas->when) {
540 yang_print_when(f, level, cas->when);
541 }
542
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200543 LY_TREE_FOR(mnode->child, sub) {
544 yang_print_mnode(f, level, sub,
545 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
546 LY_NODE_USES | LY_NODE_ANYXML);
547 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200548
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200549 level--;
550 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200551}
552
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200553static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200554yang_print_choice(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200555{
Michal Vasko4773b762015-07-07 12:15:10 +0200556 int i;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200557 struct ly_mnode *sub;
558 struct ly_mnode_choice *choice = (struct ly_mnode_choice *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200559
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200560 fprintf(f, "%*schoice %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200561
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200562 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200563 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200564 if (choice->dflt != NULL) {
565 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, choice->dflt->name);
566 }
Michal Vasko16083662015-06-09 14:00:45 +0200567
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200568 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200569
570 for (i = 0; i < choice->features_size; i++) {
571 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, choice->features[i]->name);
572 }
573
Michal Vasko1f0428a2015-07-07 14:55:04 +0200574 if (choice->when) {
575 yang_print_when(f, level, choice->when);
576 }
577
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200578 LY_TREE_FOR(mnode->child, sub) {
579 yang_print_mnode(f, level, sub,
580 LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_CASE);
581 }
582 level--;
583 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200584}
585
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200586static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200587yang_print_leaf(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200588{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200589 int i;
590 struct ly_mnode_leaf *leaf = (struct ly_mnode_leaf *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200591
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200592 fprintf(f, "%*sleaf %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200593
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200594 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200595 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200596 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200597 for (i = 0; i < leaf->features_size; i++) {
598 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, leaf->features[i]->name);
599 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200600 for (i = 0; i < leaf->must_size; i++) {
601 yang_print_must(f, level, &leaf->must[i]);
602 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200603 if (leaf->when) {
604 yang_print_when(f, level, leaf->when);
605 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200606 yang_print_type(f, level, mnode->module, &leaf->type);
607 if (leaf->units != NULL) {
608 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, leaf->units);
609 }
610 if (leaf->dflt != NULL) {
611 fprintf(f, "%*sdefault \"%s\";\n", LEVEL, INDENT, leaf->dflt);
612 }
613 level--;
Michal Vasko16083662015-06-09 14:00:45 +0200614
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200615 fprintf(f, "%*s}\n", LEVEL, INDENT);
Michal Vasko16083662015-06-09 14:00:45 +0200616}
617
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200618static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200619yang_print_anyxml(FILE *f, int level, struct ly_mnode *mnode)
Michal Vasko16083662015-06-09 14:00:45 +0200620{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200621 int i;
622 struct ly_mnode_anyxml *anyxml = (struct ly_mnode_anyxml *)mnode;
Michal Vasko16083662015-06-09 14:00:45 +0200623
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200624 fprintf(f, "%*sanyxml %s {\n", LEVEL, INDENT, anyxml->name);
625 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200626 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200627 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200628 for (i = 0; i < anyxml->features_size; i++) {
629 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, anyxml->features[i]->name);
630 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200631 for (i = 0; i < anyxml->must_size; i++) {
632 yang_print_must(f, level, &anyxml->must[i]);
633 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200634 if (anyxml->when) {
635 yang_print_when(f, level, anyxml->when);
636 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200637 level--;
638 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200639}
640
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200641static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200642yang_print_leaflist(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200643{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200644 int i;
645 struct ly_mnode_leaflist *llist = (struct ly_mnode_leaflist *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200646
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200647 fprintf(f, "%*sleaf-list %s {\n", LEVEL, INDENT, mnode->name);
Michal Vasko16083662015-06-09 14:00:45 +0200648
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200649 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200650 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200651 yang_print_mnode_common2(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200652 for (i = 0; i < llist->features_size; i++) {
653 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, llist->features[i]->name);
654 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200655 if (llist->flags & LY_NODE_USERORDERED) {
656 fprintf(f, "%*sordered-by user;\n", LEVEL, INDENT);
657 }
658 if (llist->min > 0) {
659 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, llist->min);
660 }
661 if (llist->max > 0) {
662 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, llist->max);
663 }
664 for (i = 0; i < llist->must_size; i++) {
665 yang_print_must(f, level, &llist->must[i]);
666 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200667 if (llist->when) {
668 yang_print_when(f, level, llist->when);
669 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200670 yang_print_type(f, level, mnode->module, &llist->type);
671 if (llist->units != NULL) {
672 fprintf(f, "%*sunits \"%s\";\n", LEVEL, INDENT, llist->units);
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);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200677}
678
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200679static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200680yang_print_list(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200681{
Michal Vasko1ef07972015-07-07 14:01:35 +0200682 int i;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200683 struct ly_mnode *sub;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200684 struct ly_mnode_list *list = (struct ly_mnode_list *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200685
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200686 fprintf(f, "%*slist %s {\n", LEVEL, INDENT, mnode->name);
687 level++;
Radek Krejci6a113852015-07-03 16:04:20 +0200688 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200689 yang_print_mnode_common2(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200690
Michal Vasko4773b762015-07-07 12:15:10 +0200691 for (i = 0; i < list->features_size; i++) {
692 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, list->features[i]->name);
693 }
694
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200695 if (list->keys_size) {
696 fprintf(f, "%*skey \"", LEVEL, INDENT);
697 for (i = 0; i < list->keys_size; i++) {
698 fprintf(f, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "");
699 }
700 fprintf(f, "\";\n");
701 }
Radek Krejcid7f0d012015-05-25 15:04:52 +0200702
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200703 for (i = 0; i < list->unique_size; i++) {
Michal Vasko1ef07972015-07-07 14:01:35 +0200704 yang_print_unique(f, level, &list->unique[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200705 }
Michal Vaskodff818b2015-06-09 14:01:12 +0200706
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200707 if (list->flags & LY_NODE_USERORDERED) {
708 fprintf(f, "%*sordered-by user;\n", LEVEL, INDENT);
709 }
710 if (list->min > 0) {
711 fprintf(f, "%*smin-elements %u;\n", LEVEL, INDENT, list->min);
712 }
713 if (list->max > 0) {
714 fprintf(f, "%*smax-elements %u;\n", LEVEL, INDENT, list->max);
715 }
716 for (i = 0; i < list->must_size; i++) {
717 yang_print_must(f, level, &list->must[i]);
718 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200719 if (list->when) {
720 yang_print_when(f, level, list->when);
721 }
Michal Vaskodff818b2015-06-09 14:01:12 +0200722
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200723 for (i = 0; i < list->tpdf_size; i++) {
724 yang_print_typedef(f, level, list->module, &list->tpdf[i]);
725 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200726
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200727 LY_TREE_FOR(mnode->child, sub) {
728 yang_print_mnode(f, level, sub,
729 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
730 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
731 }
732 level--;
733 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200734}
735
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200736static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200737yang_print_grouping(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200738{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200739 int i;
740 struct ly_mnode *node;
741 struct ly_mnode_grp *grp = (struct ly_mnode_grp *)mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200742
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200743 fprintf(f, "%*sgrouping %s {\n", LEVEL, INDENT, mnode->name);
744 level++;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200745
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200746 yang_print_mnode_common(f, level, mnode);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200747
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200748 for (i = 0; i < grp->tpdf_size; i++) {
749 yang_print_typedef(f, level, mnode->module, &grp->tpdf[i]);
750 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200751
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200752 LY_TREE_FOR(mnode->child, node) {
753 yang_print_mnode(f, level, node,
754 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
755 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
756 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200757
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200758 level--;
759 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200760}
761
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200762static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200763yang_print_uses(FILE *f, int level, struct ly_mnode *mnode)
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200764{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200765 int i;
766 struct ly_mnode_uses *uses = (struct ly_mnode_uses *)mnode;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200767
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200768 fprintf(f, "%*suses %s {\n", LEVEL, INDENT, uses->name);
769 level++;
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200770
Radek Krejci6a113852015-07-03 16:04:20 +0200771 yang_print_nacmext(f, level, mnode);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200772 yang_print_mnode_common(f, level, mnode);
Michal Vasko4773b762015-07-07 12:15:10 +0200773 for (i = 0; i < uses->features_size; i++) {
774 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, uses->features[i]->name);
775 }
Michal Vasko1f0428a2015-07-07 14:55:04 +0200776 if (uses->when) {
777 yang_print_when(f, level, uses->when);
778 }
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200779
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200780 for (i = 0; i < uses->refine_size; i++) {
781 yang_print_refine(f, level, &uses->refine[i]);
782 }
Michal Vasko00b7cfe2015-06-09 13:56:38 +0200783
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200784 level--;
785 fprintf(f, "%*s}\n", LEVEL, INDENT);
Radek Krejcic7c9a6c2015-05-25 16:35:06 +0200786}
787
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200788static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200789yang_print_input_output(FILE *f, int level, struct ly_mnode *mnode)
790{
Michal Vaskof4d3d742015-06-16 11:51:09 +0200791 int i;
792 struct ly_mnode *sub;
Michal Vaskofb69a842015-06-16 12:07:40 +0200793 struct ly_mnode_input_output *inout = (struct ly_mnode_input_output *)mnode;
Michal Vaskof4d3d742015-06-16 11:51:09 +0200794
795 fprintf(f, "%*s%s {\n", LEVEL, INDENT, (inout->nodetype == LY_NODE_INPUT ? "input" : "output"));
796
797 level++;
798 for (i = 0; i < inout->tpdf_size; i++) {
799 yang_print_typedef(f, level, mnode->module, &inout->tpdf[i]);
800 }
801
802 LY_TREE_FOR(mnode->child, sub) {
803 yang_print_mnode(f, level, sub,
804 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
805 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
806 }
807
808 level--;
809 fprintf(f, "%*s}\n", LEVEL, INDENT);
810}
811
812static void
813yang_print_rpc(FILE *f, int level, struct ly_mnode *mnode)
814{
815 int i;
816 struct ly_mnode *sub;
817 struct ly_mnode_rpc *rpc = (struct ly_mnode_rpc *)mnode;
818
819 fprintf(f, "%*srpc %s {\n", LEVEL, INDENT, mnode->name);
820
821 level++;
822 yang_print_mnode_common(f, level, mnode);
823
Michal Vasko4773b762015-07-07 12:15:10 +0200824 for (i = 0; i < rpc->features_size; i++) {
825 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, rpc->features[i]->name);
826 }
827
Michal Vaskof4d3d742015-06-16 11:51:09 +0200828 for (i = 0; i < rpc->tpdf_size; i++) {
829 yang_print_typedef(f, level, mnode->module, &rpc->tpdf[i]);
830 }
831
832 LY_TREE_FOR(mnode->child, sub) {
833 yang_print_mnode(f, level, sub,
834 LY_NODE_GROUPING | LY_NODE_INPUT | LY_NODE_OUTPUT);
835 }
836
837 level--;
838 fprintf(f, "%*s}\n", LEVEL, INDENT);
839}
840
841static void
Michal Vasko7690bc12015-06-16 12:26:05 +0200842yang_print_notif(FILE *f, int level, struct ly_mnode *mnode)
843{
Michal Vaskof4d3d742015-06-16 11:51:09 +0200844 int i;
845 struct ly_mnode *sub;
846 struct ly_mnode_notif *notif = (struct ly_mnode_notif *)mnode;
847
848 fprintf(f, "%*snotification %s {\n", LEVEL, INDENT, mnode->name);
849
850 level++;
851 yang_print_mnode_common(f, level, mnode);
852
Michal Vasko4773b762015-07-07 12:15:10 +0200853 for (i = 0; i < notif->features_size; i++) {
854 fprintf(f, "%*sif-feature %s;\n", LEVEL, INDENT, notif->features[i]->name);
855 }
856
Michal Vaskof4d3d742015-06-16 11:51:09 +0200857 for (i = 0; i < notif->tpdf_size; i++) {
858 yang_print_typedef(f, level, mnode->module, &notif->tpdf[i]);
859 }
860
861 LY_TREE_FOR(mnode->child, sub) {
862 yang_print_mnode(f, level, sub,
863 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
864 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
865 }
866
867 level--;
868 fprintf(f, "%*s}\n", LEVEL, INDENT);
869}
870
871static void
Michal Vasko5bbae102015-06-16 12:16:44 +0200872yang_print_mnode(FILE *f, int level, struct ly_mnode *mnode, int mask)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200873{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200874 switch (mnode->nodetype & mask) {
875 case LY_NODE_CONTAINER:
876 yang_print_container(f, level, mnode);
877 break;
878 case LY_NODE_CHOICE:
879 yang_print_choice(f, level, mnode);
880 break;
881 case LY_NODE_LEAF:
882 yang_print_leaf(f, level, mnode);
883 break;
884 case LY_NODE_LEAFLIST:
885 yang_print_leaflist(f, level, mnode);
886 break;
887 case LY_NODE_LIST:
888 yang_print_list(f, level, mnode);
889 break;
890 case LY_NODE_USES:
891 yang_print_uses(f, level, mnode);
892 break;
893 case LY_NODE_GROUPING:
894 yang_print_grouping(f, level, mnode);
895 break;
896 case LY_NODE_ANYXML:
897 yang_print_anyxml(f, level, mnode);
898 break;
899 case LY_NODE_CASE:
900 yang_print_case(f, level, mnode);
901 break;
Michal Vaskof4d3d742015-06-16 11:51:09 +0200902 case LY_NODE_INPUT:
903 case LY_NODE_OUTPUT:
904 yang_print_input_output(f, level, mnode);
905 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200906 default:
907 break;
908 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200909}
910
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200911int
Michal Vasko5bbae102015-06-16 12:16:44 +0200912yang_print_model(FILE *f, struct ly_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200913{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200914 unsigned int i;
915 int level = 0;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200916#define LEVEL (level*2)
917
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200918 struct ly_mnode *mnode;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200919
Michal Vasko116172e2015-07-07 11:54:37 +0200920 if (module->type) {
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200921 fprintf(f, "submodule %s {%s\n", module->name, (module->deviated ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +0200922 level++;
923 fprintf(f, "%*sbelongs-to %s {\n", LEVEL, INDENT, ((struct ly_submodule *)module)->belongsto->name);
924 level++;
925 fprintf(f, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
926 level--;
927 fprintf(f, "%*s}\n", LEVEL, INDENT);
928 } else {
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200929 fprintf(f, "module %s {%s\n", module->name, (module->deviated ? " // DEVIATED" : ""));
Michal Vasko116172e2015-07-07 11:54:37 +0200930 level++;
931 fprintf(f, "%*snamespace \"%s\";\n", LEVEL, INDENT, module->ns);
932 fprintf(f, "%*sprefix \"%s\";\n", LEVEL, INDENT, module->prefix);
933 }
Radek Krejcib0594bf2015-05-21 23:51:27 +0200934
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200935 if (module->version) {
Michal Vasko6c722a62015-07-07 11:54:57 +0200936 fprintf(f, "%*syang-version %s;\n", LEVEL, INDENT, module->version == 1 ? "1" : "1.1");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200937 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200938
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200939 for (i = 0; i < module->imp_size; i++) {
940 fprintf(f, "%*simport \"%s\" {\n", LEVEL, INDENT, module->imp[i].module->name);
941 level++;
942 yang_print_text(f, level, "prefix", module->imp[i].prefix);
943 if (module->imp[i].rev[0]) {
944 yang_print_text(f, level, "revision-date", module->imp[i].rev);
945 }
946 level--;
947 fprintf(f, "%*s}\n", LEVEL, INDENT);
948 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200949
Michal Vaskoe0af1e22015-07-07 14:02:02 +0200950 for (i = 0; i < module->deviation_size; ++i) {
951 yang_print_deviation(f, level, module, &module->deviation[i]);
952 }
953
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200954 for (i = 0; i < module->inc_size; i++) {
955 if (module->inc[i].rev[0]) {
956 fprintf(f, "%*sinclude \"%s\" {\n", LEVEL, INDENT, module->inc[i].submodule->name);
957 yang_print_text(f, level + 1, "revision-date", module->imp[i].rev);
958 fprintf(f, "%*s}\n", LEVEL, INDENT);
959 } else {
960 fprintf(f, "%*sinclude \"%s\";\n", LEVEL, INDENT, module->inc[i].submodule->name);
961 }
962 }
Radek Krejciefaeba32015-05-27 14:30:57 +0200963
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200964 if (module->org) {
965 yang_print_text(f, level, "organization", module->org);
966 }
967 if (module->contact) {
968 yang_print_text(f, level, "contact", module->contact);
969 }
970 if (module->dsc) {
971 yang_print_text(f, level, "description", module->dsc);
972 }
973 if (module->ref) {
974 yang_print_text(f, level, "reference", module->ref);
975 }
976 for (i = 0; i < module->rev_size; i++) {
977 if (module->rev[i].dsc || module->rev[i].ref) {
978 fprintf(f, "%*srevision \"%s\" {\n", LEVEL, INDENT, module->rev[i].date);
979 level++;
980 if (module->rev[i].dsc) {
981 yang_print_text(f, level, "description", module->rev[i].dsc);
982 }
983 if (module->rev[i].ref) {
984 yang_print_text(f, level, "reference", module->rev[i].ref);
985 }
986 level--;
987 fprintf(f, "%*s}\n", LEVEL, INDENT);
988 } else {
989 yang_print_text(f, level, "revision", module->rev[i].date);
990 }
991 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200992
Michal Vasko30f6e912015-07-07 12:24:27 +0200993 for (i = 0; i < module->features_size; i++) {
994 yang_print_feature(f, level, &module->features[i]);
995 }
996
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200997 for (i = 0; i < module->ident_size; i++) {
998 yang_print_identity(f, level, &module->ident[i]);
999 }
Radek Krejci6793db02015-05-22 17:49:54 +02001000
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001001 for (i = 0; i < module->tpdf_size; i++) {
1002 yang_print_typedef(f, level, module, &module->tpdf[i]);
1003 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001004
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001005 LY_TREE_FOR(module->data, mnode) {
1006 yang_print_mnode(f, level, mnode,
1007 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST |
1008 LY_NODE_USES | LY_NODE_GROUPING | LY_NODE_ANYXML);
1009 }
Radek Krejcida04f4a2015-05-21 12:54:09 +02001010
Michal Vaskof4d3d742015-06-16 11:51:09 +02001011 LY_TREE_FOR(module->rpc, mnode) {
1012 yang_print_rpc(f, level, mnode);
1013 }
1014
1015 LY_TREE_FOR(module->notif, mnode) {
1016 yang_print_notif(f, level, mnode);
1017 }
1018
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001019 fprintf(f, "}\n");
Radek Krejcida04f4a2015-05-21 12:54:09 +02001020
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001021 return EXIT_SUCCESS;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001022#undef LEVEL
1023}