blob: 905453e38eabb83a7a1f0af4f45e90a37341be1f [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
Radek Krejci998a0b82015-08-17 13:14:36 +020027#include "common.h"
Radek Krejci76b07902015-10-09 09:11:25 +020028#include "printer.h"
Michal Vasko2d162e12015-09-24 14:33:29 +020029#include "tree_schema.h"
Michal Vasko5ed10f12015-06-04 10:04:57 +020030
Michal Vaskoe03bfbb2015-06-16 09:07:49 +020031/* spec_config = 0 (no special config status), 1 (read-only - rpc output, notification), 2 (write-only - rpc input) */
Michal Vasko1e62a092015-12-01 12:27:20 +010032static void tree_print_choice_content(struct lyout *out, const struct lys_module* module, int level, char *indent,
33 unsigned int max_name_len, const struct lys_node *node, int mask,
34 int spec_config, const struct lys_submodule *main_submod);
35static void tree_print_snode(struct lyout *out, const struct lys_module *module, int level, char *indent,
36 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config,
37 const struct lys_submodule *main_submod);
Michal Vasko5ed10f12015-06-04 10:04:57 +020038
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020039static int
Radek Krejci1d82ef62015-08-07 14:44:40 +020040sibling_is_valid_child(const struct lys_node *node, int including)
Michal Vasko6db4fce2015-06-08 14:13:49 +020041{
Radek Krejci76512572015-08-04 09:47:08 +020042 struct lys_node *cur;
Michal Vasko7ea0a312015-06-08 10:36:48 +020043
Radek Krejci1d82ef62015-08-07 14:44:40 +020044 if (node == NULL) {
Michal Vasko07898f92015-06-15 12:17:11 +020045 return 0;
46 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020047
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020048 /* has a following printed child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020049 LY_TREE_FOR((struct lys_node *)(including ? node : node->next), cur) {
Michal Vaskof6f18f42015-09-24 13:06:14 +020050 if (!lys_is_disabled(cur, 0)) {
51 if (cur->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_CHOICE |
52 LYS_RPC | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF | LYS_CASE)) {
53 return 1;
54 }
55 if ((cur->nodetype == LYS_USES) && sibling_is_valid_child(cur->child, 1)) {
56 return 1;
57 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020058 }
59 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020060
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020061 /* if in uses, the following printed child can actually be in the parent node :-/ */
Radek Krejci1d82ef62015-08-07 14:44:40 +020062 if (node->parent && node->parent->nodetype == LYS_USES) {
63 return sibling_is_valid_child(node->parent, 0);
Michal Vasko07898f92015-06-15 12:17:11 +020064 }
65
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020066 return 0;
Michal Vasko7ea0a312015-06-08 10:36:48 +020067}
68
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020069static char *
Michal Vasko1e62a092015-12-01 12:27:20 +010070create_indent(int level, const char *old_indent, const struct lys_node *node, int shorthand,
71 const struct lys_submodule *main_submod)
Michal Vasko449afde2015-06-04 16:06:49 +020072{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020073 int next_is_case = 0, is_case = 0, has_next = 0, i, found;
74 char *new_indent = malloc((level * 4 + 1) * sizeof (char));
Michal Vasko14410462015-06-05 15:08:54 +020075
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020076 strcpy(new_indent, old_indent);
Michal Vasko14410462015-06-05 15:08:54 +020077
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020078 /* this is the indent of a case (standard or shorthand) */
Radek Krejci1d82ef62015-08-07 14:44:40 +020079 if ((node->nodetype == LYS_CASE) || shorthand) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020080 is_case = 1;
81 }
Michal Vasko14410462015-06-05 15:08:54 +020082
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020083 /* this is the direct child of a case */
Radek Krejci1d82ef62015-08-07 14:44:40 +020084 if (!is_case && node->parent && (node->parent->nodetype & (LYS_CASE | LYS_CHOICE))) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020085 /* it is not the only child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020086 if (node->next && node->next->parent && (node->next->parent->nodetype == LYS_CHOICE)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020087 next_is_case = 1;
88 }
89 }
Michal Vasko14410462015-06-05 15:08:54 +020090
Michal Vasko07898f92015-06-15 12:17:11 +020091 /* next is a node that will actually be printed */
Radek Krejci1d82ef62015-08-07 14:44:40 +020092 has_next = sibling_is_valid_child(node, 0);
Michal Vasko14410462015-06-05 15:08:54 +020093
Michal Vasko07898f92015-06-15 12:17:11 +020094 /* there is no next, but we are in top-level of a submodule */
Radek Krejci1d82ef62015-08-07 14:44:40 +020095 if (!has_next && (node->module->type == 1) && !node->parent) {
96 struct lys_submodule *submod = (struct lys_submodule *)node->module;
Radek Krejcib8048692015-08-05 13:36:34 +020097 struct lys_module *mod = submod->belongsto;
Michal Vasko14410462015-06-05 15:08:54 +020098
Michal Vasko64448d72015-07-08 13:35:24 +020099 /* a special case when we check the includes of a submodule */
100 if (main_submod) {
101 if (submod != main_submod) {
102 found = 0;
103 for (i = 0; i < main_submod->inc_size; i++) {
104 if (found) {
Radek Krejci92720552015-10-05 15:28:27 +0200105 has_next = sibling_is_valid_child(main_submod->inc[i].submodule->data, 1);
Michal Vasko64448d72015-07-08 13:35:24 +0200106 if (has_next) {
107 break;
108 }
109 }
110 if (!found && (submod == main_submod->inc[i].submodule)) {
111 found = 1;
112 }
113 }
114
115 if (!has_next) {
Radek Krejci92720552015-10-05 15:28:27 +0200116 has_next = sibling_is_valid_child(main_submod->data, 1);
Michal Vasko64448d72015-07-08 13:35:24 +0200117 }
118 }
119
120 goto strcat_indent;
121 }
122
Michal Vasko07898f92015-06-15 12:17:11 +0200123 /* find this submodule, check all the next ones for valid printed nodes */
124 found = 0;
125 for (i = 0; i < mod->inc_size; i++) {
126 /* we found ours, check all the following submodules and the module */
127 if (found) {
Radek Krejci92720552015-10-05 15:28:27 +0200128 has_next = sibling_is_valid_child(mod->inc[i].submodule->data, 1);
Michal Vasko5c7686d2015-07-08 13:36:21 +0200129 if (has_next) {
130 break;
131 }
Michal Vasko07898f92015-06-15 12:17:11 +0200132 }
Michal Vasko5c7686d2015-07-08 13:36:21 +0200133 if (!found && (submod == mod->inc[i].submodule)) {
Michal Vasko07898f92015-06-15 12:17:11 +0200134 found = 1;
135 }
136 }
Michal Vasko7ea0a312015-06-08 10:36:48 +0200137
Michal Vasko07898f92015-06-15 12:17:11 +0200138 /* there is nothing in submodules, check module */
139 if (!has_next) {
Radek Krejci92720552015-10-05 15:28:27 +0200140 has_next = sibling_is_valid_child(mod->data, 1);
Michal Vasko07898f92015-06-15 12:17:11 +0200141 }
142 }
143
Michal Vasko64448d72015-07-08 13:35:24 +0200144strcat_indent:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200145 if (has_next && !next_is_case) {
146 strcat(new_indent, "| ");
147 } else {
148 strcat(new_indent, " ");
149 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200150
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200151 return new_indent;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200152}
153
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200154static unsigned int
Michal Vasko1e62a092015-12-01 12:27:20 +0100155get_max_name_len(const struct lys_module *module, const struct lys_node *node)
Michal Vasko8d479bd2015-06-05 10:50:03 +0200156{
Michal Vasko1e62a092015-12-01 12:27:20 +0100157 const struct lys_node *sub;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200158 unsigned int max_name_len = 0, uses_max_name_len, name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200159
Radek Krejci1d82ef62015-08-07 14:44:40 +0200160 LY_TREE_FOR(node, sub) {
Radek Krejci76512572015-08-04 09:47:08 +0200161 if (sub->nodetype == LYS_USES) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200162 uses_max_name_len = get_max_name_len(module, sub->child);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200163 if (uses_max_name_len > max_name_len) {
164 max_name_len = uses_max_name_len;
165 }
166 } else if (sub->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200167 (LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
168 | LYS_ANYXML | LYS_CASE)) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200169 name_len = strlen(sub->name) + (module == sub->module ? 0 : strlen(sub->module->prefix)+1);
170 if (name_len > max_name_len) {
171 max_name_len = name_len;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200172 }
173 }
174 }
Michal Vasko8d479bd2015-06-05 10:50:03 +0200175
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200176 return max_name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200177}
178
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200179static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100180tree_print_type(struct lyout *out, const struct lys_type *type)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200181{
Michal Vasko2d22b2d2015-09-24 13:53:31 +0200182 if ((type->base == LY_TYPE_LEAFREF) && !type->der->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200183 ly_print(out, "-> %s", type->info.lref.path);
Michal Vasko1dca6882015-10-22 14:29:42 +0200184 } else if (type->module_name) {
185 ly_print(out, "%s:%s", type->module_name, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200186 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200187 ly_print(out, "%s", type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200188 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200189}
190
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200191static void
Radek Krejci76b07902015-10-09 09:11:25 +0200192tree_print_features(struct lyout *out, const struct lys_feature **features, uint8_t features_size)
Michal Vasko28c6b572015-06-18 12:43:31 +0200193{
194 int i;
195
196 if (!features_size) {
197 return;
198 }
199
Radek Krejci76b07902015-10-09 09:11:25 +0200200 ly_print(out, " {");
Michal Vasko28c6b572015-06-18 12:43:31 +0200201 for (i = 0; i < features_size; i++) {
202 if (i > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200203 ly_print(out, ",");
Michal Vasko28c6b572015-06-18 12:43:31 +0200204 }
Radek Krejci76b07902015-10-09 09:11:25 +0200205 ly_print(out, "%s", features[i]->name);
Michal Vasko28c6b572015-06-18 12:43:31 +0200206 }
Radek Krejci76b07902015-10-09 09:11:25 +0200207 ly_print(out, "}?");
Michal Vasko28c6b572015-06-18 12:43:31 +0200208}
209
210static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100211tree_print_inout(struct lyout *out, const struct lys_module *module, int level, char *indent,
212 const struct lys_node *node, int spec_config, const struct lys_submodule *main_submod)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200213{
214 unsigned int max_child_len;
215 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200216 struct lys_node *sub;
Michal Vaskob5c75d72015-06-15 12:16:52 +0200217
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200218 assert(spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200219
Radek Krejci76b07902015-10-09 09:11:25 +0200220 ly_print(out, "%s+--%s %s\n", indent, (spec_config == 1 ? "-w" : "ro"), (spec_config == 1 ? "input" : "output"));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200221
222 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200223 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200224
Radek Krejci1d82ef62015-08-07 14:44:40 +0200225 max_child_len = get_max_name_len(module, node->child);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200226
Radek Krejci1d82ef62015-08-07 14:44:40 +0200227 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200228 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200229 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200230 spec_config, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200231 }
232
233 free(new_indent);
234}
235
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200236static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100237tree_print_container(struct lyout *out, const struct lys_module *module, int level, char *indent,
238 const struct lys_node *node, int spec_config, const struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200239{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200240 unsigned int max_child_len;
241 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200242 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200243 struct lys_node *sub;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200244
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200245 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200246
Radek Krejci76b07902015-10-09 09:11:25 +0200247 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200248 (cont->flags & LYS_STATUS_DEPRC ? "x" : (cont->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200249
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200250 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200251 ly_print(out, "%s ", (cont->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200252 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200253 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200254 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200255 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200256 }
257
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200258 if (module != cont->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200259 ly_print(out, "%s:", cont->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200260 }
261
Radek Krejci76b07902015-10-09 09:11:25 +0200262 ly_print(out, "%s%s", cont->name, (cont->presence ? "!" : ""));
Michal Vasko28c6b572015-06-18 12:43:31 +0200263
Radek Krejci76b07902015-10-09 09:11:25 +0200264 tree_print_features(out, (const struct lys_feature **)cont->features, cont->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200265
Radek Krejci76b07902015-10-09 09:11:25 +0200266 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200267
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200268 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200269 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200270
Radek Krejci1d82ef62015-08-07 14:44:40 +0200271 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200272
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200273 LY_TREE_FOR(cont->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200274 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200275 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200276 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200277 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200278
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200279 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200280}
281
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200282static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100283tree_print_choice(struct lyout *out, const struct lys_module *module, int level, char *indent,
284 const struct lys_node *node, int spec_config, const struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200285{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200286 unsigned int max_child_len;
287 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200288 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200289 struct lys_node *sub;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200290
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200291 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200292
Radek Krejci76b07902015-10-09 09:11:25 +0200293 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200294 (choice->flags & LYS_STATUS_DEPRC ? "x" : (choice->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200295
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200296 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200297 ly_print(out, "%s ", (choice->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200298 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200299 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200300 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200301 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200302 }
303
Radek Krejci76b07902015-10-09 09:11:25 +0200304 ly_print(out, "(");
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200305
306 if (module != choice->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200307 ly_print(out, "%s:", choice->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200308 }
309
Radek Krejci76b07902015-10-09 09:11:25 +0200310 ly_print(out, "%s)%s", choice->name, (choice->flags & LYS_MAND_TRUE ? "" : "?"));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200311
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200312 if (choice->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200313 ly_print(out, " <%s>", choice->dflt->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200314 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200315
Radek Krejci76b07902015-10-09 09:11:25 +0200316 tree_print_features(out, (const struct lys_feature **)choice->features, choice->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200317
Radek Krejci76b07902015-10-09 09:11:25 +0200318 ly_print(out, "\n");
Michal Vasko449afde2015-06-04 16:06:49 +0200319
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200320 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200321 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vasko449afde2015-06-04 16:06:49 +0200322
Radek Krejci1d82ef62015-08-07 14:44:40 +0200323 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200324
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200325 LY_TREE_FOR(choice->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200326 tree_print_choice_content(out, module, level, new_indent, max_child_len, sub,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200327 LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML,
328 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200329 }
Michal Vasko449afde2015-06-04 16:06:49 +0200330
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200331 free(new_indent);
Michal Vasko449afde2015-06-04 16:06:49 +0200332}
333
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200334static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100335tree_print_case(struct lyout *out, const struct lys_module *module, int level, char *indent, unsigned int max_name_len,
336 const struct lys_node *node, int shorthand, int spec_config, const struct lys_submodule *main_submod)
Michal Vasko449afde2015-06-04 16:06:49 +0200337{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200338 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200339 struct lys_node_case *cas = (struct lys_node_case *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200340 struct lys_node *sub;
Radek Krejci7e97c352015-06-19 16:26:34 +0200341
Radek Krejci76b07902015-10-09 09:11:25 +0200342 ly_print(out, "%s%s--:(", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200343 (cas->flags & LYS_STATUS_DEPRC ? "x" : (cas->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200344
345 if (module != cas->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200346 ly_print(out, "%s:", cas->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200347 }
348
Radek Krejci76b07902015-10-09 09:11:25 +0200349 ly_print(out, "%s)", cas->name);
Michal Vasko449afde2015-06-04 16:06:49 +0200350
Radek Krejci76b07902015-10-09 09:11:25 +0200351 tree_print_features(out, (const struct lys_feature **)cas->features, cas->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200352
Radek Krejci76b07902015-10-09 09:11:25 +0200353 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200354
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200355 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200356 new_indent = create_indent(level, indent, node, shorthand, main_submod);
Michal Vasko449afde2015-06-04 16:06:49 +0200357
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200358 if (shorthand) {
Radek Krejci76b07902015-10-09 09:11:25 +0200359 tree_print_snode(out, module, level, new_indent, max_name_len, node,
Radek Krejci76512572015-08-04 09:47:08 +0200360 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200361 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200362 } else {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200363 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200364 tree_print_snode(out, module, level, new_indent, max_name_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200365 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200366 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200367 }
368 }
Michal Vasko449afde2015-06-04 16:06:49 +0200369
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200370 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200371}
372
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200373static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100374tree_print_anyxml(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
375 const struct lys_node *node, int spec_config)
Michal Vasko315f70b2015-06-05 10:48:59 +0200376{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200377 uint8_t prefix_len;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200378 struct lys_node_anyxml *anyxml = (struct lys_node_anyxml *)node;
Michal Vasko315f70b2015-06-05 10:48:59 +0200379
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200380 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200381
Radek Krejci76b07902015-10-09 09:11:25 +0200382 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200383 (anyxml->flags & LYS_STATUS_DEPRC ? "x" : (anyxml->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200384
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200385 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200386 ly_print(out, "%s ", (anyxml->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200387 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200388 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200389 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200390 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200391 }
392
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200393 prefix_len = 0;
394 if (module != anyxml->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200395 ly_print(out, "%s:", anyxml->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200396 prefix_len = strlen(anyxml->module->prefix)+1;
397 }
398
Radek Krejci76b07902015-10-09 09:11:25 +0200399 ly_print(out, "%s%s%*sanyxml", anyxml->name, (anyxml->flags & LYS_MAND_TRUE ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200400 3 + (int)((max_name_len - strlen(anyxml->name)) - prefix_len), " ");
Michal Vasko28c6b572015-06-18 12:43:31 +0200401
Radek Krejci76b07902015-10-09 09:11:25 +0200402 tree_print_features(out, (const struct lys_feature **)anyxml->features, anyxml->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200403
Radek Krejci76b07902015-10-09 09:11:25 +0200404 ly_print(out, "\n");
Michal Vasko315f70b2015-06-05 10:48:59 +0200405}
406
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200407static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100408tree_print_leaf(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
409 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200410{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200411 uint8_t prefix_len;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200412 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200413 struct lys_node *parent;
Radek Krejcib8048692015-08-05 13:36:34 +0200414 struct lys_node_list *list;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200415 int i, is_key = 0;
Michal Vasko449afde2015-06-04 16:06:49 +0200416
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200417 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200418
Radek Krejci69372e22015-08-13 09:55:27 +0200419 /* get know if the leaf is a key in a list, in that case it is
420 * mandatory by default */
Radek Krejci76512572015-08-04 09:47:08 +0200421 for (parent = leaf->parent; parent && parent->nodetype == LYS_USES; parent = parent->parent);
Radek Krejci69372e22015-08-13 09:55:27 +0200422 if (parent && parent->nodetype == LYS_LIST) {
Radek Krejcib8048692015-08-05 13:36:34 +0200423 list = (struct lys_node_list *)parent;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200424 for (i = 0; i < list->keys_size; i++) {
Michal Vasko96929d92015-08-03 15:30:22 +0200425 if (list->keys[i] == leaf) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200426 is_key = 1;
427 break;
428 }
429 }
430 }
Michal Vasko449afde2015-06-04 16:06:49 +0200431
Radek Krejci76b07902015-10-09 09:11:25 +0200432 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200433 (leaf->flags & LYS_STATUS_DEPRC ? "x" : (leaf->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200434
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200435 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200436 ly_print(out, "%s ", (leaf->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200437 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200438 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200439 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200440 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200441 }
442
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200443 prefix_len = 0;
444 if (module != leaf->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200445 ly_print(out, "%s:", leaf->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200446 prefix_len = strlen(leaf->module->prefix)+1;
447 }
448
Radek Krejci76b07902015-10-09 09:11:25 +0200449 ly_print(out, "%s%s%*s", leaf->name, ((leaf->flags & LYS_MAND_TRUE) || is_key ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200450 3 + (int)((max_name_len - strlen(leaf->name)) - prefix_len), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200451
Radek Krejci76b07902015-10-09 09:11:25 +0200452 tree_print_type(out, &leaf->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200453
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200454 if (leaf->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200455 ly_print(out, " <%s>", leaf->dflt);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200456 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200457
Radek Krejci76b07902015-10-09 09:11:25 +0200458 tree_print_features(out, (const struct lys_feature **)leaf->features, leaf->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200459
Radek Krejci76b07902015-10-09 09:11:25 +0200460 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200461}
462
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200463static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100464tree_print_leaflist(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
465 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200466{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200467 struct lys_node_leaflist *leaflist = (struct lys_node_leaflist *)node;
Michal Vasko449afde2015-06-04 16:06:49 +0200468
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200469 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200470
Radek Krejci76b07902015-10-09 09:11:25 +0200471 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200472 (leaflist->flags & LYS_STATUS_DEPRC ? "x" : (leaflist->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200473
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200474 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200475 ly_print(out, "%s ", (leaflist->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200476 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200477 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200478 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200479 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200480 }
481
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200482 if (module != leaflist->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200483 ly_print(out, "%s:", leaflist->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200484 }
485
Radek Krejci76b07902015-10-09 09:11:25 +0200486 ly_print(out, "%s*%*s", leaflist->name, 3 + (int)(max_name_len - strlen(leaflist->name)), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200487
Radek Krejci76b07902015-10-09 09:11:25 +0200488 tree_print_type(out, &leaflist->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200489
Radek Krejci76b07902015-10-09 09:11:25 +0200490 tree_print_features(out, (const struct lys_feature **)leaflist->features, leaflist->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200491
Radek Krejci76b07902015-10-09 09:11:25 +0200492 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200493}
494
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200495static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100496tree_print_list(struct lyout *out, const struct lys_module *module, int level, char *indent,
497 const struct lys_node *node, int spec_config, const struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200498{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200499 int i;
500 unsigned int max_child_len;
501 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200502 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200503 struct lys_node_list *list = (struct lys_node_list *)node;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200504
Radek Krejci76b07902015-10-09 09:11:25 +0200505 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200506 (list->flags & LYS_STATUS_DEPRC ? "x" : (list->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200507
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200508 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200509 ly_print(out, "%s ", (list->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200510 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200511 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200512 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200513 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200514 }
515
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200516 if (module != list->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200517 ly_print(out, "%s:", list->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200518 }
519
Radek Krejci76b07902015-10-09 09:11:25 +0200520 ly_print(out, "%s*", list->name);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200521
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200522 for (i = 0; i < list->keys_size; i++) {
523 if (i == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200524 ly_print(out, " [");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200525 }
Radek Krejcif3966532015-12-09 14:19:35 +0100526 ly_print(out, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "]");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200527 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200528
Radek Krejci76b07902015-10-09 09:11:25 +0200529 tree_print_features(out, (const struct lys_feature **)list->features, list->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200530
Radek Krejci76b07902015-10-09 09:11:25 +0200531 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200532
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200533 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200534 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200535
Radek Krejci1d82ef62015-08-07 14:44:40 +0200536 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200537
Radek Krejci1d82ef62015-08-07 14:44:40 +0200538 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200539 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200540 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Michal Vasko64448d72015-07-08 13:35:24 +0200541 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200542 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200543
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200544 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200545}
546
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200547static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100548tree_print_uses(struct lyout *out, const struct lys_module *module, int level, char *indent, unsigned int max_name_len,
549 const struct lys_node *node, int spec_config, const struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200550{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200551 struct lys_node *child;
552 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200553
Radek Krejci1d82ef62015-08-07 14:44:40 +0200554 LY_TREE_FOR(uses->child, child) {
Radek Krejci76b07902015-10-09 09:11:25 +0200555 tree_print_snode(out, module, level, indent, max_name_len, child,
Radek Krejci76512572015-08-04 09:47:08 +0200556 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Michal Vasko64448d72015-07-08 13:35:24 +0200557 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200558 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200559}
560
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200561static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100562tree_print_rpc(struct lyout *out, const struct lys_module *module, int level, char *indent,
563 const struct lys_node *node, const struct lys_submodule *main_submod)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200564{
565 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200566 struct lys_node *child;
567 struct lys_node_rpc *rpc = (struct lys_node_rpc *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200568
Radek Krejci1d82ef62015-08-07 14:44:40 +0200569 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200570 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200571 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200572
Radek Krejci76b07902015-10-09 09:11:25 +0200573 ly_print(out, "%s%s---x %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200574 (rpc->flags & LYS_STATUS_DEPRC ? "x" : (rpc->flags & LYS_STATUS_OBSLT ? "o" : "+")), rpc->name);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200575
Radek Krejci76b07902015-10-09 09:11:25 +0200576 tree_print_features(out, (const struct lys_feature **)rpc->features, rpc->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200577
Radek Krejci76b07902015-10-09 09:11:25 +0200578 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200579
Michal Vaskob5c75d72015-06-15 12:16:52 +0200580 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200581 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200582
Radek Krejci1d82ef62015-08-07 14:44:40 +0200583 LY_TREE_FOR(rpc->child, child) {
584 if (child->nodetype == LYS_INPUT) {
Radek Krejci76b07902015-10-09 09:11:25 +0200585 tree_print_inout(out, module, level, new_indent, child, 1, main_submod);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200586 } else if (child->nodetype == LYS_OUTPUT) {
Radek Krejci76b07902015-10-09 09:11:25 +0200587 tree_print_inout(out, module, level, new_indent, child, 2, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200588 }
589 }
590
591 free(new_indent);
592}
593
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200594static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100595tree_print_notif(struct lyout *out, const struct lys_module *module, int level, char *indent,
596 const struct lys_node *node, const struct lys_submodule *main_submod)
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200597{
598 unsigned int max_child_len;
599 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200600 struct lys_node *child;
601 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200602
Radek Krejci1d82ef62015-08-07 14:44:40 +0200603 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200604 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200605 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200606
Radek Krejci76b07902015-10-09 09:11:25 +0200607 ly_print(out, "%s%s---n %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200608 (notif->flags & LYS_STATUS_DEPRC ? "x" : (notif->flags & LYS_STATUS_OBSLT ? "o" : "+")),
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200609 notif->name);
610
Radek Krejci76b07902015-10-09 09:11:25 +0200611 tree_print_features(out, (const struct lys_feature **)notif->features, notif->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200612
Radek Krejci76b07902015-10-09 09:11:25 +0200613 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200614
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200615 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200616 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200617
Radek Krejci1d82ef62015-08-07 14:44:40 +0200618 max_child_len = get_max_name_len(module, node->child);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200619
Radek Krejci1d82ef62015-08-07 14:44:40 +0200620 LY_TREE_FOR(notif->child, child) {
Radek Krejci76b07902015-10-09 09:11:25 +0200621 tree_print_snode(out, module, level, new_indent, max_child_len, child,
Radek Krejci76512572015-08-04 09:47:08 +0200622 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200623 2, main_submod);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200624 }
625
626 free(new_indent);
627}
628
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200629static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100630tree_print_choice_content(struct lyout *out, const struct lys_module *module, int level, char *indent,
631 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config,
632 const struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200633{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200634 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200635 return;
636 }
637
Radek Krejci1d82ef62015-08-07 14:44:40 +0200638 if (node->nodetype & mask) {
639 if (node->nodetype == LYS_CASE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200640 tree_print_case(out, module, level, indent, max_name_len, node, 0, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200641 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200642 tree_print_case(out, module, level, indent, max_name_len, node, 1, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200643 }
644 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200645}
646
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200647static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100648tree_print_snode(struct lyout *out, const struct lys_module *module, int level, char *indent,
649 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config,
650 const struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200651{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200652 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200653 return;
Radek Krejci87e840c2015-06-19 16:44:54 +0200654 }
655
Radek Krejci1d82ef62015-08-07 14:44:40 +0200656 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +0200657 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +0200658 tree_print_container(out, module, level, indent, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200659 break;
Radek Krejci76512572015-08-04 09:47:08 +0200660 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +0200661 tree_print_choice(out, module, level, indent, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200662 break;
Radek Krejci76512572015-08-04 09:47:08 +0200663 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +0200664 tree_print_leaf(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200665 break;
Radek Krejci76512572015-08-04 09:47:08 +0200666 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +0200667 tree_print_leaflist(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200668 break;
Radek Krejci76512572015-08-04 09:47:08 +0200669 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +0200670 tree_print_list(out, module, level, indent, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200671 break;
Radek Krejci76512572015-08-04 09:47:08 +0200672 case LYS_ANYXML:
Radek Krejci76b07902015-10-09 09:11:25 +0200673 tree_print_anyxml(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200674 break;
Radek Krejci76512572015-08-04 09:47:08 +0200675 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +0200676 tree_print_uses(out, module, level, indent, max_name_len, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200677 break;
678 default:
679 break;
680 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200681}
682
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200683int
Michal Vasko1e62a092015-12-01 12:27:20 +0100684tree_print_model(struct lyout *out, const struct lys_module *module)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200685{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200686 struct lys_node *node;
Radek Krejcib8048692015-08-05 13:36:34 +0200687 struct lys_submodule *submod;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200688 unsigned int max_child_len;
689 int level = 1, i, have_rpcs = 0, have_notifs = 0;
690 char *indent = malloc((level * 4 + 1) * sizeof (char));
691 strcpy(indent, " ");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200692
Michal Vaskofc6ac172015-07-07 09:46:46 +0200693 if (module->type) {
Radek Krejcib8048692015-08-05 13:36:34 +0200694 submod = (struct lys_submodule *)module;
Radek Krejci76b07902015-10-09 09:11:25 +0200695 ly_print(out, "submodule: %s (belongs-to %s)\n", submod->name, submod->belongsto->name);
Michal Vaskofc6ac172015-07-07 09:46:46 +0200696 } else {
Michal Vasko64448d72015-07-08 13:35:24 +0200697 submod = NULL;
Radek Krejci76b07902015-10-09 09:11:25 +0200698 ly_print(out, "module: %s\n", module->name);
Michal Vaskofc6ac172015-07-07 09:46:46 +0200699 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200700
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200701 /* included submodules */
702 for (i = 0; i < module->inc_size; i++) {
Radek Krejcib8048692015-08-05 13:36:34 +0200703 max_child_len = get_max_name_len((struct lys_module *)module->inc[i].submodule, module->inc[i].submodule->data);
Michal Vasko8d479bd2015-06-05 10:50:03 +0200704
Radek Krejci1d82ef62015-08-07 14:44:40 +0200705 LY_TREE_FOR(module->inc[i].submodule->data, node) {
Radek Krejci76b07902015-10-09 09:11:25 +0200706 tree_print_snode(out, (struct lys_module *)module->inc[i].submodule, level, indent, max_child_len, node,
Radek Krejci76512572015-08-04 09:47:08 +0200707 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
708 | LYS_ANYXML | LYS_USES, 0, submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200709 }
710 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200711
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200712 /* module */
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200713 max_child_len = get_max_name_len(module, module->data);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200714 level++;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200715
Radek Krejci1d82ef62015-08-07 14:44:40 +0200716 LY_TREE_FOR(module->data, node) {
Radek Krejci92720552015-10-05 15:28:27 +0200717 switch(node->nodetype) {
718 case LYS_RPC:
719 have_rpcs++;
720 break;
721 case LYS_NOTIF:
722 have_notifs++;
723 break;
724 default:
Radek Krejcibac81762015-10-09 10:19:52 +0200725 tree_print_snode(out, module, level, indent, max_child_len, node,
Radek Krejci92720552015-10-05 15:28:27 +0200726 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
727 | LYS_ANYXML | LYS_USES, 0, submod);
728 break;
729 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200730 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200731
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200732 /* rpc */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200733 if (have_rpcs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200734 ly_print(out, "rpcs:\n");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200735 for (i = 0; i < module->inc_size; i++) {
Radek Krejci92720552015-10-05 15:28:27 +0200736 LY_TREE_FOR(module->inc[i].submodule->data, node) {
737 if (!have_rpcs) {
738 break;
739 }
740 if (node->nodetype == LYS_RPC) {
Radek Krejcibac81762015-10-09 10:19:52 +0200741 tree_print_rpc(out, (struct lys_module *)module->inc[i].submodule, level, indent, node, submod);
Radek Krejci92720552015-10-05 15:28:27 +0200742 have_rpcs--;
743 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200744 }
745 }
Radek Krejci92720552015-10-05 15:28:27 +0200746 LY_TREE_FOR(module->data, node) {
747 if (!have_rpcs) {
748 break;
749 }
750 if (node->nodetype == LYS_RPC) {
Radek Krejcibac81762015-10-09 10:19:52 +0200751 tree_print_rpc(out, module, level, indent, node, submod);
Radek Krejci92720552015-10-05 15:28:27 +0200752 have_rpcs--;
753 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200754 }
755 }
Michal Vasko449afde2015-06-04 16:06:49 +0200756
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200757 /* notification */
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200758 if (have_notifs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200759 ly_print(out, "notifications:\n");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200760 for (i = 0; i < module->inc_size; i++) {
Radek Krejci92720552015-10-05 15:28:27 +0200761 LY_TREE_FOR(module->inc[i].submodule->data, node) {
762 if (!have_notifs) {
763 break;
764 }
765 if (node->nodetype == LYS_NOTIF) {
Radek Krejcibac81762015-10-09 10:19:52 +0200766 tree_print_notif(out, (struct lys_module *)module->inc[i].submodule, level, indent, node, submod);
Radek Krejci92720552015-10-05 15:28:27 +0200767 have_notifs--;
768 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200769 }
770 }
Radek Krejci92720552015-10-05 15:28:27 +0200771 LY_TREE_FOR(module->data, node) {
772 if (!have_notifs) {
773 break;
774 }
775 if (node->nodetype == LYS_NOTIF) {
Radek Krejcibac81762015-10-09 10:19:52 +0200776 tree_print_notif(out, module, level, indent, node, submod);
Radek Krejci92720552015-10-05 15:28:27 +0200777 have_notifs--;
778 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200779 }
780 }
Michal Vasko449afde2015-06-04 16:06:49 +0200781
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200782 free(indent);
783 return EXIT_SUCCESS;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200784}