summaryrefslogtreecommitdiffstats
path: root/tools/lint/cmd_feature.c
blob: 6b332ab81be2d96e52c422f2bf24ae11c21e337f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
 * @file cmd_feature.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief 'feature' command of the libyang's yanglint tool.
 *
 * Copyright (c) 2015-2021 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE

#include "cmd.h"

#include <getopt.h>
#include <stdint.h>
#include <stdio.h>

#include "libyang.h"

#include "common.h"

void
cmd_feature_help(void)
{
    printf("Usage: feature [-f] <module> [<module>]*\n"
            "       feature -a [-f]\n"
            "                  Print features of all the modules with state of each one.\n\n"
            "  -f <module1, module2, ...>, --feature-param <module1, module2, ...>\n"
            "                  Generate features parameter for the command \"add\" \n"
            "                  in the form of -F <module-name>:<features>\n"
            "  -a, --all \n"
            "                  Print features of all implemented modules.\n");
}

void
cmd_feature(struct ly_ctx **ctx, const char *cmdline)
{
    int argc = 0;
    char **argv = NULL;
    char *features_output = NULL;
    int opt, opt_index, i;
    ly_bool generate_features = 0, print_all = 0;
    struct ly_set set = {0};
    const struct lys_module *mod;
    struct ly_out *out = NULL;
    struct option options[] = {
        {"help", no_argument, NULL, 'h'},
        {"all", no_argument, NULL, 'a'},
        {"feature-param", no_argument, NULL, 'f'},
        {NULL, 0, NULL, 0}
    };

    if (parse_cmdline(cmdline, &argc, &argv)) {
        goto cleanup;
    }

    while ((opt = getopt_long(argc, argv, "haf", options, &opt_index)) != -1) {
        switch (opt) {
        case 'h':
            cmd_feature_help();
            goto cleanup;
        case 'a':
            print_all = 1;
            break;
        case 'f':
            generate_features = 1;
            break;
        default:
            YLMSG_E("Unknown option.\n");
            goto cleanup;
        }
    }

    if (ly_out_new_file(stdout, &out)) {
        YLMSG_E("Unable to print to the standard output.\n");
        goto cleanup;
    }

    if (print_all) {
        if (print_all_features(out, *ctx, generate_features, &features_output)) {
            YLMSG_E("Printing all features failed.\n");
            goto cleanup;
        }
        if (generate_features) {
            printf("%s\n", features_output);
        }
        goto cleanup;
    }

    if (argc == optind) {
        YLMSG_E("Missing modules to print.\n");
        goto cleanup;
    }

    for (i = 0; i < argc - optind; i++) {
        /* always erase the set, so the previous module's features don't carry over to the next module's features */
        ly_set_erase(&set, NULL);

        mod = ly_ctx_get_module_latest(*ctx, argv[optind + i]);
        if (!mod) {
            YLMSG_E("Module \"%s\" not found.\n", argv[optind + i]);
            goto cleanup;
        }

        /* collect features of the module */
        if (collect_features(mod, &set)) {
            goto cleanup;
        }

        if (generate_features) {
            if (generate_features_output(mod, &set, &features_output)) {
                goto cleanup;
            }
            /* don't print features and their state of each module if generating features parameter */
            continue;
        }

        print_features(out, mod, &set);
    }

    if (generate_features) {
        printf("%s\n", features_output);
    }

cleanup:
    free_cmdline(argv);
    ly_out_free(out, NULL, 0);
    ly_set_erase(&set, NULL);
    free(features_output);
}