blob: 797167c0aa15ba424f8a5d6e0e77e8059b7eabb4 [file] [log] [blame]
Radek Krejcie9f13b12020-11-09 17:42:04 +01001/**
2 * @file cmd_load.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @author Radek Krejci <rkrejci@cesnet.cz>
5 * @brief 'load' command of the libyang's yanglint tool.
6 *
7 * Copyright (c) 2015-2020 CESNET, z.s.p.o.
8 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
15
16#define _GNU_SOURCE
17
18#include "cmd.h"
19
20#include <getopt.h>
21#include <stdint.h>
22#include <stdio.h>
23#include <string.h>
24
25#include "libyang.h"
26
27#include "common.h"
28
29void
30cmd_load_help(void)
31{
32 printf("Usage: load [-i] <module-name1>[@<revision>] [<module-name2>[@revision] ...]\n"
33 " Add a new module of the specified name, yanglint will find\n"
aPiecek41955272023-05-10 16:10:17 +020034 " them in searchpaths. If the <revision> of the module not\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010035 " specified, the latest revision available is loaded.\n\n"
36 " -F FEATURES, --features=FEATURES\n"
Michal Vasko703370c2021-10-19 14:07:16 +020037 " Features to support, default all in all implemented modules.\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010038 " <modname>:[<feature>,]*\n"
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020039 " -i, --make-implemented\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010040 " Make the imported modules \"referenced\" from any loaded\n"
41 " <schema> module also implemented. If specified a second time,\n"
aPiecek88030e52023-06-02 11:03:57 +020042 " all the modules are set implemented.\n"
43 " -X, --extended-leafref\n"
44 " Allow usage of deref() XPath function within leafref.\n");
Radek Krejcie9f13b12020-11-09 17:42:04 +010045}
46
47void
48cmd_load(struct ly_ctx **ctx, const char *cmdline)
49{
50 int argc = 0;
51 char **argv = NULL;
52 int opt, opt_index;
53 struct option options[] = {
54 {"features", required_argument, NULL, 'F'},
55 {"help", no_argument, NULL, 'h'},
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020056 {"make-implemented", no_argument, NULL, 'i'},
aPiecek88030e52023-06-02 11:03:57 +020057 {"extended-leafref", no_argument, NULL, 'X'},
Radek Krejcie9f13b12020-11-09 17:42:04 +010058 {NULL, 0, NULL, 0}
59 };
60 uint16_t options_ctx = 0;
Michal Vasko584b0c42022-09-14 10:20:52 +020061 const char *all_features[] = {"*", NULL};
Radek Krejcie9f13b12020-11-09 17:42:04 +010062 struct ly_set fset = {0};
63
64 if (parse_cmdline(cmdline, &argc, &argv)) {
65 goto cleanup;
66 }
67
aPiecek15cc4cf2023-04-17 15:23:21 +020068 while ((opt = getopt_long(argc, argv, commands[CMD_LOAD].optstring, options, &opt_index)) != -1) {
Radek Krejcie9f13b12020-11-09 17:42:04 +010069 switch (opt) {
70 case 'F': /* --features */
71 if (parse_features(optarg, &fset)) {
72 goto cleanup;
73 }
74 break;
75
76 case 'h':
77 cmd_load_help();
78 goto cleanup;
79
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020080 case 'i': /* --make-implemented */
Radek Krejcie9f13b12020-11-09 17:42:04 +010081 if (options_ctx & LY_CTX_REF_IMPLEMENTED) {
82 options_ctx &= ~LY_CTX_REF_IMPLEMENTED;
83 options_ctx |= LY_CTX_ALL_IMPLEMENTED;
84 } else {
85 options_ctx |= LY_CTX_REF_IMPLEMENTED;
86 }
87 break;
88
aPiecek88030e52023-06-02 11:03:57 +020089 case 'X': /* --extended-leafref */
90 options_ctx |= LY_CTX_LEAFREF_EXTENDED;
91 break;
92
Radek Krejcie9f13b12020-11-09 17:42:04 +010093 default:
94 YLMSG_E("Unknown option.\n");
95 goto cleanup;
96 }
97 }
98
99 if (argc == optind) {
100 /* no argument */
101 cmd_add_help();
102 goto cleanup;
103 }
104
Michal Vasko703370c2021-10-19 14:07:16 +0200105 if (!fset.count) {
106 /* no features, enable all of them */
107 options_ctx |= LY_CTX_ENABLE_IMP_FEATURES;
108 }
109
Radek Krejcie9f13b12020-11-09 17:42:04 +0100110 if (options_ctx) {
111 ly_ctx_set_options(*ctx, options_ctx);
112 }
113
114 for (int i = 0; i < argc - optind; i++) {
115 /* process the schema module files */
116 char *revision;
117 const char **features = NULL;
118
119 /* get revision */
120 revision = strchr(argv[optind + i], '@');
121 if (revision) {
122 revision[0] = '\0';
123 ++revision;
124 }
125
126 /* get features list for this module */
Michal Vasko584b0c42022-09-14 10:20:52 +0200127 if (!fset.count) {
128 features = all_features;
129 } else {
130 get_features(&fset, argv[optind + i], &features);
131 }
Radek Krejcie9f13b12020-11-09 17:42:04 +0100132
133 /* load the module */
134 if (!ly_ctx_load_module(*ctx, argv[optind + i], revision, features)) {
135 /* libyang printed the error messages */
136 goto cleanup;
137 }
138 }
139
140cleanup:
141 if (options_ctx) {
142 ly_ctx_unset_options(*ctx, options_ctx);
143 }
144 ly_set_erase(&fset, free_features);
145 free_cmdline(argv);
146}