diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-06-30 22:38:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-06-30 22:38:48 +0000 |
commit | 01c4d3d32c5044d3d17055c2d94d40fee9d130e1 (patch) | |
tree | 2c213cd5436bff644fa7023b94674a9c12d2e1af /util/argconfig.c | |
parent | Adding upstream version 2.4+really2.4. (diff) | |
download | nvme-cli-01c4d3d32c5044d3d17055c2d94d40fee9d130e1.tar.xz nvme-cli-01c4d3d32c5044d3d17055c2d94d40fee9d130e1.zip |
Adding upstream version 2.5.upstream/2.5
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'util/argconfig.c')
-rw-r--r-- | util/argconfig.c | 264 |
1 files changed, 110 insertions, 154 deletions
diff --git a/util/argconfig.c b/util/argconfig.c index 3eb885f..effeea2 100644 --- a/util/argconfig.c +++ b/util/argconfig.c @@ -42,18 +42,11 @@ #include <string.h> #include <stdbool.h> -#if __has_attribute(__fallthrough__) -#define fallthrough __attribute__((__fallthrough__)) -#else -#define fallthrough do {} while (0) -#endif - -static argconfig_help_func *help_funcs[MAX_HELP_FUNC] = { NULL }; - -static char END_DEFAULT[] = "__end_default__"; - static const char *append_usage_str = ""; +static int argconfig_parse_val(struct argconfig_commandline_options *s, struct option *option, + int index); + void argconfig_append_usage(const char *str) { append_usage_str = str; @@ -168,11 +161,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct { void *value = (void *)(char *)s->default_value; char *endptr; - const char *fopts = NULL; - FILE *f; int ret = 0; - char **opts = ((char **)value); - int remaining_space = CFG_MAX_SUBOPTS - 2; switch (s->config_type) { case CFG_STRING: @@ -190,6 +179,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct break; case CFG_BOOL: { int tmp = strtol(optarg, &endptr, 0); + if (errno || tmp < 0 || tmp > 1 || optarg == endptr) ret = argconfig_error("0 or 1", option[index].name, optarg); else @@ -201,6 +191,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct break; case CFG_SHORT: { unsigned long tmp = strtoul(optarg, &endptr, 0); + if (errno || tmp >= 1 << 16 || optarg == endptr) ret = argconfig_error("short", option[index].name, optarg); else @@ -209,6 +200,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct } case CFG_POSITIVE: { uint32_t tmp = strtoul(optarg, &endptr, 0); + if (errno || optarg == endptr) ret = argconfig_error("word", option[index].name, optarg); else @@ -224,7 +216,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct ret = argconfig_error("long integer", option[index].name, optarg); break; case CFG_LONG_SUFFIX: - ret = suffix_binary_parse(optarg, &endptr, (uint64_t*)value); + ret = suffix_binary_parse(optarg, &endptr, (uint64_t *)value); if (ret) argconfig_error("long suffixed integer", option[index].name, optarg); break; @@ -233,48 +225,6 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct if (errno || optarg == endptr) ret = argconfig_error("float", option[index].name, optarg); break; - case CFG_SUBOPTS: - *opts = END_DEFAULT; - opts += 2; - ret = argconfig_parse_subopt_string(optarg, opts, remaining_space); - if (ret) { - if (ret == 2) - fprintf(stderr, "Error Parsing Sub-Options: Too many options!\n"); - else - fprintf(stderr, "Error Parsing Sub-Options\n"); - ret = -EINVAL; - } - break; - case CFG_FILE_A: - fopts = "a"; - fallthrough; - case CFG_FILE_R: - if (!fopts) - fopts = "r"; - fallthrough; - case CFG_FILE_W: - if (!fopts) - fopts = "w"; - fallthrough; - case CFG_FILE_AP: - if (!fopts) - fopts = "a+"; - fallthrough; - case CFG_FILE_RP: - if (!fopts) - fopts = "r+"; - fallthrough; - case CFG_FILE_WP: - if (!fopts) - fopts = "w+"; - f = fopen(optarg, fopts); - if (!f) { - fprintf(stderr, "Unable to open %s file: %s\n", s->option, optarg); - ret = -EINVAL; - } else { - *((FILE **)value) = f; - } - break; case CFG_FLAG: *((bool *)value) = true; break; @@ -285,9 +235,87 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct return ret; } +static int argconfig_get_val_len(struct argconfig_opt_val *opt_val, const char *str) +{ + struct argconfig_opt_val *v; + int len; + int match; + + for (len = 1; len <= strlen(str); len++) { + match = 0; + for (v = opt_val; v && v->str; v++) { + if (!strncasecmp(str, v->str, len)) + match++; + } + if (match == 1) + break; + } + + return len; +} + +static int argconfig_set_opt_val(enum argconfig_types type, union argconfig_val *opt_val, void *val) +{ + switch (type) { + case CFG_FLAG: + *(bool *)val = opt_val->bool_val; + break; + case CFG_LONG_SUFFIX: + *(uint64_t *)val = opt_val->long_suffix; + break; + case CFG_POSITIVE: + *(uint32_t *)val = opt_val->positive; + break; + case CFG_INT: + *(int *)val = opt_val->int_val; + break; + case CFG_LONG: + *(unsigned long *)val = opt_val->long_val; + break; + case CFG_DOUBLE: + *(double *)val = opt_val->double_val; + break; + case CFG_BYTE: + *(uint8_t *)val = opt_val->byte; + break; + case CFG_SHORT: + *(uint16_t *)val = opt_val->short_val; + break; + case CFG_INCREMENT: + *(int *)val = opt_val->increment; + break; + case CFG_STRING: + *(char **)val = opt_val->string; + break; + default: + break; + } + + return 0; +} + +static int argconfig_parse_val(struct argconfig_commandline_options *s, struct option *option, + int index) +{ + const char *str = optarg; + void *val = s->default_value; + int len = strlen(optarg); + struct argconfig_opt_val *v; + int val_len; + + for (v = s->opt_val; v && v->str; v++) { + val_len = argconfig_get_val_len(s->opt_val, v->str); + if (strncasecmp(str, v->str, len > val_len ? len : val_len)) + continue; + return argconfig_set_opt_val(v->type, &v->val, val); + } + + return argconfig_parse_type(s, option, index); +} + bool argconfig_output_format_json(bool set) { - static bool output_format_json = false; + static bool output_format_json; if (set) output_format_json = true; @@ -295,6 +323,18 @@ bool argconfig_output_format_json(bool set) return output_format_json; } +static bool argconfig_check_output_format_json(struct argconfig_commandline_options *s) +{ + for (; s && s->option; s++) { + if (strcmp(s->option, "output-format") || s->config_type != CFG_STRING) + continue; + if (!strcmp(*(char **)s->default_value, "json")) + return true; + } + + return false; +} + int argconfig_parse(int argc, char *argv[], const char *program_desc, struct argconfig_commandline_options *options) { @@ -368,94 +408,24 @@ int argconfig_parse(int argc, char *argv[], const char *program_desc, if (!s->default_value) continue; - ret = argconfig_parse_type(s, long_opts,option_index); + if (s->opt_val) + ret = argconfig_parse_val(s, long_opts, option_index); + else + ret = argconfig_parse_type(s, long_opts, option_index); if (ret) break; } + + if (argconfig_check_output_format_json(options)) + argconfig_output_format_json(true); + out: free(short_opts); free(long_opts); return ret; } -int argconfig_parse_subopt_string(char *string, char **options, - size_t max_options) -{ - char **o = options; - char *tmp; - size_t toklen; - - if (!string || !strlen(string)) { - *(o++) = NULL; - *(o++) = NULL; - return 0; - } - - tmp = calloc(strlen(string) + 2, 1); - if (!tmp) - return 1; - strcpy(tmp, string); - - toklen = strcspn(tmp, "="); - - if (!toklen) { - free(tmp); - return 1; - } - - *(o++) = tmp; - tmp[toklen] = 0; - tmp += toklen + 1; - - while (1) { - if (*tmp == '"' || *tmp == '\'' || *tmp == '[' || *tmp == '(' || - *tmp == '{') { - - tmp++; - toklen = strcspn(tmp, "\"'])}"); - - if (!toklen) - return 1; - - *(o++) = tmp; - tmp[toklen] = 0; - tmp += toklen + 1; - - toklen = strcspn(tmp, ";:,"); - tmp[toklen] = 0; - tmp += toklen + 1; - } else { - toklen = strcspn(tmp, ";:,"); - - if (!toklen) - return 1; - - *(o++) = tmp; - tmp[toklen] = 0; - tmp += toklen + 1; - } - - toklen = strcspn(tmp, "="); - - if (!toklen) - break; - - *(o++) = tmp; - tmp[toklen] = 0; - tmp += toklen + 1; - - if ((o - options) > (max_options - 2)) - return 2; - } - - *(o++) = NULL; - *(o++) = NULL; - - return 0; -} - -int argconfig_parse_comma_sep_array(char *string, int *val, - unsigned max_length) +int argconfig_parse_comma_sep_array(char *string, int *val, unsigned int max_length) { int ret = 0; unsigned long v; @@ -501,7 +471,7 @@ int argconfig_parse_comma_sep_array(char *string, int *val, } int argconfig_parse_comma_sep_array_short(char *string, unsigned short *val, - unsigned max_length) + unsigned int max_length) { int ret = 0; unsigned long v; @@ -545,9 +515,8 @@ int argconfig_parse_comma_sep_array_short(char *string, unsigned short *val, } } -int argconfig_parse_comma_sep_array_long(char *string, - unsigned long long *val, - unsigned max_length) +int argconfig_parse_comma_sep_array_long(char *string, unsigned long long *val, + unsigned int max_length) { int ret = 0; char *tmp; @@ -580,19 +549,6 @@ int argconfig_parse_comma_sep_array_long(char *string, } } -void argconfig_register_help_func(argconfig_help_func * f) -{ - int i; - for (i = 0; i < MAX_HELP_FUNC; i++) { - if (help_funcs[i] == NULL) { - help_funcs[i] = f; - if (i < MAX_HELP_FUNC - 1) - help_funcs[i + 1] = NULL; - break; - } - } -} - bool argconfig_parse_seen(struct argconfig_commandline_options *s, const char *option) { |