blob: 383cf93361440646615d8c8a5a1d298a3d9d75b3 [file] [log] [blame]
Michal Vasko2e79f262021-10-19 14:29:07 +02001/**
2 * @file cmd_feature.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief 'feature' command of the libyang's yanglint tool.
5 *
6 * Copyright (c) 2015-2021 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#define _GNU_SOURCE
16
17#include "cmd.h"
18
19#include <getopt.h>
20#include <stdint.h>
21#include <stdio.h>
22
23#include "libyang.h"
24
25#include "common.h"
26
27void
28cmd_feature_help(void)
29{
roman300b8782022-08-11 12:49:21 +020030 printf("Usage: feature [-f] <module> [<module>]*\n"
31 " feature -a [-f]\n"
32 " Print features of all the modules with state of each one.\n\n"
33 " -f <module1, module2, ...>, --feature-param <module1, module2, ...>\n"
34 " Generate features parameter for the command \"add\" \n"
35 " in the form of -F <module-name>:<features>\n"
36 " -a, --all \n"
37 " Print features of all implemented modules.\n");
Michal Vasko2e79f262021-10-19 14:29:07 +020038}
39
40void
41cmd_feature(struct ly_ctx **ctx, const char *cmdline)
42{
43 int argc = 0;
44 char **argv = NULL;
roman300b8782022-08-11 12:49:21 +020045 char *features_output = NULL;
Michal Vasko2e79f262021-10-19 14:29:07 +020046 int opt, opt_index, i;
roman300b8782022-08-11 12:49:21 +020047 ly_bool generate_features = 0, print_all = 0;
48 struct ly_set set = {0};
49 const struct lys_module *mod;
50 struct ly_out *out = NULL;
Michal Vasko2e79f262021-10-19 14:29:07 +020051 struct option options[] = {
52 {"help", no_argument, NULL, 'h'},
roman300b8782022-08-11 12:49:21 +020053 {"all", no_argument, NULL, 'a'},
54 {"feature-param", no_argument, NULL, 'f'},
Michal Vasko2e79f262021-10-19 14:29:07 +020055 {NULL, 0, NULL, 0}
56 };
Michal Vasko2e79f262021-10-19 14:29:07 +020057
58 if (parse_cmdline(cmdline, &argc, &argv)) {
59 goto cleanup;
60 }
61
aPiecek15cc4cf2023-04-17 15:23:21 +020062 while ((opt = getopt_long(argc, argv, commands[CMD_FEATURE].optstring, options, &opt_index)) != -1) {
Michal Vasko2e79f262021-10-19 14:29:07 +020063 switch (opt) {
64 case 'h':
65 cmd_feature_help();
66 goto cleanup;
roman300b8782022-08-11 12:49:21 +020067 case 'a':
68 print_all = 1;
69 break;
70 case 'f':
71 generate_features = 1;
72 break;
Michal Vasko2e79f262021-10-19 14:29:07 +020073 default:
74 YLMSG_E("Unknown option.\n");
75 goto cleanup;
76 }
77 }
78
roman300b8782022-08-11 12:49:21 +020079 if (ly_out_new_file(stdout, &out)) {
80 YLMSG_E("Unable to print to the standard output.\n");
81 goto cleanup;
82 }
83
84 if (print_all) {
85 if (print_all_features(out, *ctx, generate_features, &features_output)) {
86 YLMSG_E("Printing all features failed.\n");
87 goto cleanup;
88 }
89 if (generate_features) {
90 printf("%s\n", features_output);
91 }
92 goto cleanup;
93 }
94
Michal Vasko2e79f262021-10-19 14:29:07 +020095 if (argc == optind) {
96 YLMSG_E("Missing modules to print.\n");
97 goto cleanup;
98 }
99
100 for (i = 0; i < argc - optind; i++) {
roman300b8782022-08-11 12:49:21 +0200101 /* always erase the set, so the previous module's features don't carry over to the next module's features */
102 ly_set_erase(&set, NULL);
Michal Vasko26bbb272022-08-02 14:54:33 +0200103
roman300b8782022-08-11 12:49:21 +0200104 mod = ly_ctx_get_module_latest(*ctx, argv[optind + i]);
Michal Vasko2e79f262021-10-19 14:29:07 +0200105 if (!mod) {
106 YLMSG_E("Module \"%s\" not found.\n", argv[optind + i]);
107 goto cleanup;
108 }
109
110 /* collect features of the module */
111 if (collect_features(mod, &set)) {
112 goto cleanup;
113 }
114
roman300b8782022-08-11 12:49:21 +0200115 if (generate_features) {
116 if (generate_features_output(mod, &set, &features_output)) {
117 goto cleanup;
Michal Vasko2e79f262021-10-19 14:29:07 +0200118 }
roman300b8782022-08-11 12:49:21 +0200119 /* don't print features and their state of each module if generating features parameter */
120 continue;
Michal Vasko2e79f262021-10-19 14:29:07 +0200121 }
roman300b8782022-08-11 12:49:21 +0200122
123 print_features(out, mod, &set);
124 }
125
126 if (generate_features) {
127 printf("%s\n", features_output);
Michal Vasko2e79f262021-10-19 14:29:07 +0200128 }
129
130cleanup:
131 free_cmdline(argv);
roman300b8782022-08-11 12:49:21 +0200132 ly_out_free(out, NULL, 0);
133 ly_set_erase(&set, NULL);
134 free(features_output);
Michal Vasko2e79f262021-10-19 14:29:07 +0200135}