blob: cfd064bce0d0ac18315724eaaef49037d1f5597f [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 *
Radek Krejci54f6fb32016-02-24 12:56:39 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
Michal Vasko8de098c2016-02-26 10:00:25 +010011 *
Radek Krejci54f6fb32016-02-24 12:56:39 +010012 * https://opensource.org/licenses/BSD-3-Clause
Michal Vasko5ed10f12015-06-04 10:04:57 +020013 */
14
15#include <stdlib.h>
16#include <stdio.h>
17#include <string.h>
Michal Vaskob5c75d72015-06-15 12:16:52 +020018#include <assert.h>
Michal Vasko5ed10f12015-06-04 10:04:57 +020019
Radek Krejci998a0b82015-08-17 13:14:36 +020020#include "common.h"
Radek Krejci76b07902015-10-09 09:11:25 +020021#include "printer.h"
Michal Vasko2d162e12015-09-24 14:33:29 +020022#include "tree_schema.h"
Michal Vasko5ed10f12015-06-04 10:04:57 +020023
Michal Vaskoe03bfbb2015-06-16 09:07:49 +020024/* 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 +010025static void tree_print_choice_content(struct lyout *out, const struct lys_module* module, int level, char *indent,
26 unsigned int max_name_len, const struct lys_node *node, int mask,
Radek Krejcic071c542016-01-27 14:57:51 +010027 int spec_config);
Michal Vasko1e62a092015-12-01 12:27:20 +010028static void tree_print_snode(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +010029 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config);
Michal Vasko5ed10f12015-06-04 10:04:57 +020030
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020031static int
Michal Vaskobda37192016-02-15 11:09:13 +010032sibling_is_valid_child(const struct lys_node *node, int including, const struct lys_module *module)
Michal Vasko6db4fce2015-06-08 14:13:49 +020033{
Radek Krejci76512572015-08-04 09:47:08 +020034 struct lys_node *cur;
Michal Vasko7ea0a312015-06-08 10:36:48 +020035
Michal Vaskobda37192016-02-15 11:09:13 +010036 if (!node) {
Michal Vasko07898f92015-06-15 12:17:11 +020037 return 0;
38 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020039
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020040 /* has a following printed child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020041 LY_TREE_FOR((struct lys_node *)(including ? node : node->next), cur) {
Michal Vaskobda37192016-02-15 11:09:13 +010042 if (module->type && (cur->module != module)) {
43 continue;
44 }
45
Michal Vaskof6f18f42015-09-24 13:06:14 +020046 if (!lys_is_disabled(cur, 0)) {
47 if (cur->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_CHOICE |
Radek Krejci029e7902015-12-10 13:20:55 +010048 LYS_INPUT | LYS_OUTPUT | LYS_CASE)) {
Michal Vaskof6f18f42015-09-24 13:06:14 +020049 return 1;
50 }
Michal Vaskobda37192016-02-15 11:09:13 +010051 if ((cur->nodetype == LYS_USES) && sibling_is_valid_child(cur->child, 1, module)) {
Michal Vaskof6f18f42015-09-24 13:06:14 +020052 return 1;
53 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020054 }
55 }
Michal Vasko7ea0a312015-06-08 10:36:48 +020056
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020057 /* if in uses, the following printed child can actually be in the parent node :-/ */
Michal Vaskobda37192016-02-15 11:09:13 +010058 if (node->parent && (node->parent->nodetype == LYS_USES)) {
59 return sibling_is_valid_child(node->parent, 0, module);
Michal Vasko07898f92015-06-15 12:17:11 +020060 }
61
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020062 return 0;
Michal Vasko7ea0a312015-06-08 10:36:48 +020063}
64
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020065static char *
Michal Vaskobda37192016-02-15 11:09:13 +010066create_indent(int level, const char *old_indent, const struct lys_node *node, int shorthand, const struct lys_module *module)
Michal Vasko449afde2015-06-04 16:06:49 +020067{
Radek Krejcic071c542016-01-27 14:57:51 +010068 int next_is_case = 0, is_case = 0, has_next = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020069 char *new_indent = malloc((level * 4 + 1) * sizeof (char));
Michal Vasko14410462015-06-05 15:08:54 +020070
Michal Vasko253035f2015-12-17 16:58:13 +010071 if (!new_indent) {
72 LOGMEM;
73 return NULL;
74 }
75
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020076 strcpy(new_indent, old_indent);
Michal Vasko14410462015-06-05 15:08:54 +020077
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020078 /* this is the indent of a case (standard or shorthand) */
Radek Krejci1d82ef62015-08-07 14:44:40 +020079 if ((node->nodetype == LYS_CASE) || shorthand) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020080 is_case = 1;
81 }
Michal Vasko14410462015-06-05 15:08:54 +020082
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020083 /* this is the direct child of a case */
Radek Krejci1d82ef62015-08-07 14:44:40 +020084 if (!is_case && node->parent && (node->parent->nodetype & (LYS_CASE | LYS_CHOICE))) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020085 /* it is not the only child */
Radek Krejci1d82ef62015-08-07 14:44:40 +020086 if (node->next && node->next->parent && (node->next->parent->nodetype == LYS_CHOICE)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020087 next_is_case = 1;
88 }
89 }
Michal Vasko14410462015-06-05 15:08:54 +020090
Michal Vasko07898f92015-06-15 12:17:11 +020091 /* next is a node that will actually be printed */
Michal Vaskobda37192016-02-15 11:09:13 +010092 has_next = sibling_is_valid_child(node, 0, module);
Michal Vasko14410462015-06-05 15:08:54 +020093
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020094 if (has_next && !next_is_case) {
95 strcat(new_indent, "| ");
96 } else {
97 strcat(new_indent, " ");
98 }
Michal Vasko5ed10f12015-06-04 10:04:57 +020099
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200100 return new_indent;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200101}
102
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200103static unsigned int
Michal Vasko1e62a092015-12-01 12:27:20 +0100104get_max_name_len(const struct lys_module *module, const struct lys_node *node)
Michal Vasko8d479bd2015-06-05 10:50:03 +0200105{
Michal Vasko1e62a092015-12-01 12:27:20 +0100106 const struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100107 struct lys_module *mod;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200108 unsigned int max_name_len = 0, uses_max_name_len, name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200109
Radek Krejci1d82ef62015-08-07 14:44:40 +0200110 LY_TREE_FOR(node, sub) {
Michal Vaskobda37192016-02-15 11:09:13 +0100111 if (module->type && (sub->module != module)) {
112 /* when printing submodule, we are only concerned with its own data (they are in the module data) */
113 continue;
114 }
115
Radek Krejci76512572015-08-04 09:47:08 +0200116 if (sub->nodetype == LYS_USES) {
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200117 uses_max_name_len = get_max_name_len(module, sub->child);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200118 if (uses_max_name_len > max_name_len) {
119 max_name_len = uses_max_name_len;
120 }
121 } else if (sub->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200122 (LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
123 | LYS_ANYXML | LYS_CASE)) {
Michal Vaskobda37192016-02-15 11:09:13 +0100124 mod = lys_node_module(sub);
125 name_len = strlen(sub->name) + (module == mod ? 0 : strlen(mod->name) + 1);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200126 if (name_len > max_name_len) {
127 max_name_len = name_len;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200128 }
129 }
130 }
Michal Vasko8d479bd2015-06-05 10:50:03 +0200131
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200132 return max_name_len;
Michal Vasko8d479bd2015-06-05 10:50:03 +0200133}
134
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200135static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100136tree_print_type(struct lyout *out, const struct lys_type *type)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200137{
Michal Vasko2d22b2d2015-09-24 13:53:31 +0200138 if ((type->base == LY_TYPE_LEAFREF) && !type->der->module) {
Radek Krejci76b07902015-10-09 09:11:25 +0200139 ly_print(out, "-> %s", type->info.lref.path);
Michal Vasko1dca6882015-10-22 14:29:42 +0200140 } else if (type->module_name) {
141 ly_print(out, "%s:%s", type->module_name, type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200142 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200143 ly_print(out, "%s", type->der->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200144 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200145}
146
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200147static void
Radek Krejci76b07902015-10-09 09:11:25 +0200148tree_print_features(struct lyout *out, const struct lys_feature **features, uint8_t features_size)
Michal Vasko28c6b572015-06-18 12:43:31 +0200149{
150 int i;
151
152 if (!features_size) {
153 return;
154 }
155
Radek Krejci76b07902015-10-09 09:11:25 +0200156 ly_print(out, " {");
Michal Vasko28c6b572015-06-18 12:43:31 +0200157 for (i = 0; i < features_size; i++) {
158 if (i > 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200159 ly_print(out, ",");
Michal Vasko28c6b572015-06-18 12:43:31 +0200160 }
Radek Krejci76b07902015-10-09 09:11:25 +0200161 ly_print(out, "%s", features[i]->name);
Michal Vasko28c6b572015-06-18 12:43:31 +0200162 }
Radek Krejci76b07902015-10-09 09:11:25 +0200163 ly_print(out, "}?");
Michal Vasko28c6b572015-06-18 12:43:31 +0200164}
165
166static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100167tree_print_inout(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100168 const struct lys_node *node, int spec_config)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200169{
170 unsigned int max_child_len;
171 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200172 struct lys_node *sub;
Michal Vaskob5c75d72015-06-15 12:16:52 +0200173
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200174 assert(spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200175
Radek Krejci76b07902015-10-09 09:11:25 +0200176 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 +0200177
178 level++;
Michal Vaskobda37192016-02-15 11:09:13 +0100179 new_indent = create_indent(level, indent, node, 0, module);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200180
Radek Krejci1d82ef62015-08-07 14:44:40 +0200181 max_child_len = get_max_name_len(module, node->child);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200182
Radek Krejci1d82ef62015-08-07 14:44:40 +0200183 LY_TREE_FOR(node->child, sub) {
Michal Vasko3510f892016-02-15 14:33:52 +0100184 /* submodule, foreign augments */
185 if (module->type && (sub->parent != node) && (sub->module != module)) {
186 continue;
187 }
Radek Krejci76b07902015-10-09 09:11:25 +0200188 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200189 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100190 spec_config);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200191 }
192
193 free(new_indent);
194}
195
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200196static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100197tree_print_container(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100198 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200199{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200200 unsigned int max_child_len;
201 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200202 struct lys_node_container *cont = (struct lys_node_container *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200203 struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100204 struct lys_module *nodemod;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200205
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200206 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200207
Radek Krejci76b07902015-10-09 09:11:25 +0200208 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200209 (cont->flags & LYS_STATUS_DEPRC ? "x" : (cont->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200210
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200211 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200212 ly_print(out, "%s ", (cont->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200213 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200214 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200215 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200216 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200217 }
218
Michal Vaskobda37192016-02-15 11:09:13 +0100219 nodemod = lys_node_module(node);
220 if (lys_module(module) != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100221 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200222 }
223
Radek Krejci76b07902015-10-09 09:11:25 +0200224 ly_print(out, "%s%s", cont->name, (cont->presence ? "!" : ""));
Michal Vasko28c6b572015-06-18 12:43:31 +0200225
Radek Krejci76b07902015-10-09 09:11:25 +0200226 tree_print_features(out, (const struct lys_feature **)cont->features, cont->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200227
Radek Krejci76b07902015-10-09 09:11:25 +0200228 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200229
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200230 level++;
Michal Vaskobda37192016-02-15 11:09:13 +0100231 new_indent = create_indent(level, indent, node, 0, module);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200232
Radek Krejci1d82ef62015-08-07 14:44:40 +0200233 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200234
Michal Vasko3510f892016-02-15 14:33:52 +0100235 LY_TREE_FOR(node->child, sub) {
236 /* submodule, foreign augments */
237 if (module->type && (sub->parent != node) && (sub->module != module)) {
238 continue;
239 }
Radek Krejci76b07902015-10-09 09:11:25 +0200240 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200241 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100242 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200243 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200244
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200245 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200246}
247
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200248static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100249tree_print_choice(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100250 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200251{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200252 unsigned int max_child_len;
253 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200254 struct lys_node_choice *choice = (struct lys_node_choice *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200255 struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100256 struct lys_module *nodemod;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200257
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200258 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200259
Radek Krejci76b07902015-10-09 09:11:25 +0200260 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200261 (choice->flags & LYS_STATUS_DEPRC ? "x" : (choice->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200262
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200263 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200264 ly_print(out, "%s ", (choice->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200265 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200266 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200267 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200268 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200269 }
270
Radek Krejci76b07902015-10-09 09:11:25 +0200271 ly_print(out, "(");
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200272
Michal Vaskobda37192016-02-15 11:09:13 +0100273 nodemod = lys_node_module(node);
274 if (lys_module(module) != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100275 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200276 }
277
Radek Krejci76b07902015-10-09 09:11:25 +0200278 ly_print(out, "%s)%s", choice->name, (choice->flags & LYS_MAND_TRUE ? "" : "?"));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200279
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200280 if (choice->dflt != NULL) {
Radek Krejci76b07902015-10-09 09:11:25 +0200281 ly_print(out, " <%s>", choice->dflt->name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200282 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200283
Radek Krejci76b07902015-10-09 09:11:25 +0200284 tree_print_features(out, (const struct lys_feature **)choice->features, choice->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200285
Radek Krejci76b07902015-10-09 09:11:25 +0200286 ly_print(out, "\n");
Michal Vasko449afde2015-06-04 16:06:49 +0200287
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200288 level++;
Michal Vaskobda37192016-02-15 11:09:13 +0100289 new_indent = create_indent(level, indent, node, 0, module);
Michal Vasko449afde2015-06-04 16:06:49 +0200290
Radek Krejci1d82ef62015-08-07 14:44:40 +0200291 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200292
Michal Vasko3510f892016-02-15 14:33:52 +0100293 LY_TREE_FOR(node->child, sub) {
294 /* submodule, foreign augments */
295 if (module->type && (sub->parent != node) && (sub->module != module)) {
296 continue;
297 }
Radek Krejci76b07902015-10-09 09:11:25 +0200298 tree_print_choice_content(out, module, level, new_indent, max_child_len, sub,
Radek Krejci1d82ef62015-08-07 14:44:40 +0200299 LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML,
Radek Krejcic071c542016-01-27 14:57:51 +0100300 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200301 }
Michal Vasko449afde2015-06-04 16:06:49 +0200302
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200303 free(new_indent);
Michal Vasko449afde2015-06-04 16:06:49 +0200304}
305
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200306static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100307tree_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 +0100308 const struct lys_node *node, int shorthand, int spec_config)
Michal Vasko449afde2015-06-04 16:06:49 +0200309{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200310 char *new_indent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200311 struct lys_node_case *cas = (struct lys_node_case *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200312 struct lys_node *sub;
Radek Krejcic071c542016-01-27 14:57:51 +0100313 struct lys_module *nodemod;
Radek Krejci7e97c352015-06-19 16:26:34 +0200314
Radek Krejci76b07902015-10-09 09:11:25 +0200315 ly_print(out, "%s%s--:(", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200316 (cas->flags & LYS_STATUS_DEPRC ? "x" : (cas->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200317
Michal Vaskobda37192016-02-15 11:09:13 +0100318 nodemod = lys_node_module(node);
319 if (lys_module(module) != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100320 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200321 }
322
Radek Krejci76b07902015-10-09 09:11:25 +0200323 ly_print(out, "%s)", cas->name);
Michal Vasko449afde2015-06-04 16:06:49 +0200324
Radek Krejci76b07902015-10-09 09:11:25 +0200325 tree_print_features(out, (const struct lys_feature **)cas->features, cas->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200326
Radek Krejci76b07902015-10-09 09:11:25 +0200327 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200328
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200329 level++;
Michal Vaskobda37192016-02-15 11:09:13 +0100330 new_indent = create_indent(level, indent, node, shorthand, module);
Michal Vasko449afde2015-06-04 16:06:49 +0200331
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200332 if (shorthand) {
Radek Krejci76b07902015-10-09 09:11:25 +0200333 tree_print_snode(out, module, level, new_indent, max_name_len, node,
Radek Krejci76512572015-08-04 09:47:08 +0200334 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100335 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200336 } else {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200337 LY_TREE_FOR(node->child, sub) {
Michal Vasko3510f892016-02-15 14:33:52 +0100338 /* submodule, foreign augments */
339 if (module->type && (sub->parent != node) && (sub->module != module)) {
340 continue;
341 }
Radek Krejci76b07902015-10-09 09:11:25 +0200342 tree_print_snode(out, module, level, new_indent, max_name_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200343 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES,
Radek Krejcic071c542016-01-27 14:57:51 +0100344 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200345 }
346 }
Michal Vasko449afde2015-06-04 16:06:49 +0200347
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200348 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200349}
350
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200351static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100352tree_print_anyxml(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
353 const struct lys_node *node, int spec_config)
Michal Vasko315f70b2015-06-05 10:48:59 +0200354{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200355 uint8_t prefix_len;
Radek Krejcic071c542016-01-27 14:57:51 +0100356 struct lys_module *nodemod;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200357 struct lys_node_anyxml *anyxml = (struct lys_node_anyxml *)node;
Michal Vasko315f70b2015-06-05 10:48:59 +0200358
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200359 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200360
Radek Krejci76b07902015-10-09 09:11:25 +0200361 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200362 (anyxml->flags & LYS_STATUS_DEPRC ? "x" : (anyxml->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200363
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200364 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200365 ly_print(out, "%s ", (anyxml->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200366 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200367 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200368 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200369 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200370 }
371
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200372 prefix_len = 0;
Michal Vaskobda37192016-02-15 11:09:13 +0100373 nodemod = lys_node_module(node);
374 if (lys_module(module) != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100375 ly_print(out, "%s:", nodemod->name);
376 prefix_len = strlen(nodemod->name)+1;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200377 }
378
Radek Krejci76b07902015-10-09 09:11:25 +0200379 ly_print(out, "%s%s%*sanyxml", anyxml->name, (anyxml->flags & LYS_MAND_TRUE ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200380 3 + (int)((max_name_len - strlen(anyxml->name)) - prefix_len), " ");
Michal Vasko28c6b572015-06-18 12:43:31 +0200381
Radek Krejci76b07902015-10-09 09:11:25 +0200382 tree_print_features(out, (const struct lys_feature **)anyxml->features, anyxml->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200383
Radek Krejci76b07902015-10-09 09:11:25 +0200384 ly_print(out, "\n");
Michal Vasko315f70b2015-06-05 10:48:59 +0200385}
386
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200387static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100388tree_print_leaf(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
389 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200390{
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200391 uint8_t prefix_len;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200392 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
Radek Krejci76512572015-08-04 09:47:08 +0200393 struct lys_node *parent;
Radek Krejcib8048692015-08-05 13:36:34 +0200394 struct lys_node_list *list;
Radek Krejcic071c542016-01-27 14:57:51 +0100395 struct lys_module *nodemod;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200396 int i, is_key = 0;
Michal Vasko449afde2015-06-04 16:06:49 +0200397
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200398 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200399
Radek Krejci69372e22015-08-13 09:55:27 +0200400 /* get know if the leaf is a key in a list, in that case it is
401 * mandatory by default */
Radek Krejci76512572015-08-04 09:47:08 +0200402 for (parent = leaf->parent; parent && parent->nodetype == LYS_USES; parent = parent->parent);
Radek Krejci69372e22015-08-13 09:55:27 +0200403 if (parent && parent->nodetype == LYS_LIST) {
Radek Krejcib8048692015-08-05 13:36:34 +0200404 list = (struct lys_node_list *)parent;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200405 for (i = 0; i < list->keys_size; i++) {
Michal Vasko96929d92015-08-03 15:30:22 +0200406 if (list->keys[i] == leaf) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200407 is_key = 1;
408 break;
409 }
410 }
411 }
Michal Vasko449afde2015-06-04 16:06:49 +0200412
Radek Krejci76b07902015-10-09 09:11:25 +0200413 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200414 (leaf->flags & LYS_STATUS_DEPRC ? "x" : (leaf->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200415
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200416 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200417 ly_print(out, "%s ", (leaf->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200418 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200419 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200420 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200421 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200422 }
423
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200424 prefix_len = 0;
Michal Vaskobda37192016-02-15 11:09:13 +0100425 nodemod = lys_node_module(node);
426 if (lys_module(module) != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100427 ly_print(out, "%s:", nodemod->name);
428 prefix_len = strlen(nodemod->name)+1;
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200429 }
430
Radek Krejci76b07902015-10-09 09:11:25 +0200431 ly_print(out, "%s%s%*s", leaf->name, ((leaf->flags & LYS_MAND_TRUE) || is_key ? " " : "?"),
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200432 3 + (int)((max_name_len - strlen(leaf->name)) - prefix_len), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200433
Radek Krejci76b07902015-10-09 09:11:25 +0200434 tree_print_type(out, &leaf->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200435
Michal Vaskobda37192016-02-15 11:09:13 +0100436 if (leaf->dflt) {
Radek Krejci76b07902015-10-09 09:11:25 +0200437 ly_print(out, " <%s>", leaf->dflt);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200438 }
Michal Vasko28c6b572015-06-18 12:43:31 +0200439
Radek Krejci76b07902015-10-09 09:11:25 +0200440 tree_print_features(out, (const struct lys_feature **)leaf->features, leaf->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200441
Radek Krejci76b07902015-10-09 09:11:25 +0200442 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200443}
444
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200445static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100446tree_print_leaflist(struct lyout *out, const struct lys_module *module, char *indent, unsigned int max_name_len,
447 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200448{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200449 struct lys_node_leaflist *leaflist = (struct lys_node_leaflist *)node;
Radek Krejcic071c542016-01-27 14:57:51 +0100450 struct lys_module *nodemod;
Michal Vasko449afde2015-06-04 16:06:49 +0200451
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200452 assert(spec_config >= 0 && spec_config <= 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200453
Radek Krejci76b07902015-10-09 09:11:25 +0200454 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200455 (leaflist->flags & LYS_STATUS_DEPRC ? "x" : (leaflist->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200456
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200457 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200458 ly_print(out, "%s ", (leaflist->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200459 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200460 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200461 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200462 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200463 }
464
Michal Vaskobda37192016-02-15 11:09:13 +0100465 nodemod = lys_node_module(node);
466 if (lys_module(module) != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100467 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200468 }
469
Radek Krejci76b07902015-10-09 09:11:25 +0200470 ly_print(out, "%s*%*s", leaflist->name, 3 + (int)(max_name_len - strlen(leaflist->name)), " ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200471
Radek Krejci76b07902015-10-09 09:11:25 +0200472 tree_print_type(out, &leaflist->type);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200473
Radek Krejci76b07902015-10-09 09:11:25 +0200474 tree_print_features(out, (const struct lys_feature **)leaflist->features, leaflist->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200475
Radek Krejci76b07902015-10-09 09:11:25 +0200476 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200477}
478
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200479static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100480tree_print_list(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100481 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200482{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200483 int i;
484 unsigned int max_child_len;
485 char *new_indent;
Radek Krejci76512572015-08-04 09:47:08 +0200486 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200487 struct lys_node_list *list = (struct lys_node_list *)node;
Radek Krejcic071c542016-01-27 14:57:51 +0100488 struct lys_module *nodemod;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200489
Radek Krejci76b07902015-10-09 09:11:25 +0200490 ly_print(out, "%s%s--", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200491 (list->flags & LYS_STATUS_DEPRC ? "x" : (list->flags & LYS_STATUS_OBSLT ? "o" : "+")));
Michal Vaskob5c75d72015-06-15 12:16:52 +0200492
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200493 if (spec_config == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200494 ly_print(out, "%s ", (list->flags & LYS_CONFIG_W ? "rw" : "ro"));
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200495 } else if (spec_config == 1) {
Radek Krejci76b07902015-10-09 09:11:25 +0200496 ly_print(out, "-w ");
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200497 } else if (spec_config == 2) {
Radek Krejci76b07902015-10-09 09:11:25 +0200498 ly_print(out, "ro ");
Michal Vaskob5c75d72015-06-15 12:16:52 +0200499 }
500
Michal Vaskobda37192016-02-15 11:09:13 +0100501 nodemod = lys_node_module(node);
502 if (lys_module(module) != nodemod) {
Radek Krejci662f1c02016-02-11 11:31:24 +0100503 ly_print(out, "%s:", nodemod->name);
Michal Vaskofc3b0a32015-06-29 15:50:34 +0200504 }
505
Radek Krejci76b07902015-10-09 09:11:25 +0200506 ly_print(out, "%s*", list->name);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200507
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200508 for (i = 0; i < list->keys_size; i++) {
509 if (i == 0) {
Radek Krejci76b07902015-10-09 09:11:25 +0200510 ly_print(out, " [");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200511 }
Radek Krejcif3966532015-12-09 14:19:35 +0100512 ly_print(out, "%s%s", list->keys[i]->name, i + 1 < list->keys_size ? " " : "]");
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200513 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200514
Radek Krejci76b07902015-10-09 09:11:25 +0200515 tree_print_features(out, (const struct lys_feature **)list->features, list->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200516
Radek Krejci76b07902015-10-09 09:11:25 +0200517 ly_print(out, "\n");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200518
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200519 level++;
Michal Vaskobda37192016-02-15 11:09:13 +0100520 new_indent = create_indent(level, indent, node, 0, module);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200521
Radek Krejci1d82ef62015-08-07 14:44:40 +0200522 max_child_len = get_max_name_len(module, node->child);
Michal Vasko449afde2015-06-04 16:06:49 +0200523
Radek Krejci1d82ef62015-08-07 14:44:40 +0200524 LY_TREE_FOR(node->child, sub) {
Michal Vasko3510f892016-02-15 14:33:52 +0100525 /* submodule, foreign augments */
526 if (module->type && (sub->parent != node) && (sub->module != module)) {
527 continue;
528 }
Radek Krejci76b07902015-10-09 09:11:25 +0200529 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200530 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Radek Krejcic071c542016-01-27 14:57:51 +0100531 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200532 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200533
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200534 free(new_indent);
Michal Vasko5ed10f12015-06-04 10:04:57 +0200535}
536
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200537static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100538tree_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 +0100539 const struct lys_node *node, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200540{
Michal Vasko3510f892016-02-15 14:33:52 +0100541 struct lys_node *sub;
Radek Krejci7e97c352015-06-19 16:26:34 +0200542
Michal Vasko3510f892016-02-15 14:33:52 +0100543 LY_TREE_FOR(node->child, sub) {
544 tree_print_snode(out, module, level, indent, max_name_len, sub,
Radek Krejci76512572015-08-04 09:47:08 +0200545 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ANYXML,
Radek Krejcic071c542016-01-27 14:57:51 +0100546 spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200547 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200548}
549
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200550static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100551tree_print_rpc(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100552 const struct lys_node *node)
Michal Vaskob5c75d72015-06-15 12:16:52 +0200553{
554 char *new_indent;
Michal Vasko3510f892016-02-15 14:33:52 +0100555 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200556 struct lys_node_rpc *rpc = (struct lys_node_rpc *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200557
Radek Krejci1d82ef62015-08-07 14:44:40 +0200558 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200559 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200560 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200561
Radek Krejci76b07902015-10-09 09:11:25 +0200562 ly_print(out, "%s%s---x %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200563 (rpc->flags & LYS_STATUS_DEPRC ? "x" : (rpc->flags & LYS_STATUS_OBSLT ? "o" : "+")), rpc->name);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200564
Radek Krejci76b07902015-10-09 09:11:25 +0200565 tree_print_features(out, (const struct lys_feature **)rpc->features, rpc->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200566
Radek Krejci76b07902015-10-09 09:11:25 +0200567 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200568
Michal Vaskob5c75d72015-06-15 12:16:52 +0200569 level++;
Michal Vaskobda37192016-02-15 11:09:13 +0100570 new_indent = create_indent(level, indent, node, 0, module);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200571
Michal Vasko3510f892016-02-15 14:33:52 +0100572 LY_TREE_FOR(node->child, sub) {
573 /* submodule, foreign augments */
574 if (module->type && (sub->parent != node) && (sub->module != module)) {
575 continue;
576 }
577 if (sub->nodetype == LYS_INPUT) {
578 tree_print_inout(out, module, level, new_indent, sub, 1);
579 } else if (sub->nodetype == LYS_OUTPUT) {
580 tree_print_inout(out, module, level, new_indent, sub, 2);
Michal Vaskob5c75d72015-06-15 12:16:52 +0200581 }
582 }
583
584 free(new_indent);
585}
586
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200587static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100588tree_print_notif(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100589 const struct lys_node *node)
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200590{
591 unsigned int max_child_len;
592 char *new_indent;
Michal Vasko3510f892016-02-15 14:33:52 +0100593 struct lys_node *sub;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200594 struct lys_node_notif *notif = (struct lys_node_notif *)node;
Radek Krejci7e97c352015-06-19 16:26:34 +0200595
Radek Krejci1d82ef62015-08-07 14:44:40 +0200596 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200597 return;
Radek Krejci7e97c352015-06-19 16:26:34 +0200598 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200599
Radek Krejci76b07902015-10-09 09:11:25 +0200600 ly_print(out, "%s%s---n %s", indent,
Radek Krejci1574a8d2015-08-03 14:16:52 +0200601 (notif->flags & LYS_STATUS_DEPRC ? "x" : (notif->flags & LYS_STATUS_OBSLT ? "o" : "+")),
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200602 notif->name);
603
Radek Krejci76b07902015-10-09 09:11:25 +0200604 tree_print_features(out, (const struct lys_feature **)notif->features, notif->features_size);
Michal Vasko28c6b572015-06-18 12:43:31 +0200605
Radek Krejci76b07902015-10-09 09:11:25 +0200606 ly_print(out, "\n");
Michal Vasko28c6b572015-06-18 12:43:31 +0200607
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200608 level++;
Michal Vaskobda37192016-02-15 11:09:13 +0100609 new_indent = create_indent(level, indent, node, 0, module);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200610
Radek Krejci1d82ef62015-08-07 14:44:40 +0200611 max_child_len = get_max_name_len(module, node->child);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200612
Michal Vasko3510f892016-02-15 14:33:52 +0100613 LY_TREE_FOR(node->child, sub) {
614 /* submodule, foreign augments */
615 if (module->type && (sub->parent != node) && (sub->module != module)) {
616 continue;
617 }
618 tree_print_snode(out, module, level, new_indent, max_child_len, sub,
Radek Krejcic071c542016-01-27 14:57:51 +0100619 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_USES, 2);
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200620 }
621
622 free(new_indent);
623}
624
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200625static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100626tree_print_choice_content(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100627 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200628{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200629 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200630 return;
631 }
632
Radek Krejci1d82ef62015-08-07 14:44:40 +0200633 if (node->nodetype & mask) {
634 if (node->nodetype == LYS_CASE) {
Radek Krejcic071c542016-01-27 14:57:51 +0100635 tree_print_case(out, module, level, indent, max_name_len, node, 0, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200636 } else {
Radek Krejcic071c542016-01-27 14:57:51 +0100637 tree_print_case(out, module, level, indent, max_name_len, node, 1, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200638 }
639 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200640}
641
Michal Vaskoc176b682015-12-09 14:30:14 +0100642/* 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 +0200643static void
Michal Vasko1e62a092015-12-01 12:27:20 +0100644tree_print_snode(struct lyout *out, const struct lys_module *module, int level, char *indent,
Radek Krejcic071c542016-01-27 14:57:51 +0100645 unsigned int max_name_len, const struct lys_node *node, int mask, int spec_config)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200646{
Radek Krejci1d82ef62015-08-07 14:44:40 +0200647 if (lys_is_disabled(node, 0)) {
Michal Vaskoefbb3192015-07-08 10:35:00 +0200648 return;
Radek Krejci87e840c2015-06-19 16:44:54 +0200649 }
650
Radek Krejci1d82ef62015-08-07 14:44:40 +0200651 switch (node->nodetype & mask) {
Radek Krejci76512572015-08-04 09:47:08 +0200652 case LYS_CONTAINER:
Radek Krejcic071c542016-01-27 14:57:51 +0100653 tree_print_container(out, module, level, indent, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200654 break;
Radek Krejci76512572015-08-04 09:47:08 +0200655 case LYS_CHOICE:
Radek Krejcic071c542016-01-27 14:57:51 +0100656 tree_print_choice(out, module, level, indent, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200657 break;
Radek Krejci76512572015-08-04 09:47:08 +0200658 case LYS_LEAF:
Radek Krejci76b07902015-10-09 09:11:25 +0200659 tree_print_leaf(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200660 break;
Radek Krejci76512572015-08-04 09:47:08 +0200661 case LYS_LEAFLIST:
Radek Krejci76b07902015-10-09 09:11:25 +0200662 tree_print_leaflist(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200663 break;
Radek Krejci76512572015-08-04 09:47:08 +0200664 case LYS_LIST:
Radek Krejcic071c542016-01-27 14:57:51 +0100665 tree_print_list(out, module, level, indent, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200666 break;
Radek Krejci76512572015-08-04 09:47:08 +0200667 case LYS_ANYXML:
Radek Krejci76b07902015-10-09 09:11:25 +0200668 tree_print_anyxml(out, module, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200669 break;
Radek Krejci76512572015-08-04 09:47:08 +0200670 case LYS_USES:
Radek Krejcic071c542016-01-27 14:57:51 +0100671 tree_print_uses(out, module, level, indent, max_name_len, node, spec_config);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200672 break;
Michal Vaskod4742e62016-02-15 15:11:55 +0100673 case LYS_CASE:
674 /* a very special case of cases in an augment */
675 tree_print_case(out, module, level, indent, max_name_len, node, 0, spec_config);
676 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200677 default:
678 break;
679 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200680}
681
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200682int
Michal Vasko1e62a092015-12-01 12:27:20 +0100683tree_print_model(struct lyout *out, const struct lys_module *module)
Michal Vasko5ed10f12015-06-04 10:04:57 +0200684{
Michal Vaskobda37192016-02-15 11:09:13 +0100685 struct lys_node *node, *data;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200686 unsigned int max_child_len;
Radek Krejcic071c542016-01-27 14:57:51 +0100687 int level = 1, have_rpcs = 0, have_notifs = 0;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200688 char *indent = malloc((level * 4 + 1) * sizeof (char));
Radek Krejcid49202f2016-02-11 12:53:39 +0100689 int i;
Michal Vasko253035f2015-12-17 16:58:13 +0100690
691 if (!indent) {
692 LOGMEM;
693 return EXIT_FAILURE;
694 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200695 strcpy(indent, " ");
Michal Vasko5ed10f12015-06-04 10:04:57 +0200696
Michal Vaskofc6ac172015-07-07 09:46:46 +0200697 if (module->type) {
Radek Krejcic071c542016-01-27 14:57:51 +0100698 ly_print(out, "submodule: %s (belongs-to %s)\n", module->name,
699 ((struct lys_submodule *)module)->belongsto->name);
Michal Vaskobda37192016-02-15 11:09:13 +0100700 data = ((struct lys_submodule *)module)->belongsto->data;
Michal Vaskofc6ac172015-07-07 09:46:46 +0200701 } else {
Radek Krejci76b07902015-10-09 09:11:25 +0200702 ly_print(out, "module: %s\n", module->name);
Michal Vaskobda37192016-02-15 11:09:13 +0100703 data = module->data;
Michal Vaskofc6ac172015-07-07 09:46:46 +0200704 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200705
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200706 /* module */
Michal Vaskobda37192016-02-15 11:09:13 +0100707 max_child_len = get_max_name_len(module, data);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200708 level++;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200709
Michal Vaskobda37192016-02-15 11:09:13 +0100710 LY_TREE_FOR(data, node) {
711 if (module->type && (node->module != module)) {
712 /* we're printing the submodule only */
713 continue;
714 }
715
Radek Krejci92720552015-10-05 15:28:27 +0200716 switch(node->nodetype) {
717 case LYS_RPC:
Radek Krejciadf7a8e2015-12-10 13:11:17 +0100718 if (!lys_is_disabled(node, 0)) {
719 have_rpcs++;
720 }
Radek Krejci92720552015-10-05 15:28:27 +0200721 break;
722 case LYS_NOTIF:
Radek Krejciadf7a8e2015-12-10 13:11:17 +0100723 if (!lys_is_disabled(node, 0)) {
724 have_notifs++;
725 }
Radek Krejci92720552015-10-05 15:28:27 +0200726 break;
727 default:
Radek Krejcibac81762015-10-09 10:19:52 +0200728 tree_print_snode(out, module, level, indent, max_child_len, node,
Radek Krejci92720552015-10-05 15:28:27 +0200729 LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST
Radek Krejcic071c542016-01-27 14:57:51 +0100730 | LYS_ANYXML | LYS_USES, 0);
Radek Krejci92720552015-10-05 15:28:27 +0200731 break;
732 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200733 }
Michal Vasko5ed10f12015-06-04 10:04:57 +0200734
Radek Krejcid49202f2016-02-11 12:53:39 +0100735 /* augment */
736 for (i = 0; i < module->augment_size; i++) {
Michal Vasko861ee6d2016-02-15 15:11:31 +0100737 if ((module->type && (module->augment[i].target->module == module))
738 || (!module->type && (lys_node_module(module->augment[i].target) == module))) {
Michal Vaskoe79abe82016-02-15 12:33:23 +0100739 /* submodule, target is our submodule or module, target is in our module or any submodules */
740 continue;
741 }
742
Radek Krejcid49202f2016-02-11 12:53:39 +0100743 ly_print(out, "augment %s:\n", module->augment[i].target_name);
744 LY_TREE_FOR(module->augment[i].child, node) {
Michal Vaskod4742e62016-02-15 15:11:55 +0100745 /* submodule, foreign augments */
746 if (module->type && (node->module != module)) {
747 continue;
748 }
Radek Krejcid49202f2016-02-11 12:53:39 +0100749 tree_print_snode(out, module, level, indent, max_child_len, node,
Michal Vaskod4742e62016-02-15 15:11:55 +0100750 LYS_CHOICE | LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST
751 | LYS_LIST | LYS_ANYXML | LYS_USES, 0);
Radek Krejcid49202f2016-02-11 12:53:39 +0100752 }
753 }
754
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200755 /* rpc */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200756 if (have_rpcs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200757 ly_print(out, "rpcs:\n");
Michal Vaskobda37192016-02-15 11:09:13 +0100758 LY_TREE_FOR(data, node) {
Radek Krejci92720552015-10-05 15:28:27 +0200759 if (!have_rpcs) {
760 break;
761 }
762 if (node->nodetype == LYS_RPC) {
Radek Krejcic071c542016-01-27 14:57:51 +0100763 tree_print_rpc(out, module, level, indent, node);
Radek Krejci92720552015-10-05 15:28:27 +0200764 have_rpcs--;
765 }
Michal Vaskob5c75d72015-06-15 12:16:52 +0200766 }
767 }
Michal Vasko449afde2015-06-04 16:06:49 +0200768
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200769 /* notification */
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200770 if (have_notifs) {
Radek Krejci76b07902015-10-09 09:11:25 +0200771 ly_print(out, "notifications:\n");
Michal Vaskobda37192016-02-15 11:09:13 +0100772 LY_TREE_FOR(data, node) {
Radek Krejci92720552015-10-05 15:28:27 +0200773 if (!have_notifs) {
774 break;
775 }
776 if (node->nodetype == LYS_NOTIF) {
Radek Krejcic071c542016-01-27 14:57:51 +0100777 tree_print_notif(out, module, level, indent, node);
Radek Krejci92720552015-10-05 15:28:27 +0200778 have_notifs--;
779 }
Michal Vaskoe03bfbb2015-06-16 09:07:49 +0200780 }
781 }
Michal Vasko95068c42016-03-24 14:58:11 +0100782 ly_print_flush(out);
Michal Vasko449afde2015-06-04 16:06:49 +0200783
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200784 free(indent);
785 return EXIT_SUCCESS;
Michal Vasko5ed10f12015-06-04 10:04:57 +0200786}