yanglint REFACTOR reflect libyang changes of parsing RPC reply
Since 2552ea3651, the reply's request is not identified by a standalone
RPC/Action tree, but by a top level container around the reply data
identifying the original request. This change must be reflected also in
yanglint(1) which allows to parse replies.
diff --git a/tools/lint/cmd_data.c b/tools/lint/cmd_data.c
index dba9705..a3fe6e7 100644
--- a/tools/lint/cmd_data.c
+++ b/tools/lint/cmd_data.c
@@ -33,14 +33,10 @@
{
printf("Usage: data [-ems] [-t TYPE]\n"
" [-f FORMAT] [-d DEFAULTS] [-o OUTFILE] <data1> ...\n"
- " data [-s] -t (rpc | notif) [-O FILE]\n"
+ " data [-s] -t (rpc | notif | reply) [-O FILE]\n"
" [-f FORMAT] [-d DEFAULTS] [-o OUTFILE] <data1> ...\n"
- " data [-s] -t reply -r <request-file> [-O FILE]\n"
- " [-f FORMAT] [-d DEFAULTS] [-o OUTFILE] <data1> ...\n"
- " data [-s] -t reply [-O FILE]\n"
- " [-f FORMAT] [-d DEFAULTS] [-o OUTFILE] <data1> <request1> ...\n"
" data [-es] [-t TYPE] -x XPATH [-o OUTFILE] <data1> ...\n"
- " Parse, validate and optionaly print data instances\n\n"
+ " Parse, validate and optionally print data instances\n\n"
" -t TYPE, --type=TYPE\n"
" Specify data tree type in the input data file(s):\n"
@@ -51,12 +47,10 @@
" edit - Content of the NETCONF <edit-config> operation.\n"
" rpc - Content of the NETCONF <rpc> message, defined as YANG's\n"
" RPC/Action input statement.\n"
- " reply - Reply to the RPC/Action. Besides the reply itself,\n"
- " yanglint(1) requires information about the request for\n"
- " the reply. The request (RPC/Action) can be provide as\n"
- " the --request option or as another input data <file>\n"
- " provided right after the reply data <file> and\n"
- " containing complete RPC/Action for the reply.\n"
+ " reply - Reply to the RPC/Action. Note that the reply data are\n"
+ " expected inside a container representing the original\n"
+ " RPC/Action. This is necessary to identify appropriate\n"
+ " data definitions in the schema module.\n"
" notif - Notification instance (content of the <notification>\n"
" element without <eventTime>).\n\n"
@@ -70,15 +64,6 @@
" In case of using -x option, the data are always merged.\n"
" -s, --strict Strict data parsing (do not skip unknown data), has no effect\n"
" for schemas.\n"
- " -r PATH, --request=PATH\n"
- " The alternative way of providing request information for the\n"
- " '--type=reply'. The PATH is the XPath subset described in\n"
- " documentation as Path format. It is required to point to the\n"
- " RPC or Action in the schema which is supposed to be a request\n"
- " for the reply(ies) being parsed from the input data files.\n"
- " In case of multiple input data files, the 'request' option can\n"
- " be set once for all the replies or multiple times each for the\n"
- " respective input data file.\n"
" -O FILE, --operational=FILE\n"
" Provide optional data to extend validation of the 'rpc',\n"
" 'reply' or 'notif' TYPEs. The FILE is supposed to contain\n"
@@ -110,55 +95,6 @@
}
-static int
-prepare_inputs(int argc, char *argv[], struct ly_set *requests, struct ly_set *inputs)
-{
- struct ly_in *in;
- uint8_t request_expected = 0;
-
- for (int i = 0; i < argc - optind; i++) {
- LYD_FORMAT format = LYD_UNKNOWN;
- struct cmdline_file *rec;
-
- if (get_input(argv[optind + i], NULL, &format, &in)) {
- return -1;
- }
-
- if (request_expected) {
- if (fill_cmdline_file(requests, in, argv[optind + i], format)) {
- ly_in_free(in, 1);
- return -1;
- }
-
- request_expected = 0;
- } else {
- rec = fill_cmdline_file(inputs, in, argv[optind + i], format);
- if (!rec) {
- ly_in_free(in, 1);
- return -1;
- }
-
- if (requests) {
- /* requests for the replies are expected in another input file */
- if (++i == argc - optind) {
- /* there is no such file */
- YLMSG_E("Missing request input file for the reply input file %s.\n", rec->path);
- return -1;
- }
-
- request_expected = 1;
- }
- }
- }
-
- if (request_expected) {
- YLMSG_E("Missing request input file for the reply input file %s.\n", argv[argc - optind - 1]);
- return -1;
- }
-
- return 0;
-}
-
void
cmd_data(struct ly_ctx **ctx, const char *cmdline)
{
@@ -173,7 +109,6 @@
{"merge", no_argument, NULL, 'm'},
{"output", required_argument, NULL, 'o'},
{"operational", required_argument, NULL, 'O'},
- {"request", required_argument, NULL, 'r'},
{"strict", no_argument, NULL, 's'},
{"type", required_argument, NULL, 't'},
{"xpath", required_argument, NULL, 'x'},
@@ -190,8 +125,6 @@
struct ly_out *out = NULL;
struct cmdline_file *operational = NULL;
struct ly_set inputs = {0};
- struct ly_set requests = {0};
- struct ly_set request_paths = {0};
struct ly_set xpaths = {0};
if (parse_cmdline(cmdline, &argc, &argv)) {
@@ -253,12 +186,6 @@
operational = fill_cmdline_file(NULL, in, optarg, f);
break;
} /* case 'O' */
- case 'r': /* --request */
- if (ly_set_add(&request_paths, optarg, 0, NULL)) {
- YLMSG_E("Storing request path \"%s\" failed.\n", optarg);
- goto cleanup;
- }
- break;
case 'e': /* --present */
options_validate |= LYD_VALIDATE_PRESENT;
@@ -346,13 +273,16 @@
}
/* process input data files provided as standalone command line arguments */
- if (prepare_inputs(argc, argv, ((data_type == LYD_VALIDATE_OP_REPLY) && !request_paths.count) ? &requests : NULL,
- &inputs)) {
- goto cleanup;
- }
+ for (int i = 0; i < argc - optind; i++) {
+ struct ly_in *in;
+ LYD_FORMAT format = LYD_UNKNOWN;
- if (data_type == LYD_VALIDATE_OP_REPLY) {
- if (check_request_paths(*ctx, &request_paths, &inputs)) {
+ if (get_input(argv[optind + i], NULL, &format, &in)) {
+ goto cleanup;
+ }
+
+ if (fill_cmdline_file(&inputs, in, argv[optind + i], format)) {
+ ly_in_free(in, 1);
goto cleanup;
}
}
@@ -368,15 +298,13 @@
/* parse, validate and print data */
if (process_data(*ctx, data_type, data_merge, format, out,
options_parse, options_validate, options_print,
- operational, &inputs, &request_paths, &requests, &xpaths)) {
+ operational, &inputs, &xpaths)) {
goto cleanup;
}
cleanup:
ly_out_free(out, NULL, 0);
ly_set_erase(&inputs, free_cmdline_file);
- ly_set_erase(&requests, free_cmdline_file);
- ly_set_erase(&request_paths, NULL);
ly_set_erase(&xpaths, NULL);
free_cmdline_file(operational);
free_cmdline(argv);
diff --git a/tools/lint/common.c b/tools/lint/common.c
index d2b4f5e..a072074 100644
--- a/tools/lint/common.c
+++ b/tools/lint/common.c
@@ -398,32 +398,6 @@
}
int
-check_request_paths(struct ly_ctx *ctx, struct ly_set *request_paths, struct ly_set *data_inputs)
-{
- if ((request_paths->count > 1) && (request_paths->count != data_inputs->count)) {
- YLMSG_E("Number of request paths does not match the number of reply data files (%u:%u).\n",
- request_paths->count, data_inputs->count);
- return -1;
- }
-
- for (uint32_t u = 0; u < request_paths->count; ++u) {
- const char *path = (const char *)request_paths->objs[u];
- const struct lysc_node *action = NULL;
-
- action = lys_find_path(ctx, NULL, path, 0);
- if (!action) {
- YLMSG_E("The request path \"%s\" is not valid.\n", path);
- return -1;
- } else if (!(action->nodetype & (LYS_RPC | LYS_ACTION))) {
- YLMSG_E("The request path \"%s\" does not represent RPC/Action.\n", path);
- return -1;
- }
- }
-
- return 0;
-}
-
-int
evaluate_xpath(const struct lyd_node *tree, const char *xpath)
{
struct ly_set *set = NULL;
@@ -460,8 +434,7 @@
LY_ERR
process_data(struct ly_ctx *ctx, uint8_t data_type, uint8_t merge, LYD_FORMAT format, struct ly_out *out,
uint32_t options_parse, uint32_t options_validate, uint32_t options_print,
- struct cmdline_file *operational_f, struct ly_set *inputs, struct ly_set *request_paths, struct ly_set *requests,
- struct ly_set *xpaths)
+ struct cmdline_file *operational_f, struct ly_set *inputs, struct ly_set *xpaths)
{
LY_ERR ret = LY_SUCCESS;
struct lyd_node *tree = NULL, *merged_tree = NULL;
@@ -478,7 +451,6 @@
for (uint32_t u = 0; u < inputs->count; ++u) {
struct cmdline_file *input_f = (struct cmdline_file *)inputs->objs[u];
- struct cmdline_file *request_f;
switch (data_type) {
case 0:
ret = lyd_parse_data(ctx, input_f->in, input_f->format, options_parse, options_validate, &tree);
@@ -486,41 +458,9 @@
case LYD_VALIDATE_OP_RPC:
ret = lyd_parse_rpc(ctx, input_f->in, input_f->format, &tree, NULL);
break;
- case LYD_VALIDATE_OP_REPLY: {
- struct lyd_node *request = NULL;
-
- /* get the request data */
- if (request_paths->count) {
- const char *path;
- if (request_paths->count > 1) {
- /* one to one */
- path = (const char *)request_paths->objs[u];
- } else {
- /* one to all */
- path = (const char *)request_paths->objs[0];
- }
- ret = lyd_new_path(NULL, ctx, path, NULL, 0, &request);
- if (ret) {
- YLMSG_E("Failed to create request data from path \"%s\".\n", path);
- goto cleanup;
- }
- } else {
- assert(requests->count > u);
- request_f = (struct cmdline_file *)requests->objs[u];
-
- ret = lyd_parse_rpc(ctx, request_f->in, request_f->format, &request, NULL);
- if (ret) {
- YLMSG_E("Failed to parse input data file \"%s\".\n", input_f->path);
- goto cleanup;
- }
- }
-
- /* get the reply data */
- ret = lyd_parse_reply(request, input_f->in, input_f->format, &tree, NULL);
- lyd_free_all(request);
-
+ case LYD_VALIDATE_OP_REPLY:
+ ret = lyd_parse_reply(ctx, input_f->in, input_f->format, &tree, NULL);
break;
- } /* case PARSE_REPLY */
case LYD_VALIDATE_OP_NOTIF:
ret = lyd_parse_notif(ctx, input_f->in, input_f->format, &tree, NULL);
break;
diff --git a/tools/lint/common.h b/tools/lint/common.h
index 8e78a10..21b8618 100644
--- a/tools/lint/common.h
+++ b/tools/lint/common.h
@@ -164,20 +164,6 @@
int print_list(struct ly_out *out, struct ly_ctx *ctx, LYD_FORMAT outformat);
/**
- * @brief Check correctness of the specified Request XPaths for the input data files representing RPCs/Actions.
- *
- * If the requests specified as XPath(s) of the RPC/Action, there must be only a single path applying to all the replies
- * or their number must correspond to the number of replies in input data files.
- *
- * @param[in] ctx libyang context with the schema modules to check the correctness of the paths.
- * @param[in] request_paths The set of Requests' XPaths to check.
- * @param[in] data_inputs The set of data file inputs with the replies to be parsed.
- * @return 0 on success
- * @return -1 on error
- */
-int check_request_paths(struct ly_ctx *ctx, struct ly_set *request_paths, struct ly_set *data_inputs);
-
-/**
* @brief Process the input data files - parse, validate and print according to provided options.
*
* @param[in] ctx libyang context with schema.
@@ -192,16 +178,12 @@
* @param[in] operational_f Optional operational datastore file information for the case of an extended validation of
* operation(s).
* @param[in] inputs Set of file informations of input data files.
- * @param[in] request_paths Set of xpaths refering to the request RPCs/Actions for the replies being processed.
- * @param[in] requests The set of input data files containing request RPCs/Actions for the replies being processed.
- * Alternative to @p request_paths.
* @param[in] xpath The set of XPaths to be evaluated on the processed data tree, basic information about the resulting set
* is printed. Alternative to data printing.
* return LY_ERR value.
*/
LY_ERR process_data(struct ly_ctx *ctx, uint8_t data_type, uint8_t merge, LYD_FORMAT format, struct ly_out *out,
uint32_t options_parse, uint32_t options_validate, uint32_t options_print,
- struct cmdline_file *operational_f, struct ly_set *inputs, struct ly_set *request_paths, struct ly_set *requests,
- struct ly_set *xpaths);
+ struct cmdline_file *operational_f, struct ly_set *inputs, struct ly_set *xpaths);
#endif /* COMMON_H_ */
diff --git a/tools/lint/main_ni.c b/tools/lint/main_ni.c
index 78da7f1..1dde2f5 100644
--- a/tools/lint/main_ni.c
+++ b/tools/lint/main_ni.c
@@ -81,20 +81,6 @@
/* input data files (struct cmdline_file *) */
struct ly_set data_inputs;
- /* the request files for reply data (struct cmdline_file *)
- * In case the data_type is PARSE_REPLY, the parsing function requires information about the request for this reply.
- * One way to provide the request is a data file containing the full RPC/Action request which will be parsed.
- * Alternatively, it can be set as the Path of the requested RPC/Action and in that case it is stored in
- * data_request_paths.
- */
- struct ly_set data_requests;
- /* An alternative way of providing requests for parsing data replies, instead of providing full
- * request in a data file, only the Path of the requested RPC/Action is provided and stored as
- * const char *. Note that the number of items in the set must be 1 (1 applies to all) or equal to
- * data_inputs_count (1 to 1 mapping).
- */
- struct ly_set data_request_paths;
-
/* storage for --operational */
struct cmdline_file data_operational;
};
@@ -104,8 +90,6 @@
{
/* data */
ly_set_erase(&c->data_inputs, free_cmdline_file);
- ly_set_erase(&c->data_requests, free_cmdline_file);
- ly_set_erase(&c->data_request_paths, NULL);
ly_in_free(c->data_operational.in, 1);
/* schema */
@@ -132,7 +116,7 @@
printf("Usage:\n"
" yanglint [Options] [-f { yang | yin | info}] <schema>...\n"
" Validates the YANG module in <schema>, and all its dependencies.\n\n"
- " yanglint [Options] [-f { xml | json }] <schema>... <file> [<request>]...\n"
+ " yanglint [Options] [-f { xml | json }] <schema>... <file> ...\n"
" Validates the YANG modeled data in <file> according to the <schema>.\n\n"
" yanglint\n"
" Starts interactive mode with more features.\n\n");
@@ -222,23 +206,12 @@
" edit - Content of the NETCONF <edit-config> operation.\n"
" rpc - Content of the NETCONF <rpc> message, defined as YANG's\n"
" RPC/Action input statement.\n"
- " reply - Reply to the RPC/Action. Besides the reply itself,\n"
- " yanglint(1) requires information about the request for\n"
- " the reply. The request (RPC/Action) can be provided as\n"
- " the --request option or as another input data <file>\n"
- " provided right after the reply data <file> and\n"
- " containing complete RPC/Action for the reply.\n"
+ " reply - Reply to the RPC/Action. Note that the reply data are\n"
+ " expected inside a container representing the original\n"
+ " RPC/Action. This is necessary to identify appropriate\n"
+ " data definitions in the schema module.\n"
" notif - Notification instance (content of the <notification>\n"
" element without <eventTime>).\n"
- " -r PATH, --request=PATH\n"
- " The alternative way of providing request information for the\n"
- " '--type=reply'. The PATH is the XPath subset described in\n"
- " documentation as Path format. It is required to point to the\n"
- " RPC or Action in the schema which is supposed to be a request\n"
- " for the reply(ies) being parsed from the input data files.\n"
- " In case of multiple input data files, the 'request' option can\n"
- " be set once for all the replies or multiple times each for the\n"
- " respective input data file.\n\n"
" -O FILE, --operational=FILE\n"
" Provide optional data to extend validation of the 'rpc',\n"
@@ -297,7 +270,6 @@
fill_context_inputs(int argc, char *argv[], struct context *c)
{
struct ly_in *in;
- uint8_t request_expected = 0;
/* process the operational content if any */
if (c->data_operational.path) {
@@ -355,44 +327,17 @@
goto error;
}
}
- } else if (request_expected) {
- if (fill_cmdline_file(&c->data_requests, in, argv[optind + i], format_data)) {
- goto error;
- }
- in = NULL;
-
- request_expected = 0;
} else if (format_data) {
- struct cmdline_file *rec;
-
- rec = fill_cmdline_file(&c->data_inputs, in, argv[optind + i], format_data);
- if (!rec) {
+ if (!fill_cmdline_file(&c->data_inputs, in, argv[optind + i], format_data)) {
goto error;
}
in = NULL;
-
- if ((c->data_type == LYD_VALIDATE_OP_REPLY) && !c->data_request_paths.count) {
- /* requests for the replies are expected in another input file */
- if (++i == argc - optind) {
- /* there is no such file */
- YLMSG_E("Missing request input file for the reply input file %s.\n", rec->path);
- goto error;
- }
-
- request_expected = 1;
- }
} else {
ly_in_free(in, 1);
in = NULL;
}
}
- if (request_expected) {
- YLMSG_E("Missing request input file for the reply input file %s.\n",
- ((struct cmdline_file *)c->data_inputs.objs[c->data_inputs.count - 1])->path);
- return -1;
- }
-
return 0;
error:
@@ -431,7 +376,6 @@
{"path", required_argument, NULL, 'p'},
{"schema-node", required_argument, NULL, 'P'},
{"single-node", no_argument, NULL, 'q'},
- {"request", required_argument, NULL, 'r'},
{"strict", no_argument, NULL, 's'},
{"type", required_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'},
@@ -443,9 +387,9 @@
uint8_t data_type_set = 0;
#ifndef NDEBUG
- while ((opt = getopt_long(argc, argv, "d:Def:F:hilmo:P:qr:st:vV", options, &opt_index)) != -1) {
+ while ((opt = getopt_long(argc, argv, "d:Def:F:hilmo:P:qst:vV", options, &opt_index)) != -1) {
#else
- while ((opt = getopt_long(argc, argv, "d:Def:F:G:hilmo:P:qr:st:vV", options, &opt_index)) != -1) {
+ while ((opt = getopt_long(argc, argv, "d:Def:F:G:hilmo:P:qst:vV", options, &opt_index)) != -1) {
#endif
switch (opt) {
case 'd': /* --default */
@@ -608,13 +552,6 @@
c->data_operational.path = optarg;
break;
- case 'r': /* --request */
- if (ly_set_add(&c->data_request_paths, optarg, 0, NULL)) {
- YLMSG_E("Storing request path failed.\n");
- return -1;
- }
- break;
-
case 'm': /* --merge */
c->data_merge = 1;
break;
@@ -739,12 +676,6 @@
}
}
- if (c->data_type == LYD_VALIDATE_OP_REPLY) {
- if (check_request_paths(c->ctx, &c->data_request_paths, &c->data_inputs)) {
- return -1;
- }
- }
-
return 0;
}
@@ -794,7 +725,7 @@
if (c.data_inputs.size) {
if (process_data(c.ctx, c.data_type, c.data_merge, c.data_out_format, c.out,
c.data_parse_options, c.data_validate_options, c.data_print_options,
- &c.data_operational, &c.data_inputs, &c.data_request_paths, &c.data_requests, NULL)) {
+ &c.data_operational, &c.data_inputs, NULL)) {
goto cleanup;
}
}