diff options
Diffstat (limited to 'tools/lint/yl_opt.c')
-rw-r--r-- | tools/lint/yl_opt.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/tools/lint/yl_opt.c b/tools/lint/yl_opt.c new file mode 100644 index 0000000..7cd855f --- /dev/null +++ b/tools/lint/yl_opt.c @@ -0,0 +1,344 @@ +/** + * @file yl_opt.c + * @author Adam Piecek <piecek@cesnet.cz> + * @brief Settings options for the libyang context. + * + * Copyright (c) 2020 - 2023 CESNET, z.s.p.o. + * + * This source code is licensed under BSD 3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + */ + +#define _GNU_SOURCE + +#include <assert.h> +#include <errno.h> +#include <getopt.h> +#include <strings.h> + +#include "in.h" /* ly_in_free */ + +#include "common.h" +#include "yl_opt.h" +#include "yl_schema_features.h" + +struct cmdline_file * +fill_cmdline_file(struct ly_set *set, struct ly_in *in, const char *path, LYD_FORMAT format) +{ + struct cmdline_file *rec; + + rec = malloc(sizeof *rec); + if (!rec) { + YLMSG_E("Allocating memory for data file information failed."); + return NULL; + } + rec->in = in; + rec->path = path; + rec->format = format; + + if (set && ly_set_add(set, rec, 1, NULL)) { + free(rec); + YLMSG_E("Storing data file information failed."); + return NULL; + } + + return rec; +} + +void +free_cmdline_file_items(struct cmdline_file *rec) +{ + if (rec && rec->in) { + ly_in_free(rec->in, 1); + } +} + +void +free_cmdline_file(void *cmdline_file) +{ + struct cmdline_file *rec = (struct cmdline_file *)cmdline_file; + + if (rec) { + free_cmdline_file_items(rec); + free(rec); + } +} + +void +yl_opt_erase(struct yl_opt *yo) +{ + ly_bool interactive; + + interactive = yo->interactive; + + /* data */ + ly_set_erase(&yo->data_inputs, free_cmdline_file); + ly_in_free(yo->data_operational.in, 1); + ly_set_erase(&yo->data_xpath, NULL); + + /* schema */ + ly_set_erase(&yo->schema_features, yl_schema_features_free); + ly_set_erase(&yo->schema_modules, NULL); + + /* context */ + free(yo->searchpaths); + + /* --reply-rpc */ + ly_in_free(yo->reply_rpc.in, 1); + + ly_out_free(yo->out, NULL, yo->out_stdout ? 0 : 1); + + free_cmdline(yo->argv); + + *yo = (const struct yl_opt) { + 0 + }; + yo->interactive = interactive; +} + +int +yl_opt_update_schema_out_format(const char *arg, struct yl_opt *yo) +{ + if (!strcasecmp(arg, "yang")) { + yo->schema_out_format = LYS_OUT_YANG; + yo->data_out_format = 0; + } else if (!strcasecmp(arg, "yin")) { + yo->schema_out_format = LYS_OUT_YIN; + yo->data_out_format = 0; + } else if (!strcasecmp(arg, "info")) { + yo->schema_out_format = LYS_OUT_YANG_COMPILED; + yo->data_out_format = 0; + } else if (!strcasecmp(arg, "tree")) { + yo->schema_out_format = LYS_OUT_TREE; + yo->data_out_format = 0; + } else { + return 1; + } + + return 0; +} + +int +yl_opt_update_data_out_format(const char *arg, struct yl_opt *yo) +{ + if (!strcasecmp(arg, "xml")) { + yo->schema_out_format = 0; + yo->data_out_format = LYD_XML; + } else if (!strcasecmp(arg, "json")) { + yo->schema_out_format = 0; + yo->data_out_format = LYD_JSON; + } else if (!strcasecmp(arg, "lyb")) { + yo->schema_out_format = 0; + yo->data_out_format = LYD_LYB; + } else { + return 1; + } + + return 0; +} + +static int +yl_opt_update_other_out_format(const char *arg, struct yl_opt *yo) +{ + if (!strcasecmp(arg, "feature-param")) { + yo->feature_param_format = 1; + } else { + return 1; + } + + return 0; +} + +int +yl_opt_update_out_format(const char *arg, struct yl_opt *yo) +{ + if (!yl_opt_update_schema_out_format(arg, yo)) { + return 0; + } + if (!yl_opt_update_data_out_format(arg, yo)) { + return 0; + } + if (!yl_opt_update_other_out_format(arg, yo)) { + return 0; + } + + YLMSG_E("Unknown output format %s.", arg); + return 1; +} + +int +yl_opt_update_data_type(const char *arg, struct yl_opt *yo) +{ + if (!strcasecmp(arg, "config")) { + yo->data_parse_options |= LYD_PARSE_NO_STATE; + yo->data_validate_options |= LYD_VALIDATE_NO_STATE; + } else if (!strcasecmp(arg, "get")) { + yo->data_parse_options |= LYD_PARSE_ONLY; + } else if (!strcasecmp(arg, "getconfig") || !strcasecmp(arg, "get-config") || !strcasecmp(arg, "edit")) { + yo->data_parse_options |= LYD_PARSE_ONLY | LYD_PARSE_NO_STATE; + } else if (!strcasecmp(arg, "rpc") || !strcasecmp(arg, "action")) { + yo->data_type = LYD_TYPE_RPC_YANG; + } else if (!strcasecmp(arg, "nc-rpc")) { + yo->data_type = LYD_TYPE_RPC_NETCONF; + } else if (!strcasecmp(arg, "reply") || !strcasecmp(arg, "rpcreply")) { + yo->data_type = LYD_TYPE_REPLY_YANG; + } else if (!strcasecmp(arg, "nc-reply")) { + yo->data_type = LYD_TYPE_REPLY_NETCONF; + } else if (!strcasecmp(arg, "notif") || !strcasecmp(arg, "notification")) { + yo->data_type = LYD_TYPE_NOTIF_YANG; + } else if (!strcasecmp(arg, "nc-notif")) { + yo->data_type = LYD_TYPE_NOTIF_NETCONF; + } else if (!strcasecmp(arg, "data")) { + /* default option */ + } else { + return 1; + } + + return 0; +} + +int +yo_opt_update_data_default(const char *arg, struct yl_opt *yo) +{ + if (!strcasecmp(arg, "all")) { + yo->data_print_options = (yo->data_print_options & ~LYD_PRINT_WD_MASK) | LYD_PRINT_WD_ALL; + } else if (!strcasecmp(arg, "all-tagged")) { + yo->data_print_options = (yo->data_print_options & ~LYD_PRINT_WD_MASK) | LYD_PRINT_WD_ALL_TAG; + } else if (!strcasecmp(arg, "trim")) { + yo->data_print_options = (yo->data_print_options & ~LYD_PRINT_WD_MASK) | LYD_PRINT_WD_TRIM; + } else if (!strcasecmp(arg, "implicit-tagged")) { + yo->data_print_options = (yo->data_print_options & ~LYD_PRINT_WD_MASK) | LYD_PRINT_WD_IMPL_TAG; + } else { + return 1; + } + + return 0; +} + +int +yo_opt_update_data_in_format(const char *arg, struct yl_opt *yo) +{ + if (!strcasecmp(arg, "xml")) { + yo->data_in_format = LYD_XML; + } else if (!strcasecmp(arg, "json")) { + yo->data_in_format = LYD_JSON; + } else if (!strcasecmp(arg, "lyb")) { + yo->data_in_format = LYD_LYB; + } else { + return 1; + } + + return 0; +} + +void +yo_opt_update_make_implemented(struct yl_opt *yo) +{ + if (yo->ctx_options & LY_CTX_REF_IMPLEMENTED) { + yo->ctx_options &= ~LY_CTX_REF_IMPLEMENTED; + yo->ctx_options |= LY_CTX_ALL_IMPLEMENTED; + } else { + yo->ctx_options |= LY_CTX_REF_IMPLEMENTED; + } +} + +void +yo_opt_update_disable_searchdir(struct yl_opt *yo) +{ + if (yo->ctx_options & LY_CTX_DISABLE_SEARCHDIR_CWD) { + yo->ctx_options &= ~LY_CTX_DISABLE_SEARCHDIR_CWD; + yo->ctx_options |= LY_CTX_DISABLE_SEARCHDIRS; + } else { + yo->ctx_options |= LY_CTX_DISABLE_SEARCHDIR_CWD; + } +} + +void +free_cmdline(char *argv[]) +{ + if (argv) { + free(argv[0]); + free(argv); + } +} + +int +parse_cmdline(const char *cmdline, int *argc_p, char **argv_p[]) +{ + int count; + char **vector; + char *ptr; + char qmark = 0; + + assert(cmdline); + assert(argc_p); + assert(argv_p); + + /* init */ + optind = 0; /* reinitialize getopt() */ + count = 1; + vector = malloc((count + 1) * sizeof *vector); + vector[0] = strdup(cmdline); + + /* command name */ + strtok(vector[0], " "); + + /* arguments */ + while ((ptr = strtok(NULL, " "))) { + size_t len; + void *r; + + len = strlen(ptr); + + if (qmark) { + /* still in quotated text */ + /* remove NULL termination of the previous token since it is not a token, + * but a part of the quotation string */ + ptr[-1] = ' '; + + if ((ptr[len - 1] == qmark) && (ptr[len - 2] != '\\')) { + /* end of quotation */ + qmark = 0; + /* shorten the argument by the terminating quotation mark */ + ptr[len - 1] = '\0'; + } + continue; + } + + /* another token in cmdline */ + ++count; + r = realloc(vector, (count + 1) * sizeof *vector); + if (!r) { + YLMSG_E("Memory allocation failed (%s:%d, %s).", __FILE__, __LINE__, strerror(errno)); + free(vector); + return -1; + } + vector = r; + vector[count - 1] = ptr; + + if ((ptr[0] == '"') || (ptr[0] == '\'')) { + /* remember the quotation mark to identify end of quotation */ + qmark = ptr[0]; + + /* move the remembered argument after the quotation mark */ + ++vector[count - 1]; + + /* check if the quotation is terminated within this token */ + if ((ptr[len - 1] == qmark) && (ptr[len - 2] != '\\')) { + /* end of quotation */ + qmark = 0; + /* shorten the argument by the terminating quotation mark */ + ptr[len - 1] = '\0'; + } + } + } + vector[count] = NULL; + + *argc_p = count; + *argv_p = vector; + + return 0; +} |