blob: 03ae0cebc0207e83422f859473f81ac3460a5508 [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,
Radek Krejcic071c542016-01-27 14:57:51 +010034 int spec_config);
Michal Vasko1e62a092015-12-01 12:27:20 +010035static void tree_print_snode(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +010036 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config);
Michal Vasko5ed10f12015-06-04 10:04:57 +020037
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020038static int
Radek Krejci1d82ef62015-08-07 14:44:40 +020039sibling_is_valid_child(const struct lys_node *node, int including)
Michal Vasko6db4fce2015-06-08 14:13:49 +020040{
Radek Krejci76512572015-08-04 09:47:08 +020041 struct lys_node *cur;
Michal Vasko7ea0a312015-06-08 10:36:48 +020042
Radek Krejci1d82ef62015-08-07 14:44:40 +020043 if (node == NULL) {
Michal Vasko07898f92015-06-15 12:17:11 +020044 return 0;
45 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020046
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020047 /* has a following printed child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020048 LY_TREE_FOR((struct lys_node *)(including ? node : node->next), cur) {
Michal Vaskof6f18f42015-09-24 13:06:14 +020049 if (!lys_is_disabled(cur, 0)) {
50 if (cur->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_CHOICE |
Radek Krejci029e7902015-12-10 13:20:55 +010051 LYS_INPUT | LYS_OUTPUT | LYS_CASE)) {
Michal Vaskof6f18f42015-09-24 13:06:14 +020052 return 1;
53 }
54 if ((cur->nodetype == LYS_USES) && sibling_is_valid_child(cur->child, 1)) {
55 return 1;
56 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020057 }
58 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020059
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020060 /* if in uses, the following printed child can actually be in the parent node :-/ */
Radek Krejci1d82ef62015-08-07 14:44:40 +020061 if (node->parent && node->parent->nodetype == LYS_USES) {
62 return sibling_is_valid_child(node->parent, 0);
Michal Vasko07898f92015-06-15 12:17:11 +020063 }
64
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020065 return 0;
Michal Vasko7ea0a312015-06-08 10:36:48 +020066}
67
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020068static char *
Radek Krejcic071c542016-01-27 14:57:51 +010069create_indent(int level, const char *old_indent, const struct lys_node *node, int shorthand)
Michal Vasko449afde2015-06-04 16:06:49 +020070{
Radek Krejcic071c542016-01-27 14:57:51 +010071 int next_is_case = 0, is_case = 0, has_next = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020072 char *new_indent = malloc((level * 4 + 1) * sizeof (char));
Michal Vasko14410462015-06-05 15:08:54 +020073
Michal Vasko253035f2015-12-17 16:58:13 +010074 if (!new_indent) {
75 LOGMEM;
76 return NULL;
77 }
78
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020079 strcpy(new_indent, old_indent);
Michal Vasko14410462015-06-05 15:08:54 +020080
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020081 /* this is the indent of a case (standard or shorthand) */
Radek Krejci1d82ef62015-08-07 14:44:40 +020082 if ((node->nodetype == LYS_CASE) || shorthand) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020083 is_case = 1;
84 }
Michal Vasko14410462015-06-05 15:08:54 +020085
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020086 /* this is the direct child of a case */
Radek Krejci1d82ef62015-08-07 14:44:40 +020087 if (!is_case && node->parent && (node->parent->nodetype & (LYS_CASE | LYS_CHOICE))) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020088 /* it is not the only child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020089 if (node->next && node->next->parent && (node->next->parent->nodetype == LYS_CHOICE)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020090 next_is_case = 1;
91 }
92 }
Michal Vasko14410462015-06-05 15:08:54 +020093
Michal Vasko07898f92015-06-15 12:17:11 +020094 /* next is a node that will actually be printed */
Radek Krejci1d82ef62015-08-07 14:44:40 +020095 has_next = sibling_is_valid_child(node, 0);
Michal Vasko14410462015-06-05 15:08:54 +020096
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020097 if (has_next && !next_is_case) {
98 strcat(new_indent, "| ");
99 } else {
100 strcat(new_indent, " ");
101 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200102
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200103 return new_indent;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200104}
105
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200106static unsigned int
Michal Vasko1e62a092015-12-01 12:27:20 +0100107get_max_name_len(const struct lys_module *module, const struct lys_node *node)
Michal Vasko8d479bd2015-06-05 10:50:03 +0200108{
Michal Vasko1e62a092015-12-01 12:27:20 +0100109 const struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100110 struct lys_module *mod;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200111 unsigned int max_name_len = 0, uses_max_name_len, name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200112
Radek Krejci1d82ef62015-08-07 14:44:40 +0200113 LY_TREE_FOR(node, sub) {
Radek Krejci76512572015-08-04 09:47:08 +0200114 if (sub->nodetype == LYS_USES) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200115 uses_max_name_len = get_max_name_len(module, sub->child);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200116 if (uses_max_name_len > max_name_len) {
117 max_name_len = uses_max_name_len;
118 }
119 } else if (sub->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200120 (LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
121 | LYS_ANYXML | LYS_CASE)) {
Radek Krejcic071c542016-01-27 14:57:51 +0100122 mod = lys_mainmodule(sub);
Radek Krejci662f1c02016-02-11 11:31:24 +0100123 name_len = strlen(sub->name) + (module == mod ? 0 : strlen(mod->name)+1);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200124 if (name_len > max_name_len) {
125 max_name_len = name_len;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200126 }
127 }
128 }
Michal Vasko8d479bd2015-06-05 10:50:03 +0200129
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200130 return max_name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200131}
132
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200133static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100134tree_print_type(struct lyout *out, const struct lys_type *type)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200135{
Michal Vasko2d22b2d2015-09-24 13:53:31 +0200136 if ((type->base == LY_TYPE_LEAFREF) && !type->der->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200137 ly_print(out, "-> %s", type->info.lref.path);
Michal Vasko1dca6882015-10-22 14:29:42 +0200138 } else if (type->module_name) {
139 ly_print(out, "%s:%s", type->module_name, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200140 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200141 ly_print(out, "%s", type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200142 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200143}
144
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200145static void
Radek Krejci76b07902015-10-09 09:11:25 +0200146tree_print_features(struct lyout *out, const struct lys_feature **features, uint8_t features_size)
Michal Vasko28c6b572015-06-18 12:43:31 +0200147{
148 int i;
149
150 if (!features_size) {
151 return;
152 }
153
Radek Krejci76b07902015-10-09 09:11:25 +0200154 ly_print(out, " {");
Michal Vasko28c6b572015-06-18 12:43:31 +0200155 for (i = 0; i < features_size; i++) {
156 if (i > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200157 ly_print(out, ",");
Michal Vasko28c6b572015-06-18 12:43:31 +0200158 }
Radek Krejci76b07902015-10-09 09:11:25 +0200159 ly_print(out, "%s", features[i]->name);
Michal Vasko28c6b572015-06-18 12:43:31 +0200160 }
Radek Krejci76b07902015-10-09 09:11:25 +0200161 ly_print(out, "}?");
Michal Vasko28c6b572015-06-18 12:43:31 +0200162}
163
164static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100165tree_print_inout(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100166 const struct lys_node *node, int spec_config)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200167{
168 unsigned int max_child_len;
169 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200170 struct lys_node *sub;
Michal Vaskob5c75d72015-06-15 12:16:52 +0200171
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200172 assert(spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200173
Radek Krejci76b07902015-10-09 09:11:25 +0200174 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 +0200175
176 level++;
Radek Krejcic071c542016-01-27 14:57:51 +0100177 new_indent = create_indent(level, indent, node, 0);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200178
Radek Krejci1d82ef62015-08-07 14:44:40 +0200179 max_child_len = get_max_name_len(module, node->child);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200180
Radek Krejci1d82ef62015-08-07 14:44:40 +0200181 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200182 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200183 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100184 spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200185 }
186
187 free(new_indent);
188}
189
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200190static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100191tree_print_container(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100192 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200193{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200194 unsigned int max_child_len;
195 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200196 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200197 struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100198 struct lys_module *nodemod;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200199
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200200 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200201
Radek Krejci76b07902015-10-09 09:11:25 +0200202 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200203 (cont->flags & LYS_STATUS_DEPRC ? "x" : (cont->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200204
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200205 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200206 ly_print(out, "%s ", (cont->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200207 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200208 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200209 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200210 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200211 }
212
Radek Krejcic071c542016-01-27 14:57:51 +0100213 nodemod = lys_mainmodule(node);
214 if (module != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100215 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200216 }
217
Radek Krejci76b07902015-10-09 09:11:25 +0200218 ly_print(out, "%s%s", cont->name, (cont->presence ? "!" : ""));
Michal Vasko28c6b572015-06-18 12:43:31 +0200219
Radek Krejci76b07902015-10-09 09:11:25 +0200220 tree_print_features(out, (const struct lys_feature **)cont->features, cont->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200221
Radek Krejci76b07902015-10-09 09:11:25 +0200222 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200223
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200224 level++;
Radek Krejcic071c542016-01-27 14:57:51 +0100225 new_indent = create_indent(level, indent, node, 0);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200226
Radek Krejci1d82ef62015-08-07 14:44:40 +0200227 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200228
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200229 LY_TREE_FOR(cont->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200230 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200231 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100232 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200233 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200234
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200235 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200236}
237
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200238static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100239tree_print_choice(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100240 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200241{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200242 unsigned int max_child_len;
243 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200244 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200245 struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100246 struct lys_module *nodemod;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200247
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200248 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200249
Radek Krejci76b07902015-10-09 09:11:25 +0200250 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200251 (choice->flags & LYS_STATUS_DEPRC ? "x" : (choice->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200252
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200253 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200254 ly_print(out, "%s ", (choice->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200255 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200256 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200257 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200258 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200259 }
260
Radek Krejci76b07902015-10-09 09:11:25 +0200261 ly_print(out, "(");
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200262
Radek Krejcic071c542016-01-27 14:57:51 +0100263 nodemod = lys_mainmodule(node);
264 if (module != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100265 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200266 }
267
Radek Krejci76b07902015-10-09 09:11:25 +0200268 ly_print(out, "%s)%s", choice->name, (choice->flags & LYS_MAND_TRUE ? "" : "?"));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200269
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200270 if (choice->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200271 ly_print(out, " <%s>", choice->dflt->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200272 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200273
Radek Krejci76b07902015-10-09 09:11:25 +0200274 tree_print_features(out, (const struct lys_feature **)choice->features, choice->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200275
Radek Krejci76b07902015-10-09 09:11:25 +0200276 ly_print(out, "\n");
Michal Vasko449afde2015-06-04 16:06:49 +0200277
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200278 level++;
Radek Krejcic071c542016-01-27 14:57:51 +0100279 new_indent = create_indent(level, indent, node, 0);
Michal Vasko449afde2015-06-04 16:06:49 +0200280
Radek Krejci1d82ef62015-08-07 14:44:40 +0200281 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200282
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200283 LY_TREE_FOR(choice->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200284 tree_print_choice_content(out, module, level, new_indent, max_child_len, sub,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200285 LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML,
Radek Krejcic071c542016-01-27 14:57:51 +0100286 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200287 }
Michal Vasko449afde2015-06-04 16:06:49 +0200288
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200289 free(new_indent);
Michal Vasko449afde2015-06-04 16:06:49 +0200290}
291
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200292static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100293tree_print_case(struct lyout *out, const struct lys_module *module, int level, char *indent, unsigned int max_name_len,
Radek Krejcic071c542016-01-27 14:57:51 +0100294 const struct lys_node *node, int shorthand, int spec_config)
Michal Vasko449afde2015-06-04 16:06:49 +0200295{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200296 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200297 struct lys_node_case *cas = (struct lys_node_case *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200298 struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100299 struct lys_module *nodemod;
Radek Krejci7e97c352015-06-19 16:26:34 +0200300
Radek Krejci76b07902015-10-09 09:11:25 +0200301 ly_print(out, "%s%s--:(", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200302 (cas->flags & LYS_STATUS_DEPRC ? "x" : (cas->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200303
Radek Krejcic071c542016-01-27 14:57:51 +0100304 nodemod = lys_mainmodule(node);
305 if (module != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100306 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200307 }
308
Radek Krejci76b07902015-10-09 09:11:25 +0200309 ly_print(out, "%s)", cas->name);
Michal Vasko449afde2015-06-04 16:06:49 +0200310
Radek Krejci76b07902015-10-09 09:11:25 +0200311 tree_print_features(out, (const struct lys_feature **)cas->features, cas->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200312
Radek Krejci76b07902015-10-09 09:11:25 +0200313 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200314
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200315 level++;
Radek Krejcic071c542016-01-27 14:57:51 +0100316 new_indent = create_indent(level, indent, node, shorthand);
Michal Vasko449afde2015-06-04 16:06:49 +0200317
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200318 if (shorthand) {
Radek Krejci76b07902015-10-09 09:11:25 +0200319 tree_print_snode(out, module, level, new_indent, max_name_len, node,
Radek Krejci76512572015-08-04 09:47:08 +0200320 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100321 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200322 } else {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200323 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200324 tree_print_snode(out, module, level, new_indent, max_name_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200325 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100326 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200327 }
328 }
Michal Vasko449afde2015-06-04 16:06:49 +0200329
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200330 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200331}
332
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200333static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100334tree_print_anyxml(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
335 const struct lys_node *node, int spec_config)
Michal Vasko315f70b2015-06-05 10:48:59 +0200336{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200337 uint8_t prefix_len;
Radek Krejcic071c542016-01-27 14:57:51 +0100338 struct lys_module *nodemod;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200339 struct lys_node_anyxml *anyxml = (struct lys_node_anyxml *)node;
Michal Vasko315f70b2015-06-05 10:48:59 +0200340
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200341 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200342
Radek Krejci76b07902015-10-09 09:11:25 +0200343 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200344 (anyxml->flags & LYS_STATUS_DEPRC ? "x" : (anyxml->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200345
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200346 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200347 ly_print(out, "%s ", (anyxml->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200348 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200349 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200350 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200351 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200352 }
353
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200354 prefix_len = 0;
Radek Krejcic071c542016-01-27 14:57:51 +0100355 nodemod = lys_mainmodule(node);
356 if (module != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100357 ly_print(out, "%s:", nodemod->name);
358 prefix_len = strlen(nodemod->name)+1;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200359 }
360
Radek Krejci76b07902015-10-09 09:11:25 +0200361 ly_print(out, "%s%s%*sanyxml", anyxml->name, (anyxml->flags & LYS_MAND_TRUE ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200362 3 + (int)((max_name_len - strlen(anyxml->name)) - prefix_len), " ");
Michal Vasko28c6b572015-06-18 12:43:31 +0200363
Radek Krejci76b07902015-10-09 09:11:25 +0200364 tree_print_features(out, (const struct lys_feature **)anyxml->features, anyxml->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200365
Radek Krejci76b07902015-10-09 09:11:25 +0200366 ly_print(out, "\n");
Michal Vasko315f70b2015-06-05 10:48:59 +0200367}
368
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200369static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100370tree_print_leaf(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
371 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200372{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200373 uint8_t prefix_len;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200374 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200375 struct lys_node *parent;
Radek Krejcib8048692015-08-05 13:36:34 +0200376 struct lys_node_list *list;
Radek Krejcic071c542016-01-27 14:57:51 +0100377 struct lys_module *nodemod;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200378 int i, is_key = 0;
Michal Vasko449afde2015-06-04 16:06:49 +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 Krejci69372e22015-08-13 09:55:27 +0200382 /* get know if the leaf is a key in a list, in that case it is
383 * mandatory by default */
Radek Krejci76512572015-08-04 09:47:08 +0200384 for (parent = leaf->parent; parent && parent->nodetype == LYS_USES; parent = parent->parent);
Radek Krejci69372e22015-08-13 09:55:27 +0200385 if (parent && parent->nodetype == LYS_LIST) {
Radek Krejcib8048692015-08-05 13:36:34 +0200386 list = (struct lys_node_list *)parent;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200387 for (i = 0; i < list->keys_size; i++) {
Michal Vasko96929d92015-08-03 15:30:22 +0200388 if (list->keys[i] == leaf) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200389 is_key = 1;
390 break;
391 }
392 }
393 }
Michal Vasko449afde2015-06-04 16:06:49 +0200394
Radek Krejci76b07902015-10-09 09:11:25 +0200395 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200396 (leaf->flags & LYS_STATUS_DEPRC ? "x" : (leaf->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200397
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200398 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200399 ly_print(out, "%s ", (leaf->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200400 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200401 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200402 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200403 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200404 }
405
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200406 prefix_len = 0;
Radek Krejcic071c542016-01-27 14:57:51 +0100407 nodemod = lys_mainmodule(node);
408 if (module != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100409 ly_print(out, "%s:", nodemod->name);
410 prefix_len = strlen(nodemod->name)+1;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200411 }
412
Radek Krejci76b07902015-10-09 09:11:25 +0200413 ly_print(out, "%s%s%*s", leaf->name, ((leaf->flags & LYS_MAND_TRUE) || is_key ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200414 3 + (int)((max_name_len - strlen(leaf->name)) - prefix_len), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200415
Radek Krejci76b07902015-10-09 09:11:25 +0200416 tree_print_type(out, &leaf->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200417
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200418 if (leaf->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200419 ly_print(out, " <%s>", leaf->dflt);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200420 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200421
Radek Krejci76b07902015-10-09 09:11:25 +0200422 tree_print_features(out, (const struct lys_feature **)leaf->features, leaf->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200423
Radek Krejci76b07902015-10-09 09:11:25 +0200424 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200425}
426
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200427static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100428tree_print_leaflist(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
429 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200430{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200431 struct lys_node_leaflist *leaflist = (struct lys_node_leaflist *)node;
Radek Krejcic071c542016-01-27 14:57:51 +0100432 struct lys_module *nodemod;
Michal Vasko449afde2015-06-04 16:06:49 +0200433
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200434 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200435
Radek Krejci76b07902015-10-09 09:11:25 +0200436 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200437 (leaflist->flags & LYS_STATUS_DEPRC ? "x" : (leaflist->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200438
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200439 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200440 ly_print(out, "%s ", (leaflist->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200441 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200442 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200443 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200444 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200445 }
446
Radek Krejcic071c542016-01-27 14:57:51 +0100447 nodemod = lys_mainmodule(node);
448 if (module != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100449 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200450 }
451
Radek Krejci76b07902015-10-09 09:11:25 +0200452 ly_print(out, "%s*%*s", leaflist->name, 3 + (int)(max_name_len - strlen(leaflist->name)), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200453
Radek Krejci76b07902015-10-09 09:11:25 +0200454 tree_print_type(out, &leaflist->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200455
Radek Krejci76b07902015-10-09 09:11:25 +0200456 tree_print_features(out, (const struct lys_feature **)leaflist->features, leaflist->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200457
Radek Krejci76b07902015-10-09 09:11:25 +0200458 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200459}
460
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200461static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100462tree_print_list(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100463 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200464{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200465 int i;
466 unsigned int max_child_len;
467 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200468 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200469 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejcic071c542016-01-27 14:57:51 +0100470 struct lys_module *nodemod;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200471
Radek Krejci76b07902015-10-09 09:11:25 +0200472 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200473 (list->flags & LYS_STATUS_DEPRC ? "x" : (list->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200474
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200475 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200476 ly_print(out, "%s ", (list->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200477 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200478 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200479 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200480 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200481 }
482
Radek Krejcic071c542016-01-27 14:57:51 +0100483 nodemod = lys_mainmodule(node);
484 if (module != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100485 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200486 }
487
Radek Krejci76b07902015-10-09 09:11:25 +0200488 ly_print(out, "%s*", list->name);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200489
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200490 for (i = 0; i < list->keys_size; i++) {
491 if (i == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200492 ly_print(out, " [");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200493 }
Radek Krejcif3966532015-12-09 14:19:35 +0100494 ly_print(out, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "]");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200495 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200496
Radek Krejci76b07902015-10-09 09:11:25 +0200497 tree_print_features(out, (const struct lys_feature **)list->features, list->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200498
Radek Krejci76b07902015-10-09 09:11:25 +0200499 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200500
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200501 level++;
Radek Krejcic071c542016-01-27 14:57:51 +0100502 new_indent = create_indent(level, indent, node, 0);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200503
Radek Krejci1d82ef62015-08-07 14:44:40 +0200504 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200505
Radek Krejci1d82ef62015-08-07 14:44:40 +0200506 LY_TREE_FOR(node->child, sub) {
Radek Krejci76b07902015-10-09 09:11:25 +0200507 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200508 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Radek Krejcic071c542016-01-27 14:57:51 +0100509 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200510 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200511
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200512 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200513}
514
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200515static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100516tree_print_uses(struct lyout *out, const struct lys_module *module, int level, char *indent, unsigned int max_name_len,
Radek Krejcic071c542016-01-27 14:57:51 +0100517 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200518{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200519 struct lys_node *child;
520 struct lys_node_uses *uses = (struct lys_node_uses *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200521
Radek Krejci1d82ef62015-08-07 14:44:40 +0200522 LY_TREE_FOR(uses->child, child) {
Radek Krejci76b07902015-10-09 09:11:25 +0200523 tree_print_snode(out, module, level, indent, max_name_len, child,
Radek Krejci76512572015-08-04 09:47:08 +0200524 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Radek Krejcic071c542016-01-27 14:57:51 +0100525 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200526 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200527}
528
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200529static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100530tree_print_rpc(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100531 const struct lys_node *node)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200532{
533 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200534 struct lys_node *child;
535 struct lys_node_rpc *rpc = (struct lys_node_rpc *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200536
Radek Krejci1d82ef62015-08-07 14:44:40 +0200537 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200538 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200539 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200540
Radek Krejci76b07902015-10-09 09:11:25 +0200541 ly_print(out, "%s%s---x %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200542 (rpc->flags & LYS_STATUS_DEPRC ? "x" : (rpc->flags & LYS_STATUS_OBSLT ? "o" : "+")), rpc->name);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200543
Radek Krejci76b07902015-10-09 09:11:25 +0200544 tree_print_features(out, (const struct lys_feature **)rpc->features, rpc->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200545
Radek Krejci76b07902015-10-09 09:11:25 +0200546 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200547
Michal Vaskob5c75d72015-06-15 12:16:52 +0200548 level++;
Radek Krejcic071c542016-01-27 14:57:51 +0100549 new_indent = create_indent(level, indent, node, 0);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200550
Radek Krejci1d82ef62015-08-07 14:44:40 +0200551 LY_TREE_FOR(rpc->child, child) {
552 if (child->nodetype == LYS_INPUT) {
Radek Krejcic071c542016-01-27 14:57:51 +0100553 tree_print_inout(out, module, level, new_indent, child, 1);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200554 } else if (child->nodetype == LYS_OUTPUT) {
Radek Krejcic071c542016-01-27 14:57:51 +0100555 tree_print_inout(out, module, level, new_indent, child, 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200556 }
557 }
558
559 free(new_indent);
560}
561
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200562static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100563tree_print_notif(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100564 const struct lys_node *node)
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200565{
566 unsigned int max_child_len;
567 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200568 struct lys_node *child;
569 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200570
Radek Krejci1d82ef62015-08-07 14:44:40 +0200571 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200572 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200573 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200574
Radek Krejci76b07902015-10-09 09:11:25 +0200575 ly_print(out, "%s%s---n %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200576 (notif->flags & LYS_STATUS_DEPRC ? "x" : (notif->flags & LYS_STATUS_OBSLT ? "o" : "+")),
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200577 notif->name);
578
Radek Krejci76b07902015-10-09 09:11:25 +0200579 tree_print_features(out, (const struct lys_feature **)notif->features, notif->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200580
Radek Krejci76b07902015-10-09 09:11:25 +0200581 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200582
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200583 level++;
Radek Krejcic071c542016-01-27 14:57:51 +0100584 new_indent = create_indent(level, indent, node, 0);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200585
Radek Krejci1d82ef62015-08-07 14:44:40 +0200586 max_child_len = get_max_name_len(module, node->child);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200587
Radek Krejci1d82ef62015-08-07 14:44:40 +0200588 LY_TREE_FOR(notif->child, child) {
Radek Krejci76b07902015-10-09 09:11:25 +0200589 tree_print_snode(out, module, level, new_indent, max_child_len, child,
Radek Krejcic071c542016-01-27 14:57:51 +0100590 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES, 2);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200591 }
592
593 free(new_indent);
594}
595
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200596static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100597tree_print_choice_content(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100598 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200599{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200600 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200601 return;
602 }
603
Radek Krejci1d82ef62015-08-07 14:44:40 +0200604 if (node->nodetype & mask) {
605 if (node->nodetype == LYS_CASE) {
Radek Krejcic071c542016-01-27 14:57:51 +0100606 tree_print_case(out, module, level, indent, max_name_len, node, 0, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200607 } else {
Radek Krejcic071c542016-01-27 14:57:51 +0100608 tree_print_case(out, module, level, indent, max_name_len, node, 1, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200609 }
610 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200611}
612
Michal Vaskoc176b682015-12-09 14:30:14 +0100613/* spec_config = 0 (no special config status), 1 (read-only - rpc output, notification), 2 (write-only - rpc input) */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200614static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100615tree_print_snode(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100616 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200617{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200618 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200619 return;
Radek Krejci87e840c2015-06-19 16:44:54 +0200620 }
621
Radek Krejci1d82ef62015-08-07 14:44:40 +0200622 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +0200623 case LYS_CONTAINER:
Radek Krejcic071c542016-01-27 14:57:51 +0100624 tree_print_container(out, module, level, indent, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200625 break;
Radek Krejci76512572015-08-04 09:47:08 +0200626 case LYS_CHOICE:
Radek Krejcic071c542016-01-27 14:57:51 +0100627 tree_print_choice(out, module, level, indent, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200628 break;
Radek Krejci76512572015-08-04 09:47:08 +0200629 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +0200630 tree_print_leaf(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200631 break;
Radek Krejci76512572015-08-04 09:47:08 +0200632 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +0200633 tree_print_leaflist(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200634 break;
Radek Krejci76512572015-08-04 09:47:08 +0200635 case LYS_LIST:
Radek Krejcic071c542016-01-27 14:57:51 +0100636 tree_print_list(out, module, level, indent, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200637 break;
Radek Krejci76512572015-08-04 09:47:08 +0200638 case LYS_ANYXML:
Radek Krejci76b07902015-10-09 09:11:25 +0200639 tree_print_anyxml(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200640 break;
Radek Krejci76512572015-08-04 09:47:08 +0200641 case LYS_USES:
Radek Krejcic071c542016-01-27 14:57:51 +0100642 tree_print_uses(out, module, level, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200643 break;
644 default:
645 break;
646 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200647}
648
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200649int
Michal Vasko1e62a092015-12-01 12:27:20 +0100650tree_print_model(struct lyout *out, const struct lys_module *module)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200651{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200652 struct lys_node *node;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200653 unsigned int max_child_len;
Radek Krejcic071c542016-01-27 14:57:51 +0100654 int level = 1, have_rpcs = 0, have_notifs = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200655 char *indent = malloc((level * 4 + 1) * sizeof (char));
Michal Vasko253035f2015-12-17 16:58:13 +0100656
657 if (!indent) {
658 LOGMEM;
659 return EXIT_FAILURE;
660 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200661 strcpy(indent, " ");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200662
Michal Vaskofc6ac172015-07-07 09:46:46 +0200663 if (module->type) {
Radek Krejcic071c542016-01-27 14:57:51 +0100664 ly_print(out, "submodule: %s (belongs-to %s)\n", module->name,
665 ((struct lys_submodule *)module)->belongsto->name);
Michal Vaskofc6ac172015-07-07 09:46:46 +0200666 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200667 ly_print(out, "module: %s\n", module->name);
Michal Vaskofc6ac172015-07-07 09:46:46 +0200668 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200669
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200670 /* module */
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200671 max_child_len = get_max_name_len(module, module->data);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200672 level++;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200673
Radek Krejci1d82ef62015-08-07 14:44:40 +0200674 LY_TREE_FOR(module->data, node) {
Radek Krejci92720552015-10-05 15:28:27 +0200675 switch(node->nodetype) {
676 case LYS_RPC:
Radek Krejciadf7a8e2015-12-10 13:11:17 +0100677 if (!lys_is_disabled(node, 0)) {
678 have_rpcs++;
679 }
Radek Krejci92720552015-10-05 15:28:27 +0200680 break;
681 case LYS_NOTIF:
Radek Krejciadf7a8e2015-12-10 13:11:17 +0100682 if (!lys_is_disabled(node, 0)) {
683 have_notifs++;
684 }
Radek Krejci92720552015-10-05 15:28:27 +0200685 break;
686 default:
Radek Krejcibac81762015-10-09 10:19:52 +0200687 tree_print_snode(out, module, level, indent, max_child_len, node,
Radek Krejci92720552015-10-05 15:28:27 +0200688 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
Radek Krejcic071c542016-01-27 14:57:51 +0100689 | LYS_ANYXML | LYS_USES, 0);
Radek Krejci92720552015-10-05 15:28:27 +0200690 break;
691 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200692 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200693
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200694 /* rpc */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200695 if (have_rpcs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200696 ly_print(out, "rpcs:\n");
Radek Krejci92720552015-10-05 15:28:27 +0200697 LY_TREE_FOR(module->data, node) {
698 if (!have_rpcs) {
699 break;
700 }
701 if (node->nodetype == LYS_RPC) {
Radek Krejcic071c542016-01-27 14:57:51 +0100702 tree_print_rpc(out, module, level, indent, node);
Radek Krejci92720552015-10-05 15:28:27 +0200703 have_rpcs--;
704 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200705 }
706 }
Michal Vasko449afde2015-06-04 16:06:49 +0200707
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200708 /* notification */
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200709 if (have_notifs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200710 ly_print(out, "notifications:\n");
Radek Krejci92720552015-10-05 15:28:27 +0200711 LY_TREE_FOR(module->data, node) {
712 if (!have_notifs) {
713 break;
714 }
715 if (node->nodetype == LYS_NOTIF) {
Radek Krejcic071c542016-01-27 14:57:51 +0100716 tree_print_notif(out, module, level, indent, node);
Radek Krejci92720552015-10-05 15:28:27 +0200717 have_notifs--;
718 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200719 }
720 }
Michal Vasko449afde2015-06-04 16:06:49 +0200721
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200722 free(indent);
723 return EXIT_SUCCESS;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200724}