]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
util: Add argconfig parse value function
authorTokunori Ikegami <ikegami.t@gmail.com>
Sat, 29 Apr 2023 15:24:56 +0000 (00:24 +0900)
committerDaniel Wagner <wagi@monom.org>
Tue, 2 May 2023 09:35:10 +0000 (11:35 +0200)
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
util/argconfig.c
util/argconfig.h

index 630c3ea5192a9e57ae8351c6832729c929f7f80b..1c35ba4d842ec57cbb7589df6de64e7dc1779872 100644 (file)
@@ -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;
        }
index 1a2828ff47e31667774c42079d2681510103ebbe..fe34f54d4ebfc0d0c1a2b9ce21859e180c312dfe 100644 (file)
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 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);