blob: 914671b2f3a9cfa90008ad2addfa7aa36f8adc3c [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) */
Radek Krejci76b07902015-10-09 09:11:25 +020032static void tree_print_choice_content(struct lyout *out, struct lys_module* module, int level, char *indent, unsigned int max_name_len,
Radek Krejci1d82ef62015-08-07 14:44:40 +020033 struct lys_node *node, int mask, int spec_config, struct lys_submodule *main_submod);
Radek Krejci76b07902015-10-09 09:11:25 +020034static void tree_print_snode(struct lyout *out, struct lys_module *module, int level, char *indent, unsigned int max_name_len, struct lys_node *node,
Radek Krejcib8048692015-08-05 13:36:34 +020035 int mask, int spec_config, struct lys_submodule *main_submod);
Michal Vasko5ed10f12015-06-04 10:04:57 +020036
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020037static int
Radek Krejci1d82ef62015-08-07 14:44:40 +020038sibling_is_valid_child(const struct lys_node *node, int including)
Michal Vasko6db4fce2015-06-08 14:13:49 +020039{
Radek Krejci76512572015-08-04 09:47:08 +020040 struct lys_node *cur;
Michal Vasko7ea0a312015-06-08 10:36:48 +020041
Radek Krejci1d82ef62015-08-07 14:44:40 +020042 if (node == NULL) {
Michal Vasko07898f92015-06-15 12:17:11 +020043 return 0;
44 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020045
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020046 /* has a following printed child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020047 LY_TREE_FOR((struct lys_node *)(including ? node : node->next), cur) {
Michal Vaskof6f18f42015-09-24 13:06:14 +020048 if (!lys_is_disabled(cur, 0)) {
49 if (cur->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_CHOICE |
50 LYS_RPC | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF | LYS_CASE)) {
51 return 1;
52 }
53 if ((cur->nodetype == LYS_USES) && sibling_is_valid_child(cur->child, 1)) {
54 return 1;
55 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020056 }
57 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020058
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020059 /* if in uses, the following printed child can actually be in the parent node :-/ */
Radek Krejci1d82ef62015-08-07 14:44:40 +020060 if (node->parent && node->parent->nodetype == LYS_USES) {
61 return sibling_is_valid_child(node->parent, 0);
Michal Vasko07898f92015-06-15 12:17:11 +020062 }
63
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020064 return 0;
Michal Vasko7ea0a312015-06-08 10:36:48 +020065}
66
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020067static char *
Radek Krejci1d82ef62015-08-07 14:44:40 +020068create_indent(int level, const char *old_indent, const struct lys_node *node, int shorthand, struct lys_submodule *main_submod)
Michal Vasko449afde2015-06-04 16:06:49 +020069{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020070 int next_is_case = 0, is_case = 0, has_next = 0, i, found;
71 char *new_indent = malloc((level * 4 + 1) * sizeof (char));
Michal Vasko14410462015-06-05 15:08:54 +020072
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020073 strcpy(new_indent, old_indent);
Michal Vasko14410462015-06-05 15:08:54 +020074
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020075 /* this is the indent of a case (standard or shorthand) */
Radek Krejci1d82ef62015-08-07 14:44:40 +020076 if ((node->nodetype == LYS_CASE) || shorthand) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020077 is_case = 1;
78 }
Michal Vasko14410462015-06-05 15:08:54 +020079
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020080 /* this is the direct child of a case */
Radek Krejci1d82ef62015-08-07 14:44:40 +020081 if (!is_case && node->parent && (node->parent->nodetype & (LYS_CASE | LYS_CHOICE))) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020082 /* it is not the only child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020083 if (node->next && node->next->parent && (node->next->parent->nodetype == LYS_CHOICE)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020084 next_is_case = 1;
85 }
86 }
Michal Vasko14410462015-06-05 15:08:54 +020087
Michal Vasko07898f92015-06-15 12:17:11 +020088 /* next is a node that will actually be printed */
Radek Krejci1d82ef62015-08-07 14:44:40 +020089 has_next = sibling_is_valid_child(node, 0);
Michal Vasko14410462015-06-05 15:08:54 +020090
Michal Vasko07898f92015-06-15 12:17:11 +020091 /* there is no next, but we are in top-level of a submodule */
Radek Krejci1d82ef62015-08-07 14:44:40 +020092 if (!has_next && (node->module->type == 1) && !node->parent) {
93 struct lys_submodule *submod = (struct lys_submodule *)node->module;
Radek Krejcib8048692015-08-05 13:36:34 +020094 struct lys_module *mod = submod->belongsto;
Michal Vasko14410462015-06-05 15:08:54 +020095
Michal Vasko64448d72015-07-08 13:35:24 +020096 /* a special case when we check the includes of a submodule */
97 if (main_submod) {
98 if (submod != main_submod) {
99 found = 0;
100 for (i = 0; i < main_submod->inc_size; i++) {
101 if (found) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200102 if (node->nodetype == LYS_RPC) {
Michal Vasko64448d72015-07-08 13:35:24 +0200103 has_next = sibling_is_valid_child(main_submod->inc[i].submodule->rpc, 1);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200104 } else if (node->nodetype == LYS_NOTIF) {
Michal Vasko64448d72015-07-08 13:35:24 +0200105 has_next = sibling_is_valid_child(main_submod->inc[i].submodule->notif, 1);
106 } else {
107 has_next = sibling_is_valid_child(main_submod->inc[i].submodule->data, 1);
108 }
109 if (has_next) {
110 break;
111 }
112 }
113 if (!found && (submod == main_submod->inc[i].submodule)) {
114 found = 1;
115 }
116 }
117
118 if (!has_next) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200119 if (node->nodetype == LYS_RPC) {
Michal Vasko64448d72015-07-08 13:35:24 +0200120 has_next = sibling_is_valid_child(main_submod->rpc, 1);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200121 } else if (node->nodetype == LYS_NOTIF) {
Michal Vasko64448d72015-07-08 13:35:24 +0200122 has_next = sibling_is_valid_child(main_submod->notif, 1);
123 } else {
124 has_next = sibling_is_valid_child(main_submod->data, 1);
125 }
126 }
127 }
128
129 goto strcat_indent;
130 }
131
Michal Vasko07898f92015-06-15 12:17:11 +0200132 /* find this submodule, check all the next ones for valid printed nodes */
133 found = 0;
134 for (i = 0; i < mod->inc_size; i++) {
135 /* we found ours, check all the following submodules and the module */
136 if (found) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200137 if (node->nodetype == LYS_RPC) {
Michal Vasko73f94a82015-06-29 16:00:07 +0200138 has_next = sibling_is_valid_child(mod->inc[i].submodule->rpc, 1);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200139 } else if (node->nodetype == LYS_NOTIF) {
Michal Vasko73f94a82015-06-29 16:00:07 +0200140 has_next = sibling_is_valid_child(mod->inc[i].submodule->notif, 1);
Michal Vaskof2896302015-06-16 09:30:02 +0200141 } else {
Michal Vasko73f94a82015-06-29 16:00:07 +0200142 has_next = sibling_is_valid_child(mod->inc[i].submodule->data, 1);
Michal Vasko07898f92015-06-15 12:17:11 +0200143 }
Michal Vasko5c7686d2015-07-08 13:36:21 +0200144 if (has_next) {
145 break;
146 }
Michal Vasko07898f92015-06-15 12:17:11 +0200147 }
Michal Vasko5c7686d2015-07-08 13:36:21 +0200148 if (!found && (submod == mod->inc[i].submodule)) {
Michal Vasko07898f92015-06-15 12:17:11 +0200149 found = 1;
150 }
151 }
Michal Vasko7ea0a312015-06-08 10:36:48 +0200152
Michal Vasko07898f92015-06-15 12:17:11 +0200153 /* there is nothing in submodules, check module */
154 if (!has_next) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200155 if (node->nodetype == LYS_RPC) {
Michal Vasko73f94a82015-06-29 16:00:07 +0200156 has_next = sibling_is_valid_child(mod->rpc, 1);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200157 } else if (node->nodetype == LYS_NOTIF) {
Michal Vasko73f94a82015-06-29 16:00:07 +0200158 has_next = sibling_is_valid_child(mod->notif, 1);
Michal Vaskof2896302015-06-16 09:30:02 +0200159 } else {
Michal Vasko73f94a82015-06-29 16:00:07 +0200160 has_next = sibling_is_valid_child(mod->data, 1);
Michal Vasko07898f92015-06-15 12:17:11 +0200161 }
162 }
163 }
164
Michal Vasko64448d72015-07-08 13:35:24 +0200165strcat_indent:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200166 if (has_next && !next_is_case) {
167 strcat(new_indent, "| ");
168 } else {
169 strcat(new_indent, " ");
170 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200171
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200172 return new_indent;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200173}
174
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200175static unsigned int
Radek Krejci1d82ef62015-08-07 14:44:40 +0200176get_max_name_len(struct lys_module *module, struct lys_node *node)
Michal Vasko8d479bd2015-06-05 10:50:03 +0200177{
Radek Krejci76512572015-08-04 09:47:08 +0200178 struct lys_node *sub;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200179 unsigned int max_name_len = 0, uses_max_name_len, name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200180
Radek Krejci1d82ef62015-08-07 14:44:40 +0200181 LY_TREE_FOR(node, sub) {
Radek Krejci76512572015-08-04 09:47:08 +0200182 if (sub->nodetype == LYS_USES) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200183 uses_max_name_len = get_max_name_len(module, sub->child);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200184 if (uses_max_name_len > max_name_len) {
185 max_name_len = uses_max_name_len;
186 }
187 } else if (sub->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200188 (LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
189 | LYS_ANYXML | LYS_CASE)) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200190 name_len = strlen(sub->name) + (module == sub->module ? 0 : strlen(sub->module->prefix)+1);
191 if (name_len > max_name_len) {
192 max_name_len = name_len;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200193 }
194 }
195 }
Michal Vasko8d479bd2015-06-05 10:50:03 +0200196
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200197 return max_name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200198}
199
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200200static void
Radek Krejci76b07902015-10-09 09:11:25 +0200201tree_print_type(struct lyout *out, struct lys_type *type)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200202{
Michal Vasko2d22b2d2015-09-24 13:53:31 +0200203 if ((type->base == LY_TYPE_LEAFREF) && !type->der->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200204 ly_print(out, "-> %s", type->info.lref.path);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200205 } else if (type->prefix) {
Radek Krejci76b07902015-10-09 09:11:25 +0200206 ly_print(out, "%s:%s", type->prefix, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200207 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200208 ly_print(out, "%s", type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200209 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200210}
211
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200212static void
Radek Krejci76b07902015-10-09 09:11:25 +0200213tree_print_features(struct lyout *out, const struct lys_feature **features, uint8_t features_size)
Michal Vasko28c6b572015-06-18 12:43:31 +0200214{
215 int i;
216
217 if (!features_size) {
218 return;
219 }
220
Radek Krejci76b07902015-10-09 09:11:25 +0200221 ly_print(out, " {");
Michal Vasko28c6b572015-06-18 12:43:31 +0200222 for (i = 0; i < features_size; i++) {
223 if (i > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200224 ly_print(out, ",");
Michal Vasko28c6b572015-06-18 12:43:31 +0200225 }
Radek Krejci76b07902015-10-09 09:11:25 +0200226 ly_print(out, "%s", features[i]->name);
Michal Vasko28c6b572015-06-18 12:43:31 +0200227 }
Radek Krejci76b07902015-10-09 09:11:25 +0200228 ly_print(out, "}?");
Michal Vasko28c6b572015-06-18 12:43:31 +0200229}
230
231static void
Radek Krejci76b07902015-10-09 09:11:25 +0200232tree_print_inout(struct lyout *out, struct lys_module *module, int level, char *indent, struct lys_node *node,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200233 int spec_config, struct lys_submodule *main_submod)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200234{
235 unsigned int max_child_len;
236 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200237 struct lys_node *sub;
Michal Vaskob5c75d72015-06-15 12:16:52 +0200238
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200239 assert(spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200240
Radek Krejci76b07902015-10-09 09:11:25 +0200241 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 +0200242
243 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200244 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200245
Radek Krejci1d82ef62015-08-07 14:44:40 +0200246 max_child_len = get_max_name_len(module, node->child);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200247
Radek Krejci1d82ef62015-08-07 14:44:40 +0200248 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200249 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200250 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200251 spec_config, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200252 }
253
254 free(new_indent);
255}
256
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200257static void
Radek Krejci76b07902015-10-09 09:11:25 +0200258tree_print_container(struct lyout *out, struct lys_module *module, int level, char *indent, struct lys_node *node,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200259 int spec_config, struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200260{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200261 unsigned int max_child_len;
262 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200263 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200264 struct lys_node *sub;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200265
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200266 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200267
Radek Krejci76b07902015-10-09 09:11:25 +0200268 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200269 (cont->flags & LYS_STATUS_DEPRC ? "x" : (cont->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200270
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200271 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200272 ly_print(out, "%s ", (cont->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200273 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200274 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200275 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200276 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200277 }
278
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200279 if (module != cont->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200280 ly_print(out, "%s:", cont->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200281 }
282
Radek Krejci76b07902015-10-09 09:11:25 +0200283 ly_print(out, "%s%s", cont->name, (cont->presence ? "!" : ""));
Michal Vasko28c6b572015-06-18 12:43:31 +0200284
Radek Krejci76b07902015-10-09 09:11:25 +0200285 tree_print_features(out, (const struct lys_feature **)cont->features, cont->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200286
Radek Krejci76b07902015-10-09 09:11:25 +0200287 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200288
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200289 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200290 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200291
Radek Krejci1d82ef62015-08-07 14:44:40 +0200292 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200293
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200294 LY_TREE_FOR(cont->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200295 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200296 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200297 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200298 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200299
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200300 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200301}
302
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200303static void
Radek Krejci76b07902015-10-09 09:11:25 +0200304tree_print_choice(struct lyout *out, struct lys_module *module, int level, char *indent, struct lys_node *node,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200305 int spec_config, struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200306{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200307 unsigned int max_child_len;
308 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200309 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200310 struct lys_node *sub;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200311
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200312 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200313
Radek Krejci76b07902015-10-09 09:11:25 +0200314 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200315 (choice->flags & LYS_STATUS_DEPRC ? "x" : (choice->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200316
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200317 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200318 ly_print(out, "%s ", (choice->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200319 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200320 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200321 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200322 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200323 }
324
Radek Krejci76b07902015-10-09 09:11:25 +0200325 ly_print(out, "(");
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200326
327 if (module != choice->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200328 ly_print(out, "%s:", choice->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200329 }
330
Radek Krejci76b07902015-10-09 09:11:25 +0200331 ly_print(out, "%s)%s", choice->name, (choice->flags & LYS_MAND_TRUE ? "" : "?"));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200332
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200333 if (choice->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200334 ly_print(out, " <%s>", choice->dflt->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200335 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200336
Radek Krejci76b07902015-10-09 09:11:25 +0200337 tree_print_features(out, (const struct lys_feature **)choice->features, choice->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200338
Radek Krejci76b07902015-10-09 09:11:25 +0200339 ly_print(out, "\n");
Michal Vasko449afde2015-06-04 16:06:49 +0200340
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200341 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200342 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vasko449afde2015-06-04 16:06:49 +0200343
Radek Krejci1d82ef62015-08-07 14:44:40 +0200344 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200345
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200346 LY_TREE_FOR(choice->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200347 tree_print_choice_content(out, module, level, new_indent, max_child_len, sub,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200348 LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML,
349 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200350 }
Michal Vasko449afde2015-06-04 16:06:49 +0200351
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200352 free(new_indent);
Michal Vasko449afde2015-06-04 16:06:49 +0200353}
354
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200355static void
Radek Krejci76b07902015-10-09 09:11:25 +0200356tree_print_case(struct lyout *out, struct lys_module *module, int level, char *indent, unsigned int max_name_len,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200357 struct lys_node *node, int shorthand, int spec_config, struct lys_submodule *main_submod)
Michal Vasko449afde2015-06-04 16:06:49 +0200358{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200359 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200360 struct lys_node_case *cas = (struct lys_node_case *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200361 struct lys_node *sub;
Radek Krejci7e97c352015-06-19 16:26:34 +0200362
Radek Krejci76b07902015-10-09 09:11:25 +0200363 ly_print(out, "%s%s--:(", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200364 (cas->flags & LYS_STATUS_DEPRC ? "x" : (cas->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200365
366 if (module != cas->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200367 ly_print(out, "%s:", cas->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200368 }
369
Radek Krejci76b07902015-10-09 09:11:25 +0200370 ly_print(out, "%s)", cas->name);
Michal Vasko449afde2015-06-04 16:06:49 +0200371
Radek Krejci76b07902015-10-09 09:11:25 +0200372 tree_print_features(out, (const struct lys_feature **)cas->features, cas->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200373
Radek Krejci76b07902015-10-09 09:11:25 +0200374 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200375
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200376 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200377 new_indent = create_indent(level, indent, node, shorthand, main_submod);
Michal Vasko449afde2015-06-04 16:06:49 +0200378
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200379 if (shorthand) {
Radek Krejci76b07902015-10-09 09:11:25 +0200380 tree_print_snode(out, module, level, new_indent, max_name_len, node,
Radek Krejci76512572015-08-04 09:47:08 +0200381 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200382 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200383 } else {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200384 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200385 tree_print_snode(out, module, level, new_indent, max_name_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200386 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200387 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200388 }
389 }
Michal Vasko449afde2015-06-04 16:06:49 +0200390
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200391 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200392}
393
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200394static void
Radek Krejci76b07902015-10-09 09:11:25 +0200395tree_print_anyxml(struct lyout *out, struct lys_module *module, char *indent, unsigned int max_name_len, struct lys_node *node, int spec_config)
Michal Vasko315f70b2015-06-05 10:48:59 +0200396{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200397 uint8_t prefix_len;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200398 struct lys_node_anyxml *anyxml = (struct lys_node_anyxml *)node;
Michal Vasko315f70b2015-06-05 10:48:59 +0200399
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200400 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200401
Radek Krejci76b07902015-10-09 09:11:25 +0200402 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200403 (anyxml->flags & LYS_STATUS_DEPRC ? "x" : (anyxml->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200404
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200405 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200406 ly_print(out, "%s ", (anyxml->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200407 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200408 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200409 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200410 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200411 }
412
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200413 prefix_len = 0;
414 if (module != anyxml->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200415 ly_print(out, "%s:", anyxml->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200416 prefix_len = strlen(anyxml->module->prefix)+1;
417 }
418
Radek Krejci76b07902015-10-09 09:11:25 +0200419 ly_print(out, "%s%s%*sanyxml", anyxml->name, (anyxml->flags & LYS_MAND_TRUE ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200420 3 + (int)((max_name_len - strlen(anyxml->name)) - prefix_len), " ");
Michal Vasko28c6b572015-06-18 12:43:31 +0200421
Radek Krejci76b07902015-10-09 09:11:25 +0200422 tree_print_features(out, (const struct lys_feature **)anyxml->features, anyxml->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200423
Radek Krejci76b07902015-10-09 09:11:25 +0200424 ly_print(out, "\n");
Michal Vasko315f70b2015-06-05 10:48:59 +0200425}
426
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200427static void
Radek Krejci76b07902015-10-09 09:11:25 +0200428tree_print_leaf(struct lyout *out, struct lys_module *module, char *indent, unsigned int max_name_len, struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200429{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200430 uint8_t prefix_len;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200431 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200432 struct lys_node *parent;
Radek Krejcib8048692015-08-05 13:36:34 +0200433 struct lys_node_list *list;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200434 int i, is_key = 0;
Michal Vasko449afde2015-06-04 16:06:49 +0200435
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200436 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200437
Radek Krejci69372e22015-08-13 09:55:27 +0200438 /* get know if the leaf is a key in a list, in that case it is
439 * mandatory by default */
Radek Krejci76512572015-08-04 09:47:08 +0200440 for (parent = leaf->parent; parent && parent->nodetype == LYS_USES; parent = parent->parent);
Radek Krejci69372e22015-08-13 09:55:27 +0200441 if (parent && parent->nodetype == LYS_LIST) {
Radek Krejcib8048692015-08-05 13:36:34 +0200442 list = (struct lys_node_list *)parent;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200443 for (i = 0; i < list->keys_size; i++) {
Michal Vasko96929d92015-08-03 15:30:22 +0200444 if (list->keys[i] == leaf) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200445 is_key = 1;
446 break;
447 }
448 }
449 }
Michal Vasko449afde2015-06-04 16:06:49 +0200450
Radek Krejci76b07902015-10-09 09:11:25 +0200451 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200452 (leaf->flags & LYS_STATUS_DEPRC ? "x" : (leaf->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200453
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200454 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200455 ly_print(out, "%s ", (leaf->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200456 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200457 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200458 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200459 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200460 }
461
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200462 prefix_len = 0;
463 if (module != leaf->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200464 ly_print(out, "%s:", leaf->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200465 prefix_len = strlen(leaf->module->prefix)+1;
466 }
467
Radek Krejci76b07902015-10-09 09:11:25 +0200468 ly_print(out, "%s%s%*s", leaf->name, ((leaf->flags & LYS_MAND_TRUE) || is_key ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200469 3 + (int)((max_name_len - strlen(leaf->name)) - prefix_len), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200470
Radek Krejci76b07902015-10-09 09:11:25 +0200471 tree_print_type(out, &leaf->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200472
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200473 if (leaf->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200474 ly_print(out, " <%s>", leaf->dflt);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200475 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200476
Radek Krejci76b07902015-10-09 09:11:25 +0200477 tree_print_features(out, (const struct lys_feature **)leaf->features, leaf->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200478
Radek Krejci76b07902015-10-09 09:11:25 +0200479 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200480}
481
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200482static void
Radek Krejci76b07902015-10-09 09:11:25 +0200483tree_print_leaflist(struct lyout *out, struct lys_module *module, char *indent, unsigned int max_name_len, struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200484{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200485 struct lys_node_leaflist *leaflist = (struct lys_node_leaflist *)node;
Michal Vasko449afde2015-06-04 16:06:49 +0200486
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200487 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200488
Radek Krejci76b07902015-10-09 09:11:25 +0200489 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200490 (leaflist->flags & LYS_STATUS_DEPRC ? "x" : (leaflist->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200491
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200492 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200493 ly_print(out, "%s ", (leaflist->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200494 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200495 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200496 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200497 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200498 }
499
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200500 if (module != leaflist->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200501 ly_print(out, "%s:", leaflist->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200502 }
503
Radek Krejci76b07902015-10-09 09:11:25 +0200504 ly_print(out, "%s*%*s", leaflist->name, 3 + (int)(max_name_len - strlen(leaflist->name)), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200505
Radek Krejci76b07902015-10-09 09:11:25 +0200506 tree_print_type(out, &leaflist->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200507
Radek Krejci76b07902015-10-09 09:11:25 +0200508 tree_print_features(out, (const struct lys_feature **)leaflist->features, leaflist->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200509
Radek Krejci76b07902015-10-09 09:11:25 +0200510 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200511}
512
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200513static void
Radek Krejci76b07902015-10-09 09:11:25 +0200514tree_print_list(struct lyout *out, struct lys_module *module, int level, char *indent, struct lys_node *node, int spec_config,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200515 struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200516{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200517 int i;
518 unsigned int max_child_len;
519 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200520 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200521 struct lys_node_list *list = (struct lys_node_list *)node;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200522
Radek Krejci76b07902015-10-09 09:11:25 +0200523 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200524 (list->flags & LYS_STATUS_DEPRC ? "x" : (list->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200525
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200526 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200527 ly_print(out, "%s ", (list->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200528 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200529 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200530 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200531 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200532 }
533
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200534 if (module != list->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200535 ly_print(out, "%s:", list->module->prefix);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200536 }
537
Radek Krejci76b07902015-10-09 09:11:25 +0200538 ly_print(out, "%s*", list->name);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200539
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200540 for (i = 0; i < list->keys_size; i++) {
541 if (i == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200542 ly_print(out, " [");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200543 }
Radek Krejci76b07902015-10-09 09:11:25 +0200544 ly_print(out, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? "," : "]");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200545 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200546
Radek Krejci76b07902015-10-09 09:11:25 +0200547 tree_print_features(out, (const struct lys_feature **)list->features, list->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200548
Radek Krejci76b07902015-10-09 09:11:25 +0200549 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200550
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200551 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200552 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200553
Radek Krejci1d82ef62015-08-07 14:44:40 +0200554 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200555
Radek Krejci1d82ef62015-08-07 14:44:40 +0200556 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200557 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200558 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Michal Vasko64448d72015-07-08 13:35:24 +0200559 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200560 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200561
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200562 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200563}
564
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200565static void
Radek Krejci76b07902015-10-09 09:11:25 +0200566tree_print_uses(struct lyout *out, struct lys_module *module, int level, char *indent, unsigned int max_name_len,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200567 struct lys_node *node, int spec_config, struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200568{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200569 struct lys_node *child;
570 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200571
Radek Krejci1d82ef62015-08-07 14:44:40 +0200572 LY_TREE_FOR(uses->child, child) {
Radek Krejci76b07902015-10-09 09:11:25 +0200573 tree_print_snode(out, module, level, indent, max_name_len, child,
Radek Krejci76512572015-08-04 09:47:08 +0200574 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Michal Vasko64448d72015-07-08 13:35:24 +0200575 spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200576 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200577}
578
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200579static void
Radek Krejci76b07902015-10-09 09:11:25 +0200580tree_print_rpc(struct lyout *out, struct lys_module *module, int level, char *indent, struct lys_node *node, struct lys_submodule *main_submod)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200581{
582 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200583 struct lys_node *child;
584 struct lys_node_rpc *rpc = (struct lys_node_rpc *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200585
Radek Krejci1d82ef62015-08-07 14:44:40 +0200586 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200587 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200588 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200589
Radek Krejci76b07902015-10-09 09:11:25 +0200590 ly_print(out, "%s%s---x %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200591 (rpc->flags & LYS_STATUS_DEPRC ? "x" : (rpc->flags & LYS_STATUS_OBSLT ? "o" : "+")), rpc->name);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200592
Radek Krejci76b07902015-10-09 09:11:25 +0200593 tree_print_features(out, (const struct lys_feature **)rpc->features, rpc->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200594
Radek Krejci76b07902015-10-09 09:11:25 +0200595 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200596
Michal Vaskob5c75d72015-06-15 12:16:52 +0200597 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200598 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200599
Radek Krejci1d82ef62015-08-07 14:44:40 +0200600 LY_TREE_FOR(rpc->child, child) {
601 if (child->nodetype == LYS_INPUT) {
Radek Krejci76b07902015-10-09 09:11:25 +0200602 tree_print_inout(out, module, level, new_indent, child, 1, main_submod);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200603 } else if (child->nodetype == LYS_OUTPUT) {
Radek Krejci76b07902015-10-09 09:11:25 +0200604 tree_print_inout(out, module, level, new_indent, child, 2, main_submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200605 }
606 }
607
608 free(new_indent);
609}
610
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200611static void
Radek Krejci76b07902015-10-09 09:11:25 +0200612tree_print_notif(struct lyout *out, struct lys_module *module, int level, char *indent, struct lys_node *node, struct lys_submodule *main_submod)
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200613{
614 unsigned int max_child_len;
615 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200616 struct lys_node *child;
617 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200618
Radek Krejci1d82ef62015-08-07 14:44:40 +0200619 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200620 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200621 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200622
Radek Krejci76b07902015-10-09 09:11:25 +0200623 ly_print(out, "%s%s---n %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200624 (notif->flags & LYS_STATUS_DEPRC ? "x" : (notif->flags & LYS_STATUS_OBSLT ? "o" : "+")),
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200625 notif->name);
626
Radek Krejci76b07902015-10-09 09:11:25 +0200627 tree_print_features(out, (const struct lys_feature **)notif->features, notif->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200628
Radek Krejci76b07902015-10-09 09:11:25 +0200629 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200630
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200631 level++;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200632 new_indent = create_indent(level, indent, node, 0, main_submod);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200633
Radek Krejci1d82ef62015-08-07 14:44:40 +0200634 max_child_len = get_max_name_len(module, node->child);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200635
Radek Krejci1d82ef62015-08-07 14:44:40 +0200636 LY_TREE_FOR(notif->child, child) {
Radek Krejci76b07902015-10-09 09:11:25 +0200637 tree_print_snode(out, module, level, new_indent, max_child_len, child,
Radek Krejci76512572015-08-04 09:47:08 +0200638 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Michal Vasko64448d72015-07-08 13:35:24 +0200639 2, main_submod);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200640 }
641
642 free(new_indent);
643}
644
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200645static void
Radek Krejci76b07902015-10-09 09:11:25 +0200646tree_print_choice_content(struct lyout *out, struct lys_module *module, int level, char *indent, unsigned int max_name_len,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200647 struct lys_node *node, int mask, int spec_config, struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200648{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200649 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200650 return;
651 }
652
Radek Krejci1d82ef62015-08-07 14:44:40 +0200653 if (node->nodetype & mask) {
654 if (node->nodetype == LYS_CASE) {
Radek Krejci76b07902015-10-09 09:11:25 +0200655 tree_print_case(out, module, level, indent, max_name_len, node, 0, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200656 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200657 tree_print_case(out, module, level, indent, max_name_len, node, 1, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200658 }
659 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200660}
661
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200662static void
Radek Krejci76b07902015-10-09 09:11:25 +0200663tree_print_snode(struct lyout *out, struct lys_module *module, int level, char *indent, unsigned int max_name_len,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200664 struct lys_node *node, int mask, int spec_config, struct lys_submodule *main_submod)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200665{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200666 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200667 return;
Radek Krejci87e840c2015-06-19 16:44:54 +0200668 }
669
Radek Krejci1d82ef62015-08-07 14:44:40 +0200670 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +0200671 case LYS_CONTAINER:
Radek Krejci76b07902015-10-09 09:11:25 +0200672 tree_print_container(out, module, level, indent, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200673 break;
Radek Krejci76512572015-08-04 09:47:08 +0200674 case LYS_CHOICE:
Radek Krejci76b07902015-10-09 09:11:25 +0200675 tree_print_choice(out, module, level, indent, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200676 break;
Radek Krejci76512572015-08-04 09:47:08 +0200677 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +0200678 tree_print_leaf(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200679 break;
Radek Krejci76512572015-08-04 09:47:08 +0200680 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +0200681 tree_print_leaflist(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200682 break;
Radek Krejci76512572015-08-04 09:47:08 +0200683 case LYS_LIST:
Radek Krejci76b07902015-10-09 09:11:25 +0200684 tree_print_list(out, module, level, indent, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200685 break;
Radek Krejci76512572015-08-04 09:47:08 +0200686 case LYS_ANYXML:
Radek Krejci76b07902015-10-09 09:11:25 +0200687 tree_print_anyxml(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200688 break;
Radek Krejci76512572015-08-04 09:47:08 +0200689 case LYS_USES:
Radek Krejci76b07902015-10-09 09:11:25 +0200690 tree_print_uses(out, module, level, indent, max_name_len, node, spec_config, main_submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200691 break;
692 default:
693 break;
694 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200695}
696
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200697int
Radek Krejci76b07902015-10-09 09:11:25 +0200698tree_print_model(struct lyout *out, struct lys_module *module)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200699{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200700 struct lys_node *node;
Radek Krejcib8048692015-08-05 13:36:34 +0200701 struct lys_submodule *submod;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200702 unsigned int max_child_len;
703 int level = 1, i, have_rpcs = 0, have_notifs = 0;
704 char *indent = malloc((level * 4 + 1) * sizeof (char));
705 strcpy(indent, " ");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200706
Michal Vaskofc6ac172015-07-07 09:46:46 +0200707 if (module->type) {
Radek Krejcib8048692015-08-05 13:36:34 +0200708 submod = (struct lys_submodule *)module;
Radek Krejci76b07902015-10-09 09:11:25 +0200709 ly_print(out, "submodule: %s (belongs-to %s)\n", submod->name, submod->belongsto->name);
Michal Vaskofc6ac172015-07-07 09:46:46 +0200710 } else {
Michal Vasko64448d72015-07-08 13:35:24 +0200711 submod = NULL;
Radek Krejci76b07902015-10-09 09:11:25 +0200712 ly_print(out, "module: %s\n", module->name);
Michal Vaskofc6ac172015-07-07 09:46:46 +0200713 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200714
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200715 /* included submodules */
716 for (i = 0; i < module->inc_size; i++) {
Radek Krejcib8048692015-08-05 13:36:34 +0200717 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 +0200718
Radek Krejci1d82ef62015-08-07 14:44:40 +0200719 LY_TREE_FOR(module->inc[i].submodule->data, node) {
Radek Krejci76b07902015-10-09 09:11:25 +0200720 tree_print_snode(out, (struct lys_module *)module->inc[i].submodule, level, indent, max_child_len, node,
Radek Krejci76512572015-08-04 09:47:08 +0200721 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
722 | LYS_ANYXML | LYS_USES, 0, submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200723 }
724 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200725
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200726 /* module */
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200727 max_child_len = get_max_name_len(module, module->data);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200728 level++;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200729
Radek Krejci1d82ef62015-08-07 14:44:40 +0200730 LY_TREE_FOR(module->data, node) {
Radek Krejci76b07902015-10-09 09:11:25 +0200731 tree_print_snode(out, module, level, indent, max_child_len, node,
Radek Krejci76512572015-08-04 09:47:08 +0200732 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
733 | LYS_ANYXML | LYS_USES, 0, submod);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200734 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200735
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200736 /* rpc */
737 if (module->rpc) {
Michal Vaskob5c75d72015-06-15 12:16:52 +0200738 have_rpcs = 1;
739 } else {
740 for (i = 0; i < module->inc_size; i++) {
741 if (module->inc[i].submodule->rpc) {
742 have_rpcs = 1;
743 break;
744 }
745 }
746 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200747 if (have_rpcs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200748 ly_print(out, "rpcs:\n");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200749 for (i = 0; i < module->inc_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200750 LY_TREE_FOR(module->inc[i].submodule->rpc, node) {
Radek Krejci76b07902015-10-09 09:11:25 +0200751 tree_print_rpc(out, (struct lys_module *)module->inc[i].submodule, level, indent, node, submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200752 }
753 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200754 LY_TREE_FOR(module->rpc, node) {
Radek Krejci76b07902015-10-09 09:11:25 +0200755 tree_print_rpc(out, module, level, indent, node, submod);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200756 }
757 }
Michal Vasko449afde2015-06-04 16:06:49 +0200758
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200759 /* notification */
760 if (module->notif) {
761 have_notifs = 1;
762 } else {
763 for (i = 0; i < module->inc_size; i++) {
764 if (module->inc[i].submodule->notif) {
765 have_notifs = 1;
766 break;
767 }
768 }
769 }
770 if (have_notifs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200771 ly_print(out, "notifications:\n");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200772 for (i = 0; i < module->inc_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200773 LY_TREE_FOR(module->inc[i].submodule->notif, node) {
Radek Krejci76b07902015-10-09 09:11:25 +0200774 tree_print_notif(out, (struct lys_module *)module->inc[i].submodule, level, indent, node, submod);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200775 }
776 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200777 LY_TREE_FOR(module->notif, node) {
Radek Krejci76b07902015-10-09 09:11:25 +0200778 tree_print_notif(out, module, level, indent, node, submod);
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}