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;
}
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;
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;
case CFG_FLAG:
*((bool *)value) = true;
break;
+ case CFG_VAL:
+ ret = argconfig_parse_val(s, option, index);
+ break;
default:
break;
}
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;
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;
}
#include <stdarg.h>
#include <stdio.h>
#include <stdbool.h>
+#include <stdint.h>
enum argconfig_types {
CFG_FLAG,
CFG_SHORT,
CFG_POSITIVE,
CFG_INCREMENT,
+ CFG_VAL,
};
#define OPT_ARGS(n) \
#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;
int argument_type;
const char *help;
bool seen;
+ struct argconfig_opt_val *opt_val;
};
void argconfig_append_usage(const char *str);