blob: 808c1253cd2eecd31ed72e8d8df20d10e35c0f0c [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"
aPiecekd8f002f2023-06-21 10:40:41 +020031#include "yl_schema_features.h"
Radek Krejcie9f13b12020-11-09 17:42:04 +010032
33void
34cmd_load_help(void)
35{
36 printf("Usage: load [-i] <module-name1>[@<revision>] [<module-name2>[@revision] ...]\n"
37 " Add a new module of the specified name, yanglint will find\n"
aPiecek41955272023-05-10 16:10:17 +020038 " them in searchpaths. If the <revision> of the module not\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010039 " specified, the latest revision available is loaded.\n\n"
40 " -F FEATURES, --features=FEATURES\n"
Michal Vasko703370c2021-10-19 14:07:16 +020041 " Features to support, default all in all implemented modules.\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010042 " <modname>:[<feature>,]*\n"
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020043 " -i, --make-implemented\n"
Radek Krejcie9f13b12020-11-09 17:42:04 +010044 " Make the imported modules \"referenced\" from any loaded\n"
45 " <schema> module also implemented. If specified a second time,\n"
aPiecek88030e52023-06-02 11:03:57 +020046 " all the modules are set implemented.\n"
47 " -X, --extended-leafref\n"
48 " Allow usage of deref() XPath function within leafref.\n");
Radek Krejcie9f13b12020-11-09 17:42:04 +010049}
50
aPieceka83b8e02023-06-07 15:25:16 +020051int
52cmd_load_opt(struct yl_opt *yo, const char *cmdline, char ***posv, int *posc)
Radek Krejcie9f13b12020-11-09 17:42:04 +010053{
aPieceka83b8e02023-06-07 15:25:16 +020054 int rc, argc = 0;
Radek Krejcie9f13b12020-11-09 17:42:04 +010055 int opt, opt_index;
56 struct option options[] = {
57 {"features", required_argument, NULL, 'F'},
58 {"help", no_argument, NULL, 'h'},
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020059 {"make-implemented", no_argument, NULL, 'i'},
aPiecek88030e52023-06-02 11:03:57 +020060 {"extended-leafref", no_argument, NULL, 'X'},
Radek Krejcie9f13b12020-11-09 17:42:04 +010061 {NULL, 0, NULL, 0}
62 };
Radek Krejcie9f13b12020-11-09 17:42:04 +010063
aPieceka83b8e02023-06-07 15:25:16 +020064 if ((rc = parse_cmdline(cmdline, &argc, &yo->argv))) {
65 return rc;
Radek Krejcie9f13b12020-11-09 17:42:04 +010066 }
67
aPieceka83b8e02023-06-07 15:25:16 +020068 while ((opt = getopt_long(argc, yo->argv, commands[CMD_LOAD].optstring, options, &opt_index)) != -1) {
Radek Krejcie9f13b12020-11-09 17:42:04 +010069 switch (opt) {
70 case 'F': /* --features */
aPieceka83b8e02023-06-07 15:25:16 +020071 if (parse_features(optarg, &yo->schema_features)) {
72 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +010073 }
74 break;
75
76 case 'h':
77 cmd_load_help();
aPieceka83b8e02023-06-07 15:25:16 +020078 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +010079
Michal Vasko8d6d0ad2021-10-19 12:32:27 +020080 case 'i': /* --make-implemented */
aPiecek7f22c102023-06-09 09:48:44 +020081 yo_opt_update_make_implemented(yo);
Radek Krejcie9f13b12020-11-09 17:42:04 +010082 break;
83
aPiecek88030e52023-06-02 11:03:57 +020084 case 'X': /* --extended-leafref */
aPieceka83b8e02023-06-07 15:25:16 +020085 yo->ctx_options |= LY_CTX_LEAFREF_EXTENDED;
aPiecek88030e52023-06-02 11:03:57 +020086 break;
87
Radek Krejcie9f13b12020-11-09 17:42:04 +010088 default:
Michal Vasko1407d7d2023-08-21 09:57:54 +020089 YLMSG_E("Unknown option.");
aPieceka83b8e02023-06-07 15:25:16 +020090 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +010091 }
92 }
93
aPieceka83b8e02023-06-07 15:25:16 +020094 *posv = &yo->argv[optind];
95 *posc = argc - optind;
96
97 return 0;
98}
99
100int
101cmd_load_dep(struct yl_opt *yo, int posc)
102{
103 if (yo->interactive && !posc) {
Radek Krejcie9f13b12020-11-09 17:42:04 +0100104 /* no argument */
aPieceka83b8e02023-06-07 15:25:16 +0200105 cmd_load_help();
106 return 1;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100107 }
108
aPieceka83b8e02023-06-07 15:25:16 +0200109 if (!yo->schema_features.count) {
Michal Vasko703370c2021-10-19 14:07:16 +0200110 /* no features, enable all of them */
aPieceka83b8e02023-06-07 15:25:16 +0200111 yo->ctx_options |= LY_CTX_ENABLE_IMP_FEATURES;
Michal Vasko703370c2021-10-19 14:07:16 +0200112 }
113
aPieceka83b8e02023-06-07 15:25:16 +0200114 return 0;
115}
116
117int
118cmd_load_exec(struct ly_ctx **ctx, struct yl_opt *yo, const char *posv)
119{
120 const char *all_features[] = {"*", NULL};
121 char *revision;
122 const char **features = NULL;
123
124 assert(posv);
125
126 if (yo->ctx_options) {
127 ly_ctx_set_options(*ctx, yo->ctx_options);
128 yo->ctx_options = 0;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100129 }
130
aPieceka83b8e02023-06-07 15:25:16 +0200131 /* get revision */
132 revision = strchr(posv, '@');
133 if (revision) {
134 revision[0] = '\0';
135 ++revision;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100136 }
137
aPieceka83b8e02023-06-07 15:25:16 +0200138 /* get features list for this module */
139 if (!yo->schema_features.count) {
140 features = all_features;
141 } else {
142 get_features(&yo->schema_features, posv, &features);
Radek Krejcie9f13b12020-11-09 17:42:04 +0100143 }
aPieceka83b8e02023-06-07 15:25:16 +0200144
145 /* load the module */
146 if (!ly_ctx_load_module(*ctx, posv, revision, features)) {
147 /* libyang printed the error messages */
148 return 1;
149 }
150
151 return 0;
Radek Krejcie9f13b12020-11-09 17:42:04 +0100152}