blob: dd6c278f8572b47e90d289e422fbee4c9bada300 [file] [log] [blame]
Michal Vasko5ed10f12015-06-04 10:04:57 +02001/**
2 * @file printer/tree.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief TREE printer for libyang data model structure
5 *
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>
Michal Vaskob5c75d72015-06-15 12:16:52 +020025#include <assert.h>
Michal Vasko5ed10f12015-06-04 10:04:57 +020026
27#include "../common.h"
28#include "../tree.h"
29
Michal Vaskoe03bfbb2015-06-16 09:07:49 +020030/* spec_config = 0 (no special config status), 1 (read-only - rpc output, notification), 2 (write-only - rpc input) */
Michal Vaskofc3b0a32015-06-29 15:50:34 +020031static void tree_print_mnode_choice(FILE *f, struct ly_module* module, int level, char *indent, unsigned int max_name_len,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020032 struct ly_mnode *mnode, int mask, int spec_config);
Michal Vaskofc3b0a32015-06-29 15:50:34 +020033static void tree_print_mnode(FILE *f, struct ly_module *module, int level, char *indent, unsigned int max_name_len, struct ly_mnode *mnode,
Michal Vaskoe03bfbb2015-06-16 09:07:49 +020034 int mask, int spec_config);
Michal Vasko5ed10f12015-06-04 10:04:57 +020035
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020036static int
37sibling_is_valid_child(const struct ly_mnode *mnode)
Michal Vasko6db4fce2015-06-08 14:13:49 +020038{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020039 struct ly_mnode *cur;
Michal Vasko7ea0a312015-06-08 10:36:48 +020040
Michal Vasko07898f92015-06-15 12:17:11 +020041 if (mnode == NULL) {
42 return 0;
43 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020044
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020045 /* has a following printed child */
46 LY_TREE_FOR((struct ly_mnode *)mnode->next, cur) {
47 if (cur->nodetype &
48 (LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_CHOICE |
49 LY_NODE_RPC | LY_NODE_INPUT | LY_NODE_OUTPUT | LY_NODE_NOTIF)) {
50 return 1;
51 }
52 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020053
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020054 /* if in uses, the following printed child can actually be in the parent node :-/ */
Michal Vasko07898f92015-06-15 12:17:11 +020055 if (mnode->parent && mnode->parent->nodetype == LY_NODE_USES) {
56 return sibling_is_valid_child(mnode->parent);
57 }
58
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020059 return 0;
Michal Vasko7ea0a312015-06-08 10:36:48 +020060}
61
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020062static char *
63create_indent(int level, const char *old_indent, const struct ly_mnode *mnode, int shorthand)
Michal Vasko449afde2015-06-04 16:06:49 +020064{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020065 int next_is_case = 0, is_case = 0, has_next = 0, i, found;
66 char *new_indent = malloc((level * 4 + 1) * sizeof (char));
Michal Vasko14410462015-06-05 15:08:54 +020067
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020068 strcpy(new_indent, old_indent);
Michal Vasko14410462015-06-05 15:08:54 +020069
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020070 /* this is the indent of a case (standard or shorthand) */
71 if (mnode->nodetype == LY_NODE_CASE || shorthand) {
72 is_case = 1;
73 }
Michal Vasko14410462015-06-05 15:08:54 +020074
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020075 /* this is the direct child of a case */
76 if (!is_case && mnode->parent && (mnode->parent->nodetype & (LY_NODE_CASE | LY_NODE_CHOICE))) {
77 /* it is not the only child */
78 if (mnode->next && mnode->next->parent && mnode->next->parent->nodetype == LY_NODE_CHOICE) {
79 next_is_case = 1;
80 }
81 }
Michal Vasko14410462015-06-05 15:08:54 +020082
Michal Vasko07898f92015-06-15 12:17:11 +020083 /* next is a node that will actually be printed */
84 has_next = sibling_is_valid_child(mnode);
Michal Vasko14410462015-06-05 15:08:54 +020085
Michal Vasko07898f92015-06-15 12:17:11 +020086 /* there is no next, but we are in top-level of a submodule */
87 if (!has_next && mnode->module->type == 1 && !mnode->parent) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020088 struct ly_submodule *submod = (struct ly_submodule *)mnode->module;
89 struct ly_module *mod = submod->belongsto;
Michal Vasko14410462015-06-05 15:08:54 +020090
Michal Vasko07898f92015-06-15 12:17:11 +020091 /* find this submodule, check all the next ones for valid printed nodes */
92 found = 0;
93 for (i = 0; i < mod->inc_size; i++) {
94 /* we found ours, check all the following submodules and the module */
95 if (found) {
Michal Vaskof2896302015-06-16 09:30:02 +020096 if (mnode->nodetype == LY_NODE_RPC) {
97 has_next = sibling_is_valid_child(mod->inc[i].submodule->rpc);
98 } else if (mnode->nodetype == LY_NODE_NOTIF) {
99 has_next = sibling_is_valid_child(mod->inc[i].submodule->notif);
100 } else {
101 has_next = sibling_is_valid_child(mod->inc[i].submodule->data);
Michal Vasko07898f92015-06-15 12:17:11 +0200102 }
103 }
Michal Vasko7ea0a312015-06-08 10:36:48 +0200104
Michal Vasko07898f92015-06-15 12:17:11 +0200105 if (!found && !strcmp(submod->name, mod->inc[i].submodule->name)) {
106 found = 1;
107 }
108 }
Michal Vasko7ea0a312015-06-08 10:36:48 +0200109
Michal Vasko07898f92015-06-15 12:17:11 +0200110 /* there is nothing in submodules, check module */
111 if (!has_next) {
Michal Vaskof2896302015-06-16 09:30:02 +0200112 if (mnode->nodetype == LY_NODE_RPC) {
Michal Vasko0e893c92015-06-16 11:09:40 +0200113 has_next = sibling_is_valid_child(mod->rpc);
Michal Vaskof2896302015-06-16 09:30:02 +0200114 } else if (mnode->nodetype == LY_NODE_NOTIF) {
Michal Vasko0e893c92015-06-16 11:09:40 +0200115 has_next = sibling_is_valid_child(mod->notif);
Michal Vaskof2896302015-06-16 09:30:02 +0200116 } else {
Michal Vasko0e893c92015-06-16 11:09:40 +0200117 has_next = sibling_is_valid_child(mod->data);
Michal Vasko07898f92015-06-15 12:17:11 +0200118 }
119 }
120 }
121
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200122 if (has_next && !next_is_case) {
123 strcat(new_indent, "| ");
124 } else {
125 strcat(new_indent, " ");
126 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200127
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200128 return new_indent;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200129}
130
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200131static unsigned int
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200132get_max_name_len(struct ly_module *module, struct ly_mnode *mnode)
Michal Vasko8d479bd2015-06-05 10:50:03 +0200133{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200134 struct ly_mnode *sub;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200135 unsigned int max_name_len = 0, uses_max_name_len, name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200136
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200137 LY_TREE_FOR(mnode, sub) {
138 if (sub->nodetype == LY_NODE_USES) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200139 uses_max_name_len = get_max_name_len(module, sub->child);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200140 if (uses_max_name_len > max_name_len) {
141 max_name_len = uses_max_name_len;
142 }
143 } else if (sub->nodetype &
144 (LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML)) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200145 name_len = strlen(sub->name) + (module == sub->module ? 0 : strlen(sub->module->prefix)+1);
146 if (name_len > max_name_len) {
147 max_name_len = name_len;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200148 }
149 }
150 }
Michal Vasko8d479bd2015-06-05 10:50:03 +0200151
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200152 return max_name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200153}
154
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200155static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200156tree_print_type(FILE *f, struct ly_type *type)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200157{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200158 if (type->base == LY_TYPE_LEAFREF) {
159 fprintf(f, "-> %s", type->info.lref.path);
160 } else if (type->prefix) {
161 fprintf(f, "%s:%s", type->prefix, type->der->name);
162 } else {
163 fprintf(f, "%s", type->der->name);
164 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200165}
166
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200167static void
Michal Vasko28c6b572015-06-18 12:43:31 +0200168tree_print_features(FILE *f, const struct ly_feature **features, uint8_t features_size)
169{
170 int i;
171
172 if (!features_size) {
173 return;
174 }
175
176 fprintf(f, " {");
177 for (i = 0; i < features_size; i++) {
178 if (i > 0) {
179 fprintf(f, ",");
180 }
181 fprintf(f, "%s", features[i]->name);
182 }
183 fprintf(f, "}?");
184}
185
186static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200187tree_print_input_output(FILE *f, struct ly_module *module, int level, char *indent, struct ly_mnode *mnode, int spec_config)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200188{
189 unsigned int max_child_len;
190 char *new_indent;
191 struct ly_mnode *sub;
192
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200193 assert(spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200194
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200195 fprintf(f, "%s+--%s %s\n", indent, (spec_config == 1 ? "-w" : "ro"), (spec_config == 1 ? "input" : "output"));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200196
197 level++;
198 new_indent = create_indent(level, indent, mnode, 0);
199
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200200 max_child_len = get_max_name_len(module, mnode->child);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200201
202 LY_TREE_FOR(mnode->child, sub) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200203 tree_print_mnode(f, module, level, new_indent, max_child_len, sub,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200204 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_USES,
205 spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200206 }
207
208 free(new_indent);
209}
210
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200211static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200212tree_print_container(FILE *f, struct ly_module *module, int level, char *indent, struct ly_mnode *mnode, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200213{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200214 unsigned int max_child_len;
215 char *new_indent;
216 struct ly_mnode_container *cont = (struct ly_mnode_container *)mnode;
217 struct ly_mnode *sub;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200218
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200219 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200220
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200221 fprintf(f, "%s%s--", indent,
222 (cont->flags & LY_NODE_STATUS_DEPRC ? "x" : (cont->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200223
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200224 if (spec_config == 0) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200225 fprintf(f, "%s ", (cont->flags & LY_NODE_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200226 } else if (spec_config == 1) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200227 fprintf(f, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200228 } else if (spec_config == 2) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200229 fprintf(f, "ro ");
230 }
231
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200232 if (module != cont->module) {
233 fprintf(f, "%s:", cont->module->prefix);
234 }
235
Michal Vasko28c6b572015-06-18 12:43:31 +0200236 fprintf(f, "%s%s", cont->name, (cont->presence ? "!" : ""));
237
238 tree_print_features(f, (const struct ly_feature **)cont->features, cont->features_size);
239
240 fprintf(f, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200241
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200242 level++;
243 new_indent = create_indent(level, indent, mnode, 0);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200244
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200245 max_child_len = get_max_name_len(module, mnode->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200246
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200247 LY_TREE_FOR(cont->child, sub) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200248 tree_print_mnode(f, module, level, new_indent, max_child_len, sub,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200249 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_USES,
250 spec_config);
251 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200252
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200253 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200254}
255
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200256static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200257tree_print_choice(FILE *f, struct ly_module *module, int level, char *indent, struct ly_mnode *mnode, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200258{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200259 unsigned int max_child_len;
260 char *new_indent;
261 struct ly_mnode_choice *choice = (struct ly_mnode_choice *)mnode;
262 struct ly_mnode *sub;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200263
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200264 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200265
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200266 fprintf(f, "%s%s--", indent,
267 (choice->flags & LY_NODE_STATUS_DEPRC ? "x" : (choice->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200268
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200269 if (spec_config == 0) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200270 fprintf(f, "%s ", (choice->flags & LY_NODE_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200271 } else if (spec_config == 1) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200272 fprintf(f, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200273 } else if (spec_config == 2) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200274 fprintf(f, "ro ");
275 }
276
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200277 fprintf(f, "(");
278
279 if (module != choice->module) {
280 fprintf(f, "%s:", choice->module->prefix);
281 }
282
283 fprintf(f, "%s)%s", choice->name, (choice->flags & LY_NODE_MAND_TRUE ? "" : "?"));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200284
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200285 if (choice->dflt != NULL) {
286 fprintf(f, " <%s>", choice->dflt->name);
287 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200288
289 tree_print_features(f, (const struct ly_feature **)choice->features, choice->features_size);
290
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200291 fprintf(f, "\n");
Michal Vasko449afde2015-06-04 16:06:49 +0200292
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200293 level++;
294 new_indent = create_indent(level, indent, mnode, 0);
Michal Vasko449afde2015-06-04 16:06:49 +0200295
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200296 max_child_len = get_max_name_len(module, mnode->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200297
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200298 LY_TREE_FOR(choice->child, sub) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200299 tree_print_mnode_choice(f, module, level, new_indent, max_child_len, sub,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200300 LY_NODE_CASE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML,
301 spec_config);
302 }
Michal Vasko449afde2015-06-04 16:06:49 +0200303
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200304 free(new_indent);
Michal Vasko449afde2015-06-04 16:06:49 +0200305}
306
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200307static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200308tree_print_case(FILE *f, struct ly_module *module, int level, char *indent, unsigned int max_name_len, struct ly_mnode *mnode, int shorthand, int spec_config)
Michal Vasko449afde2015-06-04 16:06:49 +0200309{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200310 char *new_indent;
311 struct ly_mnode_case *cas = (struct ly_mnode_case *)mnode;
312 struct ly_mnode *sub;
Radek Krejci7e97c352015-06-19 16:26:34 +0200313 int i;
314
315 /* stop if features are not enabled */
316 for (i = 0; i < cas->features_size; i++) {
317 if (!(cas->features[i]->flags & LY_NODE_FENABLED)) {
318 return;
319 }
320 }
321 /* or if the data are from augment under a not enabled feature */
322 if (cas->parent && cas->parent->nodetype == LY_NODE_AUGMENT) {
323 for (i = 0; i < cas->parent->features_size; i++) {
324 if (!(cas->parent->features[i]->flags & LY_NODE_FENABLED)) {
325 return;
326 }
327 }
328 }
Michal Vasko449afde2015-06-04 16:06:49 +0200329
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200330 fprintf(f, "%s%s--:(", indent,
331 (cas->flags & LY_NODE_STATUS_DEPRC ? "x" : (cas->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")));
332
333 if (module != cas->module) {
334 fprintf(f, "%s:", cas->module->prefix);
335 }
336
337 fprintf(f, "%s)", cas->name);
Michal Vasko449afde2015-06-04 16:06:49 +0200338
Michal Vasko28c6b572015-06-18 12:43:31 +0200339 tree_print_features(f, (const struct ly_feature **)cas->features, cas->features_size);
340
341 fprintf(f, "\n");
342
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200343 level++;
344 new_indent = create_indent(level, indent, mnode, shorthand);
Michal Vasko449afde2015-06-04 16:06:49 +0200345
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200346 if (shorthand) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200347 tree_print_mnode(f, module, level, new_indent, max_name_len, mnode,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200348 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_USES,
349 spec_config);
350 } else {
351 LY_TREE_FOR(mnode->child, sub) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200352 tree_print_mnode(f, module, level, new_indent, max_name_len, sub,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200353 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_USES,
354 spec_config);
355 }
356 }
Michal Vasko449afde2015-06-04 16:06:49 +0200357
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200358 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200359}
360
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200361static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200362tree_print_anyxml(FILE *f, struct ly_module *module, char *indent, unsigned int max_name_len, struct ly_mnode *mnode, int spec_config)
Michal Vasko315f70b2015-06-05 10:48:59 +0200363{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200364 uint8_t prefix_len;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200365 struct ly_mnode_anyxml *anyxml = (struct ly_mnode_anyxml *)mnode;
Michal Vasko315f70b2015-06-05 10:48:59 +0200366
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200367 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200368
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200369 fprintf(f, "%s%s--", indent,
370 (anyxml->flags & LY_NODE_STATUS_DEPRC ? "x" : (anyxml->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200371
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200372 if (spec_config == 0) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200373 fprintf(f, "%s ", (anyxml->flags & LY_NODE_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200374 } else if (spec_config == 1) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200375 fprintf(f, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200376 } else if (spec_config == 2) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200377 fprintf(f, "ro ");
378 }
379
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200380 prefix_len = 0;
381 if (module != anyxml->module) {
382 fprintf(f, "%s:", anyxml->module->prefix);
383 prefix_len = strlen(anyxml->module->prefix)+1;
384 }
385
Michal Vasko28c6b572015-06-18 12:43:31 +0200386 fprintf(f, "%s%s%*sanyxml", anyxml->name, (anyxml->flags & LY_NODE_MAND_TRUE ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200387 3 + (int)((max_name_len - strlen(anyxml->name)) - prefix_len), " ");
Michal Vasko28c6b572015-06-18 12:43:31 +0200388
389 tree_print_features(f, (const struct ly_feature **)anyxml->features, anyxml->features_size);
390
391 fprintf(f, "\n");
Michal Vasko315f70b2015-06-05 10:48:59 +0200392}
393
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200394static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200395tree_print_leaf(FILE *f, struct ly_module *module, char *indent, unsigned int max_name_len, struct ly_mnode *mnode, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200396{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200397 uint8_t prefix_len;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200398 struct ly_mnode_leaf *leaf = (struct ly_mnode_leaf *)mnode;
399 struct ly_mnode_list *list;
400 int i, is_key = 0;
Michal Vasko449afde2015-06-04 16:06:49 +0200401
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200402 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200403
Radek Krejci87e840c2015-06-19 16:44:54 +0200404 if (leaf->parent && leaf->parent->nodetype == LY_NODE_LIST) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200405 list = (struct ly_mnode_list *)leaf->parent;
406 for (i = 0; i < list->keys_size; i++) {
407 if (strcmp(list->keys[i]->name, leaf->name) == 0) {
408 is_key = 1;
409 break;
410 }
411 }
412 }
Michal Vasko449afde2015-06-04 16:06:49 +0200413
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200414 fprintf(f, "%s%s--", indent,
415 (leaf->flags & LY_NODE_STATUS_DEPRC ? "x" : (leaf->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200416
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200417 if (spec_config == 0) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200418 fprintf(f, "%s ", (leaf->flags & LY_NODE_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200419 } else if (spec_config == 1) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200420 fprintf(f, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200421 } else if (spec_config == 2) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200422 fprintf(f, "ro ");
423 }
424
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200425 prefix_len = 0;
426 if (module != leaf->module) {
427 fprintf(f, "%s:", leaf->module->prefix);
428 prefix_len = strlen(leaf->module->prefix)+1;
429 }
430
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200431 fprintf(f, "%s%s%*s", leaf->name, ((leaf->flags & LY_NODE_MAND_TRUE) || is_key ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200432 3 + (int)((max_name_len - strlen(leaf->name)) - prefix_len), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200433
434 tree_print_type(f, &leaf->type);
435
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200436 if (leaf->dflt != NULL) {
437 fprintf(f, " <%s>", leaf->dflt);
438 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200439
440 tree_print_features(f, (const struct ly_feature **)leaf->features, leaf->features_size);
441
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200442 fprintf(f, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200443}
444
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200445static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200446tree_print_leaflist(FILE *f, struct ly_module *module, char *indent, unsigned int max_name_len, struct ly_mnode *mnode, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200447{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200448 struct ly_mnode_leaflist *leaflist = (struct ly_mnode_leaflist *)mnode;
Michal Vasko449afde2015-06-04 16:06:49 +0200449
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200450 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200451
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200452 fprintf(f, "%s%s--", indent,
453 (leaflist->flags & LY_NODE_STATUS_DEPRC ? "x" : (leaflist->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200454
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200455 if (spec_config == 0) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200456 fprintf(f, "%s ", (leaflist->flags & LY_NODE_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200457 } else if (spec_config == 1) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200458 fprintf(f, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200459 } else if (spec_config == 2) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200460 fprintf(f, "ro ");
461 }
462
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200463 if (module != leaflist->module) {
464 fprintf(f, "%s:", leaflist->module->prefix);
465 }
466
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200467 fprintf(f, "%s*%*s", leaflist->name, 3 + (int)(max_name_len - strlen(leaflist->name)), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200468
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200469 tree_print_type(f, &leaflist->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200470
Michal Vasko28c6b572015-06-18 12:43:31 +0200471 tree_print_features(f, (const struct ly_feature **)leaflist->features, leaflist->features_size);
472
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200473 fprintf(f, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200474}
475
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200476static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200477tree_print_list(FILE *f, struct ly_module *module, int level, char *indent, struct ly_mnode *mnode, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200478{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200479 int i;
480 unsigned int max_child_len;
481 char *new_indent;
482 struct ly_mnode *sub;
483 struct ly_mnode_list *list = (struct ly_mnode_list *)mnode;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200484
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200485 fprintf(f, "%s%s--", indent,
486 (list->flags & LY_NODE_STATUS_DEPRC ? "x" : (list->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200487
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200488 if (spec_config == 0) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200489 fprintf(f, "%s ", (list->flags & LY_NODE_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200490 } else if (spec_config == 1) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200491 fprintf(f, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200492 } else if (spec_config == 2) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200493 fprintf(f, "ro ");
494 }
495
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200496 if (module != list->module) {
497 fprintf(f, "%s:", list->module->prefix);
498 }
499
Michal Vaskob5c75d72015-06-15 12:16:52 +0200500 fprintf(f, "%s*", list->name);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200501
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200502 for (i = 0; i < list->keys_size; i++) {
503 if (i == 0) {
504 fprintf(f, " [");
505 }
506 fprintf(f, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? "," : "]");
507 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200508
Michal Vasko28c6b572015-06-18 12:43:31 +0200509 tree_print_features(f, (const struct ly_feature **)list->features, list->features_size);
510
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200511 fprintf(f, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200512
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200513 level++;
514 new_indent = create_indent(level, indent, mnode, 0);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200515
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200516 max_child_len = get_max_name_len(module, mnode->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200517
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200518 LY_TREE_FOR(mnode->child, sub) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200519 tree_print_mnode(f, module, level, new_indent, max_child_len, sub,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200520 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_USES | LY_NODE_ANYXML,
521 spec_config);
522 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200523
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200524 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200525}
526
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200527static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200528tree_print_uses(FILE *f, struct ly_module *module, int level, char *indent, unsigned int max_name_len, struct ly_mnode *mnode, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200529{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200530 struct ly_mnode *node;
531 struct ly_mnode_uses *uses = (struct ly_mnode_uses *)mnode;
Radek Krejci7e97c352015-06-19 16:26:34 +0200532
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200533 LY_TREE_FOR(uses->child, node) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200534 tree_print_mnode(f, module, level, indent, max_name_len, node,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200535 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_USES | LY_NODE_ANYXML,
536 spec_config);
537 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200538}
539
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200540static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200541tree_print_rpc(FILE *f, struct ly_module *module, int level, char *indent, struct ly_mnode *mnode)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200542{
543 char *new_indent;
544 struct ly_mnode *node;
545 struct ly_mnode_rpc *rpc = (struct ly_mnode_rpc *)mnode;
Radek Krejci7e97c352015-06-19 16:26:34 +0200546 int i;
547
548 /* stop if features are not enabled */
549 for (i = 0; i < rpc->features_size; i++) {
550 if (!(rpc->features[i]->flags & LY_NODE_FENABLED)) {
551 return;
552 }
553 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200554
Michal Vasko28c6b572015-06-18 12:43:31 +0200555 fprintf(f, "%s%s---x %s", indent,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200556 (rpc->flags & LY_NODE_STATUS_DEPRC ? "x" : (rpc->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")), rpc->name);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200557
Michal Vasko28c6b572015-06-18 12:43:31 +0200558 tree_print_features(f, (const struct ly_feature **)rpc->features, rpc->features_size);
559
560 fprintf(f, "\n");
561
Michal Vaskob5c75d72015-06-15 12:16:52 +0200562 level++;
563 new_indent = create_indent(level, indent, mnode, 0);
564
565 LY_TREE_FOR(rpc->child, node) {
566 if (node->nodetype == LY_NODE_INPUT) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200567 tree_print_input_output(f, module, level, new_indent, node, 1);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200568 } else if (node->nodetype == LY_NODE_OUTPUT) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200569 tree_print_input_output(f, module, level, new_indent, node, 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200570 }
571 }
572
573 free(new_indent);
574}
575
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200576static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200577tree_print_notif(FILE *f, struct ly_module *module, int level, char *indent, struct ly_mnode *mnode)
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200578{
579 unsigned int max_child_len;
580 char *new_indent;
581 struct ly_mnode *node;
582 struct ly_mnode_notif *notif = (struct ly_mnode_notif *)mnode;
Radek Krejci7e97c352015-06-19 16:26:34 +0200583 int i;
584
585 /* stop if features are not enabled */
586 for (i = 0; i < notif->features_size; i++) {
587 if (!(notif->features[i]->flags & LY_NODE_FENABLED)) {
588 return;
589 }
590 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200591
Michal Vasko28c6b572015-06-18 12:43:31 +0200592 fprintf(f, "%s%s---n %s", indent,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200593 (notif->flags & LY_NODE_STATUS_DEPRC ? "x" : (notif->flags & LY_NODE_STATUS_OBSLT ? "o" : "+")),
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200594 notif->name);
595
Michal Vasko28c6b572015-06-18 12:43:31 +0200596 tree_print_features(f, (const struct ly_feature **)notif->features, notif->features_size);
597
598 fprintf(f, "\n");
599
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200600 level++;
601 new_indent = create_indent(level, indent, mnode, 0);
602
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200603 max_child_len = get_max_name_len(module, mnode->child);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200604
605 LY_TREE_FOR(notif->child, node) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200606 tree_print_mnode(f, module, level, new_indent, max_child_len, node,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200607 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_USES,
608 2);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200609 }
610
611 free(new_indent);
612}
613
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200614static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200615tree_print_mnode_choice(FILE *f, struct ly_module *module, int level, char *indent, unsigned int max_name_len, struct ly_mnode *mnode, int mask,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200616 int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200617{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200618 if (mnode->nodetype & mask) {
619 if (mnode->nodetype == LY_NODE_CASE) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200620 tree_print_case(f, module, level, indent, max_name_len, mnode, 0, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200621 } else {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200622 tree_print_case(f, module, level, indent, max_name_len, mnode, 1, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200623 }
624 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200625}
626
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200627static void
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200628tree_print_mnode(FILE *f, struct ly_module *module, int level, char *indent, unsigned int max_name_len, struct ly_mnode *mnode, int mask,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200629 int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200630{
Radek Krejci87e840c2015-06-19 16:44:54 +0200631 int i;
632
633 /* stop if features are not enabled */
634 for (i = 0; i < mnode->features_size; i++) {
635 if (!(mnode->features[i]->flags & LY_NODE_FENABLED)) {
636 return;
637 }
638 }
639 /* or if the data are from augment under a not enabled feature */
640 if (mnode->parent && mnode->parent->nodetype == LY_NODE_AUGMENT) {
641 for (i = 0; i < mnode->parent->features_size; i++) {
642 if (!(mnode->parent->features[i]->flags & LY_NODE_FENABLED)) {
643 return;
644 }
645 }
646 }
647
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200648 switch (mnode->nodetype & mask) {
649 case LY_NODE_CONTAINER:
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200650 tree_print_container(f, module, level, indent, mnode, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200651 break;
652 case LY_NODE_CHOICE:
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200653 tree_print_choice(f, module, level, indent, mnode, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200654 break;
655 case LY_NODE_LEAF:
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200656 tree_print_leaf(f, module, indent, max_name_len, mnode, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200657 break;
658 case LY_NODE_LEAFLIST:
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200659 tree_print_leaflist(f, module, indent, max_name_len, mnode, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200660 break;
661 case LY_NODE_LIST:
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200662 tree_print_list(f, module, level, indent, mnode, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200663 break;
664 case LY_NODE_ANYXML:
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200665 tree_print_anyxml(f, module, indent, max_name_len, mnode, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200666 break;
667 case LY_NODE_USES:
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200668 tree_print_uses(f, module, level, indent, max_name_len, mnode, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200669 break;
670 default:
671 break;
672 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200673}
674
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200675int
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200676tree_print_model(FILE *f, struct ly_module *module)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200677{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200678 struct ly_mnode *mnode;
679 unsigned int max_child_len;
680 int level = 1, i, have_rpcs = 0, have_notifs = 0;
681 char *indent = malloc((level * 4 + 1) * sizeof (char));
682 strcpy(indent, " ");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200683
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200684 fprintf(f, "module: %s\n", module->name);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200685
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200686 /* included submodules */
687 for (i = 0; i < module->inc_size; i++) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200688 max_child_len = get_max_name_len((struct ly_module *)module->inc[i].submodule, module->inc[i].submodule->data);
Michal Vasko8d479bd2015-06-05 10:50:03 +0200689
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200690 LY_TREE_FOR(module->inc[i].submodule->data, mnode) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200691 tree_print_mnode(f, (struct ly_module *)module->inc[i].submodule, level, indent, max_child_len, mnode,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200692 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_USES,
693 0);
694 }
695 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200696
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200697 /* module */
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200698 max_child_len = get_max_name_len(module, module->data);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200699 level++;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200700
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200701 LY_TREE_FOR(module->data, mnode) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200702 tree_print_mnode(f, module, level, indent, max_child_len, mnode,
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200703 LY_NODE_CHOICE | LY_NODE_CONTAINER | LY_NODE_LEAF | LY_NODE_LEAFLIST | LY_NODE_LIST | LY_NODE_ANYXML | LY_NODE_USES,
704 0);
705 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200706
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200707 /* rpc */
708 if (module->rpc) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200709 have_rpcs = 1;
710 } else {
711 for (i = 0; i < module->inc_size; i++) {
712 if (module->inc[i].submodule->rpc) {
713 have_rpcs = 1;
714 break;
715 }
716 }
717 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200718 if (have_rpcs) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200719 fprintf(f, "rpcs:\n");
720 for (i = 0; i < module->inc_size; i++) {
721 LY_TREE_FOR(module->inc[i].submodule->rpc, mnode) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200722 tree_print_rpc(f, (struct ly_module *)module->inc[i].submodule, level, indent, mnode);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200723 }
724 }
725 LY_TREE_FOR(module->rpc, mnode) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200726 tree_print_rpc(f, module, level, indent, mnode);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200727 }
728 }
Michal Vasko449afde2015-06-04 16:06:49 +0200729
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200730 /* notification */
731 if (module->notif) {
732 have_notifs = 1;
733 } else {
734 for (i = 0; i < module->inc_size; i++) {
735 if (module->inc[i].submodule->notif) {
736 have_notifs = 1;
737 break;
738 }
739 }
740 }
741 if (have_notifs) {
742 fprintf(f, "notifications:\n");
743 for (i = 0; i < module->inc_size; i++) {
744 LY_TREE_FOR(module->inc[i].submodule->notif, mnode) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200745 tree_print_notif(f, (struct ly_module *)module->inc[i].submodule, level, indent, mnode);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200746 }
747 }
748 LY_TREE_FOR(module->notif, mnode) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200749 tree_print_notif(f, module, level, indent, mnode);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200750 }
751 }
Michal Vasko449afde2015-06-04 16:06:49 +0200752
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200753 free(indent);
754 return EXIT_SUCCESS;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200755}