1 /**
2 * @file printer/info.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief INFO printer for libyang data model structure
5 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
8 * 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
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <assert.h>
19
20 #include "common.h"
21 #include "printer.h"
22 #include "tree_schema.h"
23 #include "resolve.h"
24
25 #define INDENT_LEN 11
26
27 static void
info_print_text(struct lyout * out,const char * text,const char * label)28 info_print_text(struct lyout *out, const char *text, const char *label)
29 {
30 const char *ptr1, *ptr2;
31 int first = 1;
32
33 ly_print(out, "%-*s", INDENT_LEN, label);
34
35 if (text) {
36 ptr1 = text;
37 while (1) {
38 ptr2 = strchr(ptr1, '\n');
39 if (!ptr2) {
40 if (first) {
41 ly_print(out, "%s\n", ptr1);
42 first = 0;
43 } else {
44 ly_print(out, "%*s%s\n", INDENT_LEN, "", ptr1);
45 }
46 break;
47 }
48 ++ptr2;
49 if (first) {
50 ly_print(out, "%.*s", (int)(ptr2-ptr1), ptr1);
51 first = 0;
52 } else {
53 ly_print(out, "%*s%.*s", INDENT_LEN, "", (int)(ptr2-ptr1), ptr1);
54 }
55 ptr1 = ptr2;
56 }
57 }
58
59 if (first) {
60 ly_print(out, "\n");
61 }
62 }
63
64 static void
info_print_snode(struct lyout * out,const struct lys_node * parent,const struct lys_node * node,const char * label)65 info_print_snode(struct lyout *out, const struct lys_node *parent, const struct lys_node *node, const char *label)
66 {
67 assert(strlen(label) < INDENT_LEN-1);
68
69 ly_print(out, "%-*s", INDENT_LEN, label);
70
71 if (node) {
72 if (node->name) {
73 ly_print(out, "%s \"", strnodetype(node->nodetype));
74 if (parent != lys_parent(node)) {
75 ly_print(out, "%s:", node->module->prefix);
76 }
77 ly_print(out, "%s\"\n", node->name);
78 } else {
79 ly_print(out, "%s\n", (node->nodetype == LYS_INPUT ? "input" : "output"));
80 }
81 node = node->next;
82 for (; node; node = node->next) {
83 if (node->name) {
84 ly_print(out, "%*s%s \"", INDENT_LEN, "", strnodetype(node->nodetype));
85 if (parent != lys_parent(node)) {
86 ly_print(out, "%s:", node->module->prefix);
87 }
88 ly_print(out, "%s\"\n", node->name);
89 } else {
90 ly_print(out, "%*s%s\n", INDENT_LEN, "", (node->nodetype == LYS_INPUT ? "input" : "output"));
91 }
92 }
93 } else {
94 ly_print(out, "\n");
95 }
96 }
97
98 static void
info_print_flags(struct lyout * out,uint16_t flags,uint16_t mask,int is_list)99 info_print_flags(struct lyout *out, uint16_t flags, uint16_t mask, int is_list)
100 {
101 if (mask & LYS_CONFIG_MASK) {
102 ly_print(out, "%-*s", INDENT_LEN, "Config: ");
103 if (flags & LYS_CONFIG_R) {
104 ly_print(out, "read-only\n");
105 } else {
106 ly_print(out, "read-write\n");
107 }
108 }
109
110 if (mask & LYS_STATUS_MASK) {
111 ly_print(out, "%-*s", INDENT_LEN, "Status: ");
112
113 if (flags & LYS_STATUS_DEPRC) {
114 ly_print(out, "deprecated\n");
115 } else if (flags & LYS_STATUS_OBSLT) {
116 ly_print(out, "obsolete\n");
117 } else {
118 ly_print(out, "current\n");
119 }
120 }
121
122 if (mask & LYS_MAND_MASK) {
123 ly_print(out, "%-*s", INDENT_LEN, "Mandatory: ");
124
125 if (flags & LYS_MAND_TRUE) {
126 ly_print(out, "yes\n");
127 } else {
128 ly_print(out, "no\n");
129 }
130 }
131
132 if (is_list && (mask & LYS_USERORDERED)) {
133 ly_print(out, "%-*s", INDENT_LEN, "Order: ");
134
135 if (flags & LYS_USERORDERED) {
136 ly_print(out, "user-ordered\n");
137 } else {
138 ly_print(out, "system-ordered\n");
139 }
140 }
141
142 if (!is_list && (mask & LYS_FENABLED)) {
143 ly_print(out, "%-*s", INDENT_LEN, "Enabled: ");
144
145 if (flags & LYS_FENABLED) {
146 ly_print(out, "yes\n");
147 } else {
148 ly_print(out, "no\n");
149 }
150 }
151 }
152
153 static void
info_print_if_feature(struct lyout * out,const struct lys_module * module,struct lys_iffeature * iffeature,uint8_t iffeature_size)154 info_print_if_feature(struct lyout *out, const struct lys_module *module,
155 struct lys_iffeature *iffeature, uint8_t iffeature_size)
156 {
157 int i;
158
159 ly_print(out, "%-*s", INDENT_LEN, "If-feats: ");
160
161 if (iffeature_size) {
162 ly_print_iffeature(out, module, &iffeature[0], 1);
163 ly_print(out, "\n");
164 for (i = 1; i < iffeature_size; ++i) {
165 ly_print(out, "%*s", INDENT_LEN, "");
166 ly_print_iffeature(out, module, &iffeature[i], 1);
167 ly_print(out, "\n");
168 }
169 } else {
170 ly_print(out, "\n");
171 }
172 }
173
174 static void
info_print_when(struct lyout * out,const struct lys_when * when)175 info_print_when(struct lyout *out, const struct lys_when *when)
176 {
177 ly_print(out, "%-*s", INDENT_LEN, "When: ");
178 if (when) {
179 ly_print(out, "%s\n", when->cond);
180 } else {
181 ly_print(out, "\n");
182 }
183 }
184
185 static void
info_print_must(struct lyout * out,const struct lys_restr * must,uint8_t must_size)186 info_print_must(struct lyout *out, const struct lys_restr *must, uint8_t must_size)
187 {
188 int i;
189
190 ly_print(out, "%-*s", INDENT_LEN, "Must: ");
191
192 if (must_size) {
193 ly_print(out, "%s\n", must[0].expr);
194 for (i = 1; i < must_size; ++i) {
195 ly_print(out, "%*s%s\n", INDENT_LEN, "", must[i].expr);
196 }
197 } else {
198 ly_print(out, "\n");
199 }
200 }
201
202 static void
info_print_typedef(struct lyout * out,const struct lys_tpdf * tpdf,uint8_t tpdf_size)203 info_print_typedef(struct lyout *out, const struct lys_tpdf *tpdf, uint8_t tpdf_size)
204 {
205 int i;
206
207 ly_print(out, "%-*s", INDENT_LEN, "Typedefs: ");
208
209 if (tpdf_size) {
210 ly_print(out, "%s\n", tpdf[0].name);
211 for (i = 1; i < tpdf_size; ++i) {
212 ly_print(out, "%*s%s", INDENT_LEN, "", tpdf[i].name);
213 }
214 } else {
215 ly_print(out, "\n");
216 }
217 }
218
219 static void
info_print_typedef_with_include(struct lyout * out,const struct lys_module * mod)220 info_print_typedef_with_include(struct lyout *out, const struct lys_module *mod)
221 {
222 int i, j, first = 1;
223
224 ly_print(out, "%-*s", INDENT_LEN, "Typedefs: ");
225
226 if (mod->tpdf_size) {
227 ly_print(out, "%s\n", mod->tpdf[0].name);
228 first = 0;
229
230 for (i = 1; i < mod->tpdf_size; ++i) {
231 ly_print(out, "%*s%s\n", INDENT_LEN, "", mod->tpdf[i].name);
232 }
233 }
234
235 for (i = 0; i < mod->inc_size; ++i) {
236 if (mod->inc[i].submodule->tpdf_size) {
237 if (first) {
238 ly_print(out, "%s (%s)\n", mod->inc[i].submodule->tpdf[0].name, mod->inc[i].submodule->name);
239 j = 1;
240 } else {
241 j = 0;
242 }
243 first = 0;
244
245 for (; j < mod->inc[i].submodule->tpdf_size; ++j) {
246 ly_print(out, "%*s%s (%s)\n", INDENT_LEN, "", mod->inc[i].submodule->tpdf[j].name, mod->inc[i].submodule->name);
247 }
248 }
249 }
250
251 if (first) {
252 ly_print(out, "\n");
253 }
254 }
255
256 static void
info_print_type_detail_(struct lyout * out,const struct lys_type * type,int uni)257 info_print_type_detail_(struct lyout *out, const struct lys_type *type, int uni)
258 {
259 unsigned int i;
260 struct lys_type *orig;
261
262 if (uni) {
263 ly_print(out, " ");
264 }
265
266 switch (type->base) {
267 case LY_TYPE_BINARY:
268 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "binary");
269 if (!uni) {
270 info_print_text(out, (type->info.binary.length ? type->info.binary.length->expr : NULL), "Length: ");
271 }
272 break;
273 case LY_TYPE_BITS:
274 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "bits");
275
276 assert(type->info.bits.count);
277 if (!uni) {
278 ly_print(out, "%-*s%u %s\n", INDENT_LEN, "Bits: ", type->info.bits.bit[0].pos, type->info.bits.bit[0].name);
279 for (i = 1; i < type->info.bits.count; ++i) {
280 ly_print(out, "%*s%u %s\n", INDENT_LEN, "", type->info.bits.bit[i].pos, type->info.bits.bit[i].name);
281 }
282 }
283
284 break;
285 case LY_TYPE_BOOL:
286 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "boolean");
287 break;
288 case LY_TYPE_DEC64:
289 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "decimal64");
290 if (!uni) {
291 info_print_text(out, (type->info.dec64.range ? type->info.dec64.range->expr : NULL), "Range: ");
292 assert(type->info.dec64.dig);
293 ly_print(out, "%-*s%u%s\n", INDENT_LEN, "Frac dig: ", type->info.dec64.dig,
294 type->der->type.der ? " (derived)" : "");
295 }
296 break;
297 case LY_TYPE_EMPTY:
298 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "empty");
299 break;
300 case LY_TYPE_ENUM:
301 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "enumeration");
302
303 for (orig = (struct lys_type *)type; !orig->info.enums.count; orig = &orig->der->type);
304
305 if (!uni) {
306 ly_print(out, "%-*s%s (%d)\n", INDENT_LEN, "Values: ",
307 orig->info.enums.enm[0].name, orig->info.enums.enm[0].value);
308 for (i = 1; i < orig->info.enums.count; ++i) {
309 ly_print(out, "%*s%s (%d)\n", INDENT_LEN, "",
310 orig->info.enums.enm[i].name, orig->info.enums.enm[i].value);
311 }
312 }
313
314 break;
315 case LY_TYPE_IDENT:
316 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "identityref");
317 if (!uni && type->info.ident.count) {
318 ly_print(out, "%-*s%s\n", INDENT_LEN, "Idents: ", type->info.ident.ref[0]->name);
319 for (i = 1; i < type->info.ident.count; ++i) {
320 ly_print(out, "%*s%s\n", INDENT_LEN, "", type->info.ident.ref[i]->name);
321 }
322 }
323 break;
324 case LY_TYPE_INST:
325 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "instance-identifier");
326 if (!uni) {
327 ly_print(out, "%-*s%s\n", INDENT_LEN, "Required: ", (type->info.inst.req < 1 ? "no" : "yes"));
328 }
329 break;
330 case LY_TYPE_INT8:
331 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "int8");
332 goto int_range;
333 case LY_TYPE_INT16:
334 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "int16");
335 goto int_range;
336 case LY_TYPE_INT32:
337 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "int32");
338 goto int_range;
339 case LY_TYPE_INT64:
340 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "int64");
341 goto int_range;
342 case LY_TYPE_UINT8:
343 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "uint8");
344 goto int_range;
345 case LY_TYPE_UINT16:
346 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "uint16");
347 goto int_range;
348 case LY_TYPE_UINT32:
349 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "uint32");
350 goto int_range;
351 case LY_TYPE_UINT64:
352 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "uint64");
353
354 int_range:
355 if (!uni) {
356 info_print_text(out, (type->info.num.range ? type->info.num.range->expr : NULL), "Range: ");
357 }
358 break;
359 case LY_TYPE_LEAFREF:
360 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "leafref");
361 if (!uni) {
362 info_print_text(out, type->info.lref.path, "Path: ");
363 }
364 break;
365 case LY_TYPE_STRING:
366 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "string");
367 if (!uni) {
368 info_print_text(out, (type->info.str.length ? type->info.str.length->expr : NULL), "Length: ");
369
370 ly_print(out, "%-*s", INDENT_LEN, "Pattern: ");
371 if (type->info.str.pat_count) {
372 ly_print(out, "%s%s\n", &type->info.str.patterns[0].expr[1],
373 type->info.str.patterns[0].expr[0] == 0x15 ? " (invert-match)" : "");
374 for (i = 1; i < type->info.str.pat_count; ++i) {
375 ly_print(out, "%*s%s%s\n", INDENT_LEN, "", &type->info.str.patterns[i].expr[1],
376 type->info.str.patterns[i].expr[0] == 0x15 ? " (invert-match)" : "");
377 }
378 } else {
379 ly_print(out, "\n");
380 }
381 }
382
383 break;
384 case LY_TYPE_UNION:
385 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "union");
386
387 if (!uni) {
388 for (i = 0; i < type->info.uni.count; ++i) {
389 info_print_type_detail_(out, &type->info.uni.types[i], 1);
390 }
391 }
392 break;
393 default:
394 /* unused outside libyang, we never should be here */
395 LOGINT(type->parent->module->ctx);
396 ly_print(out, "%-*s%s\n", INDENT_LEN, "Base type: ", "UNKNOWN");
397 break;
398 }
399
400 if (uni) {
401 ly_print(out, " ");
402 }
403 ly_print(out, "%-*s", INDENT_LEN, "Superior: ");
404 if (type->der) {
405 if (!lys_type_is_local(type)) {
406 ly_print(out, "%s:", type->der->module->name);
407 }
408 ly_print(out, "%s\n", type->der->name);
409 } else {
410 ly_print(out, "\n");
411 }
412 }
413
414 static void
info_print_type_detail(struct lyout * out,const struct lys_type * type,int * UNUSED (first))415 info_print_type_detail(struct lyout *out, const struct lys_type *type, int * UNUSED(first))
416 {
417 return info_print_type_detail_(out, type, 0);
418 }
419
420 static void
info_print_list_constr(struct lyout * out,uint32_t min,uint32_t max)421 info_print_list_constr(struct lyout *out, uint32_t min, uint32_t max)
422 {
423 ly_print(out, "%-*s%u..", INDENT_LEN, "Elements: ", min);
424 if (max) {
425 ly_print(out, "%u\n", max);
426 } else {
427 ly_print(out, "unbounded\n");
428 }
429 }
430
431 static void
info_print_unique(struct lyout * out,const struct lys_unique * unique,uint8_t unique_size)432 info_print_unique(struct lyout *out, const struct lys_unique *unique, uint8_t unique_size)
433 {
434 int i, j;
435
436 ly_print(out, "%-*s", INDENT_LEN, "Unique: ");
437
438 if (unique_size) {
439 ly_print(out, "%s\n", unique[0].expr[0]);
440 for (i = 0; i < unique_size; ++i) {
441 for (j = (!i ? 1 : 0); j < unique[i].expr_size; ++j) {
442 ly_print(out, "%*s%s\n", INDENT_LEN, "", unique[i].expr[j]);
443 }
444 }
445 } else {
446 ly_print(out, "\n");
447 }
448 }
449
450 static void
info_print_revision(struct lyout * out,const struct lys_revision * rev,uint8_t rev_size)451 info_print_revision(struct lyout *out, const struct lys_revision *rev, uint8_t rev_size)
452 {
453 int i;
454
455 ly_print(out, "%-*s", INDENT_LEN, "Revisions: ");
456
457 if (rev_size) {
458 ly_print(out, "%s\n", rev[0].date);
459 for (i = 1; i < rev_size; ++i) {
460 ly_print(out, "%*s%s\n", INDENT_LEN, "", rev[i].date);
461 }
462 } else {
463 ly_print(out, "\n");
464 }
465 }
466
467 static void
info_print_import_with_include(struct lyout * out,const struct lys_module * mod)468 info_print_import_with_include(struct lyout *out, const struct lys_module *mod)
469 {
470 int first = 1, i, j;
471
472 ly_print(out, "%-*s", INDENT_LEN, "Imports: ");
473 if (mod->imp_size) {
474 ly_print(out, "%s:%s\n", mod->imp[0].prefix, mod->imp[0].module->name);
475 i = 1;
476 first = 0;
477
478 for (; i < mod->imp_size; ++i) {
479 ly_print(out, "%*s%s:%s\n", INDENT_LEN, "", mod->imp[i].prefix, mod->imp[i].module->name);
480 }
481 }
482
483 for (j = 0; j < mod->inc_size; ++j) {
484 if (mod->inc[j].submodule->imp_size) {
485 if (first) {
486 ly_print(out, "%s:%s (%s)\n",
487 mod->inc[j].submodule->imp[0].prefix, mod->inc[j].submodule->imp[0].module->name, mod->inc[j].submodule->name);
488 i = 1;
489 } else {
490 i = 0;
491 }
492 first = 0;
493
494 for (; i < mod->inc[j].submodule->imp_size; ++i) {
495 ly_print(out, "%*s%s:%s (%s)\n", INDENT_LEN, "",
496 mod->inc[j].submodule->imp[i].prefix, mod->inc[j].submodule->imp[i].module->name, mod->inc[j].submodule->name);
497 }
498 }
499 }
500
501 if (first) {
502 ly_print(out, "\n");
503 }
504 }
505
506 static void
info_print_include(struct lyout * out,const struct lys_module * mod)507 info_print_include(struct lyout *out, const struct lys_module *mod)
508 {
509 int first = 1, i;
510
511 ly_print(out, "%-*s", INDENT_LEN, "Includes: ");
512 if (mod->inc_size) {
513 ly_print(out, "%s\n", mod->inc[0].submodule->name);
514 i = 1;
515 first = 0;
516
517 for (; i < mod->inc_size; ++i) {
518 ly_print(out, "%*s%s\n", INDENT_LEN, "", mod->inc[i].submodule->name);
519 }
520 }
521
522 if (first) {
523 ly_print(out, "\n");
524 }
525 }
526
527 static void
info_print_augment(struct lyout * out,const struct lys_module * mod)528 info_print_augment(struct lyout *out, const struct lys_module *mod)
529 {
530 int first = 1, i;
531
532 ly_print(out, "%-*s", INDENT_LEN, "Augments: ");
533 if (mod->augment_size) {
534 ly_print(out, "\"%s\"\n", mod->augment[0].target_name);
535 i = 1;
536 first = 0;
537
538 for (; i < mod->augment_size; ++i) {
539 ly_print(out, "%*s\"%s\"\n", INDENT_LEN, "", mod->augment[i].target_name);
540 }
541 }
542
543 if (first) {
544 ly_print(out, "\n");
545 }
546 }
547
548 static void
info_print_deviation(struct lyout * out,const struct lys_module * mod)549 info_print_deviation(struct lyout *out, const struct lys_module *mod)
550 {
551 int first = 1, i;
552
553 ly_print(out, "%-*s", INDENT_LEN, "Deviation: ");
554 if (mod->deviation_size) {
555 ly_print(out, "\"%s\"\n", mod->deviation[0].target_name);
556 i = 1;
557 first = 0;
558
559 for (; i < mod->deviation_size; ++i) {
560 ly_print(out, "%*s\"%s\"\n", INDENT_LEN, "", mod->deviation[i].target_name);
561 }
562 }
563
564 if (first) {
565 ly_print(out, "\n");
566 }
567 }
568
569 static void
info_print_ident_with_include(struct lyout * out,const struct lys_module * mod)570 info_print_ident_with_include(struct lyout *out, const struct lys_module *mod)
571 {
572 int first = 1, i, j;
573
574 ly_print(out, "%-*s", INDENT_LEN, "Idents: ");
575 if (mod->ident_size) {
576 ly_print(out, "%s\n", mod->ident[0].name);
577 i = 1;
578 first = 0;
579
580 for (; i < (signed)mod->ident_size; ++i) {
581 ly_print(out, "%*s%s\n", INDENT_LEN, "", mod->ident[i].name);
582 }
583 }
584
585 for (j = 0; j < mod->inc_size; ++j) {
586 if (mod->inc[j].submodule->ident_size) {
587 if (first) {
588 ly_print(out, "%s (%s)\n", mod->inc[j].submodule->ident[0].name, mod->inc[j].submodule->name);
589 i = 1;
590 } else {
591 i = 0;
592 }
593 first = 0;
594
595 for (; i < (signed)mod->inc[j].submodule->ident_size; ++i) {
596 ly_print(out, "%*s%s (%s)\n", INDENT_LEN, "", mod->inc[j].submodule->ident[i].name, mod->inc[j].submodule->name);
597 }
598 }
599 }
600
601 if (first) {
602 ly_print(out, "\n");
603 }
604 }
605
606 static void
info_print_features_with_include(struct lyout * out,const struct lys_module * mod)607 info_print_features_with_include(struct lyout *out, const struct lys_module *mod)
608 {
609 int first = 1, i, j;
610
611 ly_print(out, "%-*s", INDENT_LEN, "Features: ");
612 if (mod->features_size) {
613 ly_print(out, "%s\n", mod->features[0].name);
614 i = 1;
615 first = 0;
616
617 for (; i < mod->features_size; ++i) {
618 ly_print(out, "%*s%s\n", INDENT_LEN, "", mod->features[i].name);
619 }
620 }
621
622 for (j = 0; j < mod->inc_size; ++j) {
623 if (mod->inc[j].submodule->features_size) {
624 if (first) {
625 ly_print(out, "%s (%s)\n", mod->inc[j].submodule->features[0].name, mod->inc[j].submodule->name);
626 i = 1;
627 } else {
628 i = 0;
629 }
630 first = 0;
631
632 for (; i < mod->inc[j].submodule->features_size; ++i) {
633 ly_print(out, "%*s%s (%s)\n", INDENT_LEN, "", mod->inc[j].submodule->features[i].name, mod->inc[j].submodule->name);
634 }
635 }
636 }
637
638 if (first) {
639 ly_print(out, "\n");
640 }
641 }
642
643 static void
info_print_data_mainmod_with_include(struct lyout * out,const struct lys_module * mod)644 info_print_data_mainmod_with_include(struct lyout *out, const struct lys_module *mod)
645 {
646 int first = 1, from_include;
647 struct lys_node *node;
648 const struct lys_module *mainmod = lys_main_module(mod);
649
650 ly_print(out, "%-*s", INDENT_LEN, "Data: ");
651
652 if (mainmod->data) {
653 LY_TREE_FOR(mainmod->data, node) {
654 if (node->module != mod) {
655 if (mainmod != mod) {
656 continue;
657 } else {
658 from_include = 1;
659 }
660 } else {
661 from_include = 0;
662 }
663
664 if (!lys_parent(node) && !strcmp(node->name, "config") && !strcmp(node->module->name, "ietf-netconf")) {
665 /* node added by libyang, not actually in the model */
666 continue;
667 }
668
669 if (first) {
670 ly_print(out, "%s \"%s\"%s%s%s\n", strnodetype(node->nodetype), node->name, (from_include ? " (" : ""),
671 (from_include ? node->module->name : ""), (from_include ? ")" : ""));
672 first = 0;
673 } else {
674 ly_print(out, "%*s%s \"%s\"%s%s%s\n", INDENT_LEN, "", strnodetype(node->nodetype), node->name,
675 (from_include ? " (" : ""), (from_include ? node->module->name : ""), (from_include ? ")" : ""));
676 }
677 }
678 }
679
680 if (first) {
681 ly_print(out, "\n");
682 }
683 }
684
685 static void
info_print_typedef_detail(struct lyout * outf,const struct lys_tpdf * tpdf,int * UNUSED (first))686 info_print_typedef_detail(struct lyout *outf, const struct lys_tpdf *tpdf, int * UNUSED(first))
687 {
688 ly_print(outf, "%-*s%s\n", INDENT_LEN, "Typedef: ", tpdf->name);
689 ly_print(outf, "%-*s%s\n", INDENT_LEN, "Module: ", tpdf->module->name);
690 info_print_text(outf, tpdf->dsc, "Desc: ");
691 info_print_text(outf, tpdf->ref, "Reference: ");
692 info_print_flags(outf, tpdf->flags, LYS_STATUS_MASK, 0);
693 info_print_type_detail_(outf, &tpdf->type, 0);
694 info_print_text(outf, tpdf->units, "Units: ");
695 info_print_text(outf, tpdf->dflt, "Default: ");
696 }
697
698 static void
info_print_ident_detail(struct lyout * out,const struct lys_ident * ident,int * UNUSED (first))699 info_print_ident_detail(struct lyout *out, const struct lys_ident *ident, int * UNUSED(first))
700 {
701 unsigned int i;
702
703 ly_print(out, "%-*s%s\n", INDENT_LEN, "Identity: ", ident->name);
704 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", ident->module->name);
705 info_print_text(out, ident->dsc, "Desc: ");
706 info_print_text(out, ident->ref, "Reference: ");
707 info_print_flags(out, ident->flags, LYS_STATUS_MASK, 0);
708
709 ly_print(out, "%-*s", INDENT_LEN, "Base: ");
710 for (i = 0; i < ident->base_size; i++) {
711 ly_print(out, "%*s%s\n", i ? INDENT_LEN : 0, "", ident->base[i]->name);
712 }
713 if (!i) {
714 ly_print(out, "\n");
715 }
716
717 ly_print(out, "%-*s", INDENT_LEN, "Derived: ");
718 if (ident->der) {
719 for (i = 0; i < ident->der->number; i++) {
720 ly_print(out, "%*s%s\n", i ? INDENT_LEN : 0, "", ((struct lys_ident *)ident->der->set.g[i])->name);
721 }
722 if (!i) {
723 ly_print(out, "\n");
724 }
725 }
726 }
727
728 static void
info_print_feature_detail(struct lyout * out,const struct lys_feature * feat,int * UNUSED (first))729 info_print_feature_detail(struct lyout *out, const struct lys_feature *feat, int * UNUSED(first))
730 {
731 ly_print(out, "%-*s%s\n", INDENT_LEN, "Feature: ", feat->name);
732 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", feat->module->name);
733 info_print_text(out, feat->dsc, "Desc: ");
734 info_print_text(out, feat->ref, "Reference: ");
735 info_print_flags(out, feat->flags, LYS_STATUS_MASK | LYS_FENABLED, 0);
736 info_print_if_feature(out, feat->module, feat->iffeature, feat->iffeature_size);
737 }
738
739 static void
info_print_module(struct lyout * out,const struct lys_module * module)740 info_print_module(struct lyout *out, const struct lys_module *module)
741 {
742 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", module->name);
743 ly_print(out, "%-*s%s\n", INDENT_LEN, "Namespace: ", module->ns);
744 ly_print(out, "%-*s%s\n", INDENT_LEN, "Prefix: ", module->prefix);
745 info_print_text(out, module->dsc, "Desc: ");
746 info_print_text(out, module->ref, "Reference: ");
747 info_print_text(out, module->org, "Org: ");
748 info_print_text(out, module->contact, "Contact: ");
749 ly_print(out, "%-*s%s\n", INDENT_LEN, "YANG ver: ", (module->version == LYS_VERSION_1_1 ? "1.1" : "1.0"));
750 ly_print(out, "%-*s%s\n", INDENT_LEN, "Deviated: ", (module->deviated ? "yes" : "no"));
751 ly_print(out, "%-*s%s\n", INDENT_LEN, "Implement: ", (module->implemented ? "yes" : "no"));
752 info_print_text(out, module->filepath, "URI: file://");
753
754 info_print_revision(out, module->rev, module->rev_size);
755 info_print_include(out, module);
756 info_print_import_with_include(out, module);
757 info_print_typedef_with_include(out, module);
758 info_print_ident_with_include(out, module);
759 info_print_features_with_include(out, module);
760 info_print_augment(out, module);
761 info_print_deviation(out, module);
762
763 info_print_data_mainmod_with_include(out, module);
764 }
765
766 static void
info_print_submodule(struct lyout * out,const struct lys_submodule * module)767 info_print_submodule(struct lyout *out, const struct lys_submodule *module)
768 {
769 ly_print(out, "%-*s%s\n", INDENT_LEN, "Submodule: ", module->name);
770 ly_print(out, "%-*s%s\n", INDENT_LEN, "Parent: ", module->belongsto->name);
771 ly_print(out, "%-*s%s\n", INDENT_LEN, "Prefix: ", module->prefix);
772 info_print_text(out, module->dsc, "Desc: ");
773 info_print_text(out, module->ref, "Reference: ");
774 info_print_text(out, module->org, "Org: ");
775 info_print_text(out, module->contact, "Contact: ");
776
777 ly_print(out, "%-*s%s\n", INDENT_LEN, "YANG ver: ", (module->version == 2 ? "1.1" : "1.0"));
778 ly_print(out, "%-*s%s\n", INDENT_LEN, "Deviated: ", (module->deviated ? "yes" : "no"));
779 ly_print(out, "%-*s%s\n", INDENT_LEN, "Implement: ", (module->implemented ? "yes" : "no"));
780
781 info_print_text(out, module->filepath, "URI: file://");
782
783 info_print_revision(out, module->rev, module->rev_size);
784 info_print_include(out, (struct lys_module *)module);
785 info_print_import_with_include(out, (struct lys_module *)module);
786 info_print_typedef_with_include(out, (struct lys_module *)module);
787 info_print_ident_with_include(out, (struct lys_module *)module);
788 info_print_features_with_include(out, (struct lys_module *)module);
789 info_print_augment(out, (struct lys_module *)module);
790 info_print_deviation(out, (struct lys_module *)module);
791
792 info_print_data_mainmod_with_include(out, (struct lys_module *)module);
793 }
794
795 static void
info_print_container(struct lyout * out,const struct lys_node * node,int * UNUSED (first))796 info_print_container(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
797 {
798 struct lys_node_container *cont = (struct lys_node_container *)node;
799
800 ly_print(out, "%-*s%s\n", INDENT_LEN, "Container: ", cont->name);
801 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", cont->module->name);
802 info_print_text(out, cont->dsc, "Desc: ");
803 info_print_text(out, cont->ref, "Reference: ");
804 info_print_flags(out, cont->flags, LYS_CONFIG_MASK | LYS_STATUS_MASK, 0);
805 info_print_text(out, cont->presence, "Presence: ");
806 info_print_if_feature(out, cont->module, cont->iffeature, cont->iffeature_size);
807 info_print_when(out, cont->when);
808 info_print_must(out, cont->must, cont->must_size);
809 info_print_typedef(out, cont->tpdf, cont->tpdf_size);
810
811 info_print_snode(out, (struct lys_node *)cont, cont->child, "Children:");
812 }
813
814 static void
info_print_choice(struct lyout * out,const struct lys_node * node,int * UNUSED (first))815 info_print_choice(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
816 {
817 struct lys_node_choice *choice = (struct lys_node_choice *)node;
818
819 ly_print(out, "%-*s%s\n", INDENT_LEN, "Choice: ", choice->name);
820 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", choice->module->name);
821 info_print_text(out, choice->dsc, "Desc: ");
822 info_print_text(out, choice->ref, "Reference: ");
823 info_print_flags(out, choice->flags, LYS_CONFIG_MASK | LYS_STATUS_MASK | LYS_MAND_MASK, 0);
824 ly_print(out, "%-*s", INDENT_LEN, "Default: ");
825 if (choice->dflt) {
826 ly_print(out, "%s\n", choice->dflt->name);
827 } else {
828 ly_print(out, "\n");
829 }
830 info_print_if_feature(out, choice->module, choice->iffeature, choice->iffeature_size);
831 info_print_when(out, choice->when);
832
833 info_print_snode(out, (struct lys_node *)choice, choice->child, "Cases:");
834 }
835
836 static void
info_print_leaf(struct lyout * out,const struct lys_node * node,int * UNUSED (first))837 info_print_leaf(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
838 {
839 struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
840
841 ly_print(out, "%-*s%s\n", INDENT_LEN, "Leaf: ", leaf->name);
842 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", leaf->module->name);
843 info_print_text(out, leaf->dsc, "Desc: ");
844 info_print_text(out, leaf->ref, "Reference: ");
845 info_print_flags(out, leaf->flags, LYS_CONFIG_MASK | LYS_STATUS_MASK | LYS_MAND_MASK, 0);
846 info_print_text(out, leaf->type.der->name, "Type: ");
847 info_print_text(out, leaf->units, "Units: ");
848 info_print_text(out, leaf->dflt, "Default: ");
849 info_print_if_feature(out, leaf->module, leaf->iffeature, leaf->iffeature_size);
850 info_print_when(out, leaf->when);
851 info_print_must(out, leaf->must, leaf->must_size);
852 }
853
854 static void
info_print_leaflist(struct lyout * out,const struct lys_node * node,int * UNUSED (first))855 info_print_leaflist(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
856 {
857 struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
858
859 ly_print(out, "%-*s%s\n", INDENT_LEN, "Leaflist: ", llist->name);
860 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", llist->module->name);
861 info_print_text(out, llist->dsc, "Desc: ");
862 info_print_text(out, llist->ref, "Reference: ");
863 info_print_flags(out, llist->flags, LYS_CONFIG_MASK | LYS_STATUS_MASK | LYS_USERORDERED, 1);
864 info_print_text(out, llist->type.der->name, "Type: ");
865 info_print_text(out, llist->units, "Units: ");
866 info_print_list_constr(out, llist->min, llist->max);
867 info_print_if_feature(out, llist->module, llist->iffeature, llist->iffeature_size);
868 info_print_when(out, llist->when);
869 info_print_must(out, llist->must, llist->must_size);
870 }
871
872 static void
info_print_list(struct lyout * out,const struct lys_node * node,int * UNUSED (first))873 info_print_list(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
874 {
875 struct lys_node_list *list = (struct lys_node_list *)node;
876
877 ly_print(out, "%-*s%s\n", INDENT_LEN, "List: ", list->name);
878 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", list->module->name);
879 info_print_text(out, list->dsc, "Desc: ");
880 info_print_text(out, list->ref, "Reference: ");
881 info_print_flags(out, list->flags, LYS_CONFIG_MASK | LYS_STATUS_MASK | LYS_USERORDERED, 1);
882 info_print_list_constr(out, list->min, list->max);
883 info_print_if_feature(out, list->module, list->iffeature, list->iffeature_size);
884 info_print_when(out, list->when);
885 info_print_must(out, list->must, list->must_size);
886 info_print_text(out, list->keys_str, "Keys: ");
887 info_print_unique(out, list->unique, list->unique_size);
888 info_print_typedef(out, list->tpdf, list->tpdf_size);
889
890 info_print_snode(out, (struct lys_node *)list, list->child, "Children:");
891 }
892
893 static void
info_print_anydata(struct lyout * out,const struct lys_node * node,int * UNUSED (first))894 info_print_anydata(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
895 {
896 struct lys_node_anydata *any = (struct lys_node_anydata *)node;
897
898 ly_print(out, "%-*s%s\n", INDENT_LEN, "%s: ", any->nodetype == LYS_ANYXML ? "Anyxml" : "Anydata", any->name);
899 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", any->module->name);
900 info_print_text(out, any->dsc, "Desc: ");
901 info_print_text(out, any->ref, "Reference: ");
902 info_print_flags(out, any->flags, LYS_CONFIG_MASK | LYS_STATUS_MASK | LYS_MAND_MASK, 0);
903 info_print_if_feature(out, any->module, any->iffeature, any->iffeature_size);
904 info_print_when(out, any->when);
905 info_print_must(out, any->must, any->must_size);
906 }
907
908 static void
info_print_grouping(struct lyout * out,const struct lys_node * node,int * UNUSED (first))909 info_print_grouping(struct lyout *out, const struct lys_node *node, int * UNUSED(first))
910 {
911 struct lys_node_grp *group = (struct lys_node_grp *)node;
912
913 ly_print(out, "%-*s%s\n", INDENT_LEN, "Grouping: ", group->name);
914 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", group->module->name);
915 info_print_text(out, group->dsc, "Desc: ");
916 info_print_text(out, group->ref, "Reference: ");
917 info_print_flags(out, group->flags, LYS_STATUS_MASK, 0);
918 info_print_typedef(out, group->tpdf, group->tpdf_size);
919
920 info_print_snode(out, (struct lys_node *)group, group->child, "Children:");
921 }
922
923 static void
info_print_case(struct lyout * out,const struct lys_node * node,int * UNUSED (first))924 info_print_case(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
925 {
926 struct lys_node_case *cas = (struct lys_node_case *)node;
927
928 ly_print(out, "%-*s%s\n", INDENT_LEN, "Case: ", cas->name);
929 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", cas->module->name);
930 info_print_text(out, cas->dsc, "Desc: ");
931 info_print_text(out, cas->ref, "Reference: ");
932 info_print_flags(out, cas->flags, LYS_CONFIG_MASK | LYS_STATUS_MASK, 0);
933 info_print_if_feature(out, cas->module, cas->iffeature, cas->iffeature_size);
934 info_print_when(out, cas->when);
935
936 info_print_snode(out, (struct lys_node *)cas, cas->child, "Children:");
937 }
938
939 static void
info_print_input(struct lyout * out,const struct lys_node * node,int * UNUSED (first))940 info_print_input(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
941 {
942 struct lys_node_inout *input = (struct lys_node_inout *)node;
943
944 assert(lys_parent(node) && lys_parent(node)->nodetype == LYS_RPC);
945
946 ly_print(out, "%-*s%s\n", INDENT_LEN, "Input of: ", lys_parent(node)->name);
947 info_print_typedef(out, input->tpdf, input->tpdf_size);
948 info_print_must(out, input->must, input->must_size);
949
950 info_print_snode(out, (struct lys_node *)input, input->child, "Children:");
951 }
952
953 static void
info_print_output(struct lyout * out,const struct lys_node * node,int * UNUSED (first))954 info_print_output(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
955 {
956 struct lys_node_inout *output = (struct lys_node_inout *)node;
957
958 assert(lys_parent(node) && lys_parent(node)->nodetype == LYS_RPC);
959
960 ly_print(out, "%-*s%s\n", INDENT_LEN, "Output of: ", lys_parent(node)->name);
961 info_print_typedef(out, output->tpdf, output->tpdf_size);
962 info_print_must(out, output->must, output->must_size);
963
964 info_print_snode(out, (struct lys_node *)output, output->child, "Children:");
965 }
966
967 static void
info_print_notif(struct lyout * out,const struct lys_node * node,int * UNUSED (first))968 info_print_notif(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
969 {
970 struct lys_node_notif *ntf = (struct lys_node_notif *)node;
971
972 ly_print(out, "%-*s%s\n", INDENT_LEN, "Notif: ", ntf->name);
973 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", ntf->module->name);
974 info_print_text(out, ntf->dsc, "Desc: ");
975 info_print_text(out, ntf->ref, "Reference: ");
976 info_print_flags(out, ntf->flags, LYS_STATUS_MASK, 0);
977 info_print_if_feature(out, ntf->module, ntf->iffeature, ntf->iffeature_size);
978 info_print_typedef(out, ntf->tpdf, ntf->tpdf_size);
979 info_print_must(out, ntf->must, ntf->must_size);
980
981 info_print_snode(out, (struct lys_node *)ntf, ntf->child, "Params:");
982 }
983
984 static void
info_print_rpc(struct lyout * out,const struct lys_node * node,int * UNUSED (first))985 info_print_rpc(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
986 {
987 struct lys_node_rpc_action *rpc = (struct lys_node_rpc_action *)node;
988
989 ly_print(out, "%-*s%s\n", INDENT_LEN, "RPC: ", rpc->name);
990 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", rpc->module->name);
991 info_print_text(out, rpc->dsc, "Desc: ");
992 info_print_text(out, rpc->ref, "Reference: ");
993 info_print_flags(out, rpc->flags, LYS_STATUS_MASK, 0);
994 info_print_if_feature(out, rpc->module, rpc->iffeature, rpc->iffeature_size);
995 info_print_typedef(out, rpc->tpdf, rpc->tpdf_size);
996
997 info_print_snode(out, (struct lys_node *)rpc, rpc->child, "Data:");
998 }
999
1000 static void
info_print_action(struct lyout * out,const struct lys_node * node,int * UNUSED (first))1001 info_print_action(struct lyout *out, const struct lys_node *node, int *UNUSED(first))
1002 {
1003 struct lys_node_rpc_action *act = (struct lys_node_rpc_action *)node;
1004
1005 ly_print(out, "%-*s%s\n", INDENT_LEN, "Action: ", act->name);
1006 ly_print(out, "%-*s%s\n", INDENT_LEN, "Module: ", act->module->name);
1007 info_print_text(out, act->dsc, "Desc: ");
1008 info_print_text(out, act->ref, "Reference: ");
1009 info_print_flags(out, act->flags, LYS_STATUS_MASK, 0);
1010 info_print_if_feature(out, act->module, act->iffeature, act->iffeature_size);
1011 info_print_typedef(out, act->tpdf, act->tpdf_size);
1012
1013 info_print_snode(out, (struct lys_node *)act, act->child, "Data:");
1014 }
1015
1016 int
info_print_model(struct lyout * out,const struct lys_module * module,const char * target_schema_path)1017 info_print_model(struct lyout *out, const struct lys_module *module, const char *target_schema_path)
1018 {
1019 int rc = EXIT_SUCCESS;
1020
1021 if (!target_schema_path) {
1022 if (module->type == 0) {
1023 info_print_module(out, module);
1024 } else {
1025 info_print_submodule(out, (struct lys_submodule *)module);
1026 }
1027 } else {
1028 rc = lys_print_target(out, module, target_schema_path,
1029 info_print_typedef_detail,
1030 info_print_ident_detail,
1031 info_print_feature_detail,
1032 info_print_type_detail,
1033 info_print_grouping,
1034 info_print_container,
1035 info_print_choice,
1036 info_print_leaf,
1037 info_print_leaflist,
1038 info_print_list,
1039 info_print_anydata,
1040 info_print_case,
1041 info_print_notif,
1042 info_print_rpc,
1043 info_print_action,
1044 info_print_input,
1045 info_print_output);
1046 }
1047 ly_print_flush(out);
1048
1049 return rc;
1050 }
1051