blob: 4a869afa4bac66c0a81075a3cee0112ddde98a65 [file] [log] [blame]
Radek Krejcie9f13b12020-11-09 17:42:04 +01001/**
2 * @file cmd_clear.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @author Radek Krejci <rkrejci@cesnet.cz>
aPieceka83b8e02023-06-07 15:25:16 +02005 * @author Adam Piecek <piecek@cesnet.cz>
Radek Krejcie9f13b12020-11-09 17:42:04 +01006 * @brief 'clear' command of the libyang's yanglint tool.
7 *
aPieceka83b8e02023-06-07 15:25:16 +02008 * Copyright (c) 2015-2023 CESNET, z.s.p.o.
Radek Krejcie9f13b12020-11-09 17:42:04 +01009 *
10 * This source code is licensed under BSD 3-Clause License (the "License").
11 * You may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * https://opensource.org/licenses/BSD-3-Clause
15 */
16
17#define _GNU_SOURCE
18
19#include "cmd.h"
20
21#include <getopt.h>
22#include <stdint.h>
23#include <stdio.h>
24
25#include "libyang.h"
26
27#include "common.h"
aPieceka83b8e02023-06-07 15:25:16 +020028#include "yl_opt.h"
Radek Krejcie9f13b12020-11-09 17:42:04 +010029
30void
31cmd_clear_help(void)
32{
Michal Vasko8b280602021-10-05 13:23:48 +020033 printf("Usage: clear [-i] [-y]\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010034 " Replace the current context with an empty one, searchpaths\n"
Michal Vasko8b280602021-10-05 13:23:48 +020035 " are not kept.\n\n"
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020036 " -i, --make-implemented\n"
aPiecek6c1e57e2023-03-30 14:43:34 +020037 " When loading a module into the context, the imported 'referenced'\n"
38 " modules will also be implemented. If specified a second time,\n"
39 " all the modules will be implemented.\n"
Michal Vaskoc431a0a2021-01-25 14:31:58 +010040 " -y, --yang-library\n"
41 " Load and implement internal \"ietf-yang-library\" YANG module.\n"
42 " Note that this module includes definitions of mandatory state\n"
aPiecek21c1bc82023-05-18 15:38:31 +020043 " data that can result in unexpected data validation errors.\n"
44 " -Y FILE, --yang-library-file=FILE\n"
45 " Parse FILE with \"ietf-yang-library\" data and use them to\n"
46 " create an exact YANG schema context. Searchpaths defined so far\n"
47 " are used, but then deleted.\n");
48}
49
aPieceka83b8e02023-06-07 15:25:16 +020050int
51cmd_clear_opt(struct yl_opt *yo, const char *cmdline, char ***posv, int *posc)
52{
53 int rc = 0, argc = 0;
54 int opt, opt_index;
55 struct option options[] = {
56 {"make-implemented", no_argument, NULL, 'i'},
57 {"yang-library", no_argument, NULL, 'y'},
58 {"yang-library-file", no_argument, NULL, 'Y'},
59 {"help", no_argument, NULL, 'h'},
60 {NULL, 0, NULL, 0}
61 };
62
63 yo->ctx_options = LY_CTX_NO_YANGLIBRARY;
64
65 if ((rc = parse_cmdline(cmdline, &argc, &yo->argv))) {
66 return rc;
67 }
68
69 while ((opt = getopt_long(argc, yo->argv, commands[CMD_CLEAR].optstring, options, &opt_index)) != -1) {
70 switch (opt) {
71 case 'i':
72 if (yo->ctx_options & LY_CTX_REF_IMPLEMENTED) {
73 yo->ctx_options &= ~LY_CTX_REF_IMPLEMENTED;
74 yo->ctx_options |= LY_CTX_ALL_IMPLEMENTED;
75 } else {
76 yo->ctx_options |= LY_CTX_REF_IMPLEMENTED;
77 }
78 break;
79 case 'y':
80 yo->ctx_options &= ~LY_CTX_NO_YANGLIBRARY;
81 break;
82 case 'Y':
83 yo->ctx_options &= ~LY_CTX_NO_YANGLIBRARY;
84 yo->yang_lib_file = optarg;
85 if (!yo->yang_lib_file) {
Michal Vasko1407d7d2023-08-21 09:57:54 +020086 YLMSG_E("Memory allocation error.");
aPieceka83b8e02023-06-07 15:25:16 +020087 return 1;
88 }
89 break;
90 case 'h':
91 cmd_clear_help();
92 return 1;
93 default:
Michal Vasko1407d7d2023-08-21 09:57:54 +020094 YLMSG_E("Unknown option.");
aPieceka83b8e02023-06-07 15:25:16 +020095 return 1;
96 }
97 }
98
99 *posv = &yo->argv[optind];
100 *posc = argc - optind;
101
102 return rc;
103}
104
105int
106cmd_clear_dep(struct yl_opt *yo, int posc)
107{
108 (void) yo;
109
110 if (posc) {
Michal Vasko1407d7d2023-08-21 09:57:54 +0200111 YLMSG_E("No positional arguments are allowed.");
aPieceka83b8e02023-06-07 15:25:16 +0200112 return 1;
113 }
114
115 return 0;
116}
117
aPiecek21c1bc82023-05-18 15:38:31 +0200118/**
119 * @brief Convert searchpaths into single string.
120 *
121 * @param[in] ctx Context with searchpaths.
122 * @param[out] searchpaths Collection of paths in the single string. Paths are delimited by colon ":"
123 * (on Windows, used semicolon ";" instead).
124 * @return LY_ERR value.
125 */
126static LY_ERR
127searchpaths_to_str(const struct ly_ctx *ctx, char **searchpaths)
128{
129 uint32_t i;
130 int rc = 0;
131 const char * const *dirs = ly_ctx_get_searchdirs(ctx);
132
133 for (i = 0; dirs[i]; ++i) {
134 rc = searchpath_strcat(searchpaths, dirs[i]);
135 if (!rc) {
136 break;
137 }
138 }
139
140 return rc;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100141}
142
aPieceka83b8e02023-06-07 15:25:16 +0200143int
144cmd_clear_exec(struct ly_ctx **ctx, struct yl_opt *yo, const char *posv)
Radek Krejcie9f13b12020-11-09 17:42:04 +0100145{
aPieceka83b8e02023-06-07 15:25:16 +0200146 (void) posv;
aPiecek21c1bc82023-05-18 15:38:31 +0200147 struct ly_ctx *ctx_new = NULL;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100148
aPieceka83b8e02023-06-07 15:25:16 +0200149 if (yo->yang_lib_file) {
150 if (searchpaths_to_str(*ctx, &yo->searchpaths)) {
Michal Vasko1407d7d2023-08-21 09:57:54 +0200151 YLMSG_E("Storing searchpaths failed.");
aPieceka83b8e02023-06-07 15:25:16 +0200152 return 1;
aPiecek21c1bc82023-05-18 15:38:31 +0200153 }
aPieceka83b8e02023-06-07 15:25:16 +0200154 if (ly_ctx_new_ylpath(yo->searchpaths, yo->yang_lib_file, LYD_UNKNOWN, yo->ctx_options, &ctx_new)) {
Michal Vasko1407d7d2023-08-21 09:57:54 +0200155 YLMSG_E("Unable to create libyang context with yang-library data.");
aPieceka83b8e02023-06-07 15:25:16 +0200156 return 1;
aPiecek21c1bc82023-05-18 15:38:31 +0200157 }
158 } else {
aPieceka83b8e02023-06-07 15:25:16 +0200159 if (ly_ctx_new(NULL, yo->ctx_options, &ctx_new)) {
Michal Vasko1407d7d2023-08-21 09:57:54 +0200160 YLMSG_W("Failed to create context.");
aPieceka83b8e02023-06-07 15:25:16 +0200161 return 1;
aPiecek21c1bc82023-05-18 15:38:31 +0200162 }
Radek Krejcie9f13b12020-11-09 17:42:04 +0100163 }
164
aPiecek647f62e2023-05-18 10:55:58 +0200165 /* Global variables in commands are also deleted. */
166 cmd_free();
167
Radek Krejci90ed21e2021-04-12 14:47:46 +0200168 ly_ctx_destroy(*ctx);
Radek Krejcie9f13b12020-11-09 17:42:04 +0100169 *ctx = ctx_new;
170
aPieceka83b8e02023-06-07 15:25:16 +0200171 return 0;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100172}