From: Tokunori Ikegami Date: Sat, 29 Apr 2023 15:24:56 +0000 (+0900) Subject: util: Add argconfig parse value function X-Git-Tag: v2.5~132 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=21bda57486c79c957d385495612964464d696af3;p=users%2Fsagi%2Fnvme-cli.git util: Add argconfig parse value function Signed-off-by: Tokunori Ikegami --- diff --git a/util/argconfig.c b/util/argconfig.c index 630c3ea5..1c35ba4d 100644 --- a/util/argconfig.c +++ b/util/argconfig.c @@ -50,6 +50,9 @@ 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; @@ -160,13 +163,13 @@ int argconfig_parse_byte(const char *opt, const char *str, unsigned char *val) } static int argconfig_parse_type(struct argconfig_commandline_options *s, struct option *option, - int index) + int index, enum argconfig_types type) { void *value = (void *)(char *)s->default_value; char *endptr; int ret = 0; - switch (s->config_type) { + switch (type) { case CFG_STRING: *((char **)value) = optarg; break; @@ -216,7 +219,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; @@ -228,6 +231,9 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct case CFG_FLAG: *((bool *)value) = true; break; + case CFG_VAL: + ret = argconfig_parse_val(s, option, index); + break; default: break; } @@ -235,6 +241,57 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct return ret; } +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; + + for (v = s->opt_val; v && v->str; v++) { + if (strncasecmp(str, v->str, len > v->len ? len : v->len)) + continue; + switch (v->type) { + case CFG_FLAG: + *(bool *)val = v->val.bool_val; + break; + case CFG_LONG_SUFFIX: + *(uint64_t *)val = v->val.long_suffix; + break; + case CFG_POSITIVE: + *(uint32_t *)val = v->val.positive; + break; + case CFG_INT: + *(int *)val = v->val.int_val; + break; + case CFG_LONG: + *(unsigned long *)val = v->val.long_val; + break; + case CFG_DOUBLE: + *(double *)val = v->val.double_val; + break; + case CFG_BYTE: + *(uint8_t *)val = v->val.byte; + break; + case CFG_SHORT: + *(uint16_t *)val = v->val.short_val; + break; + case CFG_INCREMENT: + *(int *)val = v->val.increment; + break; + case CFG_STRING: + *(char **)val = v->val.string; + break; + default: + break; + } + return 0; + } + + return argconfig_parse_type(s, option, index, s->opt_val->type); +} + bool argconfig_output_format_json(bool set) { static bool output_format_json = false; @@ -330,7 +387,7 @@ 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); + ret = argconfig_parse_type(s, long_opts, option_index, s->config_type); if (ret) break; } diff --git a/util/argconfig.h b/util/argconfig.h index 1a2828ff..fe34f54d 100644 --- a/util/argconfig.h +++ b/util/argconfig.h @@ -39,6 +39,7 @@ #include #include #include +#include enum argconfig_types { CFG_FLAG, @@ -53,6 +54,7 @@ enum argconfig_types { CFG_SHORT, CFG_POSITIVE, CFG_INCREMENT, + CFG_VAL, }; #define OPT_ARGS(n) \ @@ -95,6 +97,66 @@ enum argconfig_types { #define OPT_LIST(l, s, v, d) OPT_STRING(l, s, "LIST", v, d) #define OPT_STR(l, s, v, d) OPT_STRING(l, s, "STRING", v, d) +#define OPT_VAL(l, s, v, d, o) \ + {l, s, "VAL", CFG_VAL, v, required_argument, d, false, o} + +#define OPT_VALS(n) \ + struct argconfig_opt_val n[] + +#define VAL_END() { NULL } + +#define VAL_FLAG(s, l, v) \ + {s, l, CFG_FLAG, .val.flag = v} + +#define VAL_LONG_SUFFIX(s, l, v) \ + {s, l, CFG_LONG_SUFFIX, .val.long_suffix = v} + +#define VAL_UINT(s, l, v) \ + {s, l, CFG_POSITIVE, v} + +#define VAL_INT(s, l, v) \ + {s, l, CFG_INT, .val.int_val = v} + +#define VAL_LONG(s, l, v) \ + {s, l, CFG_LONG, .val.long_val = v} + +#define VAL_DOUBLE(s, l, v) \ + {s, l, CFG_DOUBLE, .val.double_val = v} + +#define VAL_BYTE(s, l, v) \ + {s, l, CFG_BYTE, .val.byte = v} + +#define VAL_SHRT(s, l, v) \ + {s, l, CFG_SHORT, .val.short_val = v} + +#define VAL_INCR(s, l, v) \ + {s, l, CFG_INCREMENT, .val.increment = v} + +#define VAL_STRING(s, l, m, v) \ + {s, l, CFG_STRING, .val.string = v} + +union argconfig_val { + char *string; + size_t size; + int int_val; + int bool_val; + uint8_t byte; + uint16_t short_val; + uint32_t positive; + int increment; + unsigned long long_val; + uint64_t long_suffix; + double double_val; + bool flag; +}; + +struct argconfig_opt_val { + const char *str; + const int len; + enum argconfig_types type; + union argconfig_val val; +}; + struct argconfig_commandline_options { const char *option; const char short_option; @@ -104,6 +166,7 @@ struct argconfig_commandline_options { int argument_type; const char *help; bool seen; + struct argconfig_opt_val *opt_val; }; void argconfig_append_usage(const char *str);