blob: fe56d84bc8f16d0bac525eb4e387e39989d89b8a [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>
aPieceka83b8e02023-06-07 15:25:16 +02005 * @author Adam Piecek <piecek@cesnet.cz>
Radek Krejcie9f13b12020-11-09 17:42:04 +01006 * @brief 'load' 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
aPieceka83b8e02023-06-07 15:25:16 +020021#include <assert.h>
Radek Krejcie9f13b12020-11-09 17:42:04 +010022#include <getopt.h>
23#include <stdint.h>
24#include <stdio.h>
25#include <string.h>
26
27#include "libyang.h"
28
29#include "common.h"
aPieceka83b8e02023-06-07 15:25:16 +020030#include "yl_opt.h"
Radek Krejcie9f13b12020-11-09 17:42:04 +010031
32void
33cmd_load_help(void)
34{
35 printf("Usage: load [-i] <module-name1>[@<revision>] [<module-name2>[@revision] ...]\n"
36 " Add a new module of the specified name, yanglint will find\n"
aPiecek41955272023-05-10 16:10:17 +020037 " them in searchpaths. If the <revision> of the module not\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010038 " specified, the latest revision available is loaded.\n\n"
39 " -F FEATURES, --features=FEATURES\n"
Michal Vasko703370c2021-10-19 14:07:16 +020040 " Features to support, default all in all implemented modules.\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010041 " <modname>:[<feature>,]*\n"
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020042 " -i, --make-implemented\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010043 " Make the imported modules \"referenced\" from any loaded\n"
44 " <schema> module also implemented. If specified a second time,\n"
aPiecek88030e52023-06-02 11:03:57 +020045 " all the modules are set implemented.\n"
46 " -X, --extended-leafref\n"
47 " Allow usage of deref() XPath function within leafref.\n");
Radek Krejcie9f13b12020-11-09 17:42:04 +010048}
49
aPieceka83b8e02023-06-07 15:25:16 +020050int
51cmd_load_opt(struct yl_opt *yo, const char *cmdline, char ***posv, int *posc)
Radek Krejcie9f13b12020-11-09 17:42:04 +010052{
aPieceka83b8e02023-06-07 15:25:16 +020053 int rc, argc = 0;
Radek Krejcie9f13b12020-11-09 17:42:04 +010054 int opt, opt_index;
55 struct option options[] = {
56 {"features", required_argument, NULL, 'F'},
57 {"help", no_argument, NULL, 'h'},
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020058 {"make-implemented", no_argument, NULL, 'i'},
aPiecek88030e52023-06-02 11:03:57 +020059 {"extended-leafref", no_argument, NULL, 'X'},
Radek Krejcie9f13b12020-11-09 17:42:04 +010060 {NULL, 0, NULL, 0}
61 };
Radek Krejcie9f13b12020-11-09 17:42:04 +010062
aPieceka83b8e02023-06-07 15:25:16 +020063 if ((rc = parse_cmdline(cmdline, &argc, &yo->argv))) {
64 return rc;
Radek Krejcie9f13b12020-11-09 17:42:04 +010065 }
66
aPieceka83b8e02023-06-07 15:25:16 +020067 while ((opt = getopt_long(argc, yo->argv, commands[CMD_LOAD].optstring, options, &opt_index)) != -1) {
Radek Krejcie9f13b12020-11-09 17:42:04 +010068 switch (opt) {
69 case 'F': /* --features */
aPieceka83b8e02023-06-07 15:25:16 +020070 if (parse_features(optarg, &yo->schema_features)) {
71 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +010072 }
73 break;
74
75 case 'h':
76 cmd_load_help();
aPieceka83b8e02023-06-07 15:25:16 +020077 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +010078
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020079 case 'i': /* --make-implemented */
aPiecek7f22c102023-06-09 09:48:44 +020080 yo_opt_update_make_implemented(yo);
Radek Krejcie9f13b12020-11-09 17:42:04 +010081 break;
82
aPiecek88030e52023-06-02 11:03:57 +020083 case 'X': /* --extended-leafref */
aPieceka83b8e02023-06-07 15:25:16 +020084 yo->ctx_options |= LY_CTX_LEAFREF_EXTENDED;
aPiecek88030e52023-06-02 11:03:57 +020085 break;
86
Radek Krejcie9f13b12020-11-09 17:42:04 +010087 default:
88 YLMSG_E("Unknown option.\n");
aPieceka83b8e02023-06-07 15:25:16 +020089 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +010090 }
91 }
92
aPieceka83b8e02023-06-07 15:25:16 +020093 *posv = &yo->argv[optind];
94 *posc = argc - optind;
95
96 return 0;
97}
98
99int
100cmd_load_dep(struct yl_opt *yo, int posc)
101{
102 if (yo->interactive && !posc) {
Radek Krejcie9f13b12020-11-09 17:42:04 +0100103 /* no argument */
aPieceka83b8e02023-06-07 15:25:16 +0200104 cmd_load_help();
105 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100106 }
107
aPieceka83b8e02023-06-07 15:25:16 +0200108 if (!yo->schema_features.count) {
Michal Vasko703370c2021-10-19 14:07:16 +0200109 /* no features, enable all of them */
aPieceka83b8e02023-06-07 15:25:16 +0200110 yo->ctx_options |= LY_CTX_ENABLE_IMP_FEATURES;
Michal Vasko703370c2021-10-19 14:07:16 +0200111 }
112
aPieceka83b8e02023-06-07 15:25:16 +0200113 return 0;
114}
115
116int
117cmd_load_exec(struct ly_ctx **ctx, struct yl_opt *yo, const char *posv)
118{
119 const char *all_features[] = {"*", NULL};
120 char *revision;
121 const char **features = NULL;
122
123 assert(posv);
124
125 if (yo->ctx_options) {
126 ly_ctx_set_options(*ctx, yo->ctx_options);
127 yo->ctx_options = 0;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100128 }
129
aPieceka83b8e02023-06-07 15:25:16 +0200130 /* get revision */
131 revision = strchr(posv, '@');
132 if (revision) {
133 revision[0] = '\0';
134 ++revision;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100135 }
136
aPieceka83b8e02023-06-07 15:25:16 +0200137 /* get features list for this module */
138 if (!yo->schema_features.count) {
139 features = all_features;
140 } else {
141 get_features(&yo->schema_features, posv, &features);
Radek Krejcie9f13b12020-11-09 17:42:04 +0100142 }
aPieceka83b8e02023-06-07 15:25:16 +0200143
144 /* load the module */
145 if (!ly_ctx_load_module(*ctx, posv, revision, features)) {
146 /* libyang printed the error messages */
147 return 1;
148 }
149
150 return 0;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100151}