return prefix_filename_except_for_dash(prefix, file);
}
+static int do_get_int_value(const void *value, size_t precision, intmax_t *ret)
+{
+ switch (precision) {
+ case sizeof(int8_t):
+ *ret = *(int8_t *)value;
+ return 0;
+ case sizeof(int16_t):
+ *ret = *(int16_t *)value;
+ return 0;
+ case sizeof(int32_t):
+ *ret = *(int32_t *)value;
+ return 0;
+ case sizeof(int64_t):
+ *ret = *(int64_t *)value;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
const struct option *opt,
enum opt_parsed flags,
}
struct parse_opt_cmdmode_list {
- int value, *value_ptr;
+ intmax_t value;
+ void *value_ptr;
+ size_t precision;
const struct option *opt;
const char *arg;
enum opt_parsed flags;
for (; opts->type != OPTION_END; opts++) {
struct parse_opt_cmdmode_list *elem = ctx->cmdmode_list;
- int *value_ptr = opts->value;
+ void *value_ptr = opts->value;
if (!(opts->flags & PARSE_OPT_CMDMODE) || !value_ptr)
continue;
CALLOC_ARRAY(elem, 1);
elem->value_ptr = value_ptr;
- elem->value = *value_ptr;
+ elem->precision = opts->precision;
+ if (do_get_int_value(value_ptr, opts->precision, &elem->value))
+ optbug(opts, "has invalid precision");
elem->next = ctx->cmdmode_list;
ctx->cmdmode_list = elem;
}
+ BUG_if_bug("invalid 'struct option'");
}
static char *optnamearg(const struct option *opt, const char *arg,
char *opt_name, *other_opt_name;
for (; elem; elem = elem->next) {
- if (*elem->value_ptr == elem->value)
+ intmax_t new_value;
+
+ if (do_get_int_value(elem->value_ptr, elem->precision,
+ &new_value))
+ BUG("impossible: invalid precision");
+
+ if (new_value == elem->value)
continue;
if (elem->opt &&
elem->opt = opt;
elem->arg = arg;
elem->flags = flags;
- elem->value = *elem->value_ptr;
+ elem->value = new_value;
}
if (result || !elem)
OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
OPT_CMDMODE(0, "mode1", &integer, "set integer to 1 (cmdmode option)", 1),
OPT_CMDMODE(0, "mode2", &integer, "set integer to 2 (cmdmode option)", 2),
- OPT_CALLBACK_F(0, "mode34", &integer, "(3|4)",
- "set integer to 3 or 4 (cmdmode option)",
- PARSE_OPT_CMDMODE, mode34_callback),
+ {
+ .type = OPTION_CALLBACK,
+ .long_name = "mode34",
+ .value = &integer,
+ .precision = sizeof(integer),
+ .argh = "(3|4)",
+ .help = "set integer to 3 or 4 (cmdmode option)",
+ .flags = PARSE_OPT_CMDMODE,
+ .callback = mode34_callback,
+ },
OPT_CALLBACK('L', "length", &integer, "str",
"get length of <str>", length_callback),
OPT_FILENAME('F', "file", &file, "set file to <file>"),