Provide a ccan variant OPT_WITH_CBARG that assigns the arguments passed as a string and then performs the callback function on the string.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
diff --git a/ccan/opt/opt.c b/ccan/opt/opt.c
index 9bc34d9..8ff00ea 100644
--- a/ccan/opt/opt.c
+++ b/ccan/opt/opt.c
@@ -116,7 +116,7 @@ static void check_opt(const struct opt_table *entry)
const char *p;
unsigned len;
- if (entry->type != OPT_HASARG && entry->type != OPT_NOARG)
+ if (entry->type != OPT_HASARG && entry->type != OPT_NOARG && entry->type != OPT_PROCESSARG)
errx(1, "Option %s: unknown entry type %u",
entry->names, entry->type);
diff --git a/ccan/opt/opt.h b/ccan/opt/opt.h
index 6fe2fb0..90ff680 100644
--- a/ccan/opt/opt.h
+++ b/ccan/opt/opt.h
@@ -68,6 +68,13 @@ struct opt_table;
{ (name), OPT_CB_ARG((cb), (show), (arg)), { (arg) }, (desc) }
/**
+ * OPT_WITH_CBARG() - variant of OPT_WITH_ARG which assigns arguments to arg
+ * and then performs the callback function on the args as well.
+ */
+#define OPT_WITH_CBARG(name, cb, show, arg, desc) \
+ { (name), OPT_CB_WITHARG((cb), (show), (arg)), { (arg) }, (desc) }
+
+/**
* OPT_SUBTABLE() - macro for including another table inside a table.
* @table: the table to include in this table.
* @desc: description of this subtable (for opt_usage()) or NULL.
@@ -296,8 +303,9 @@ char *opt_usage_and_exit(const char *extra);
enum opt_type {
OPT_NOARG = 1, /* -f|--foo */
OPT_HASARG = 2, /* -f arg|--foo=arg|--foo arg */
- OPT_SUBTABLE = 4, /* Actually, longopt points to a subtable... */
- OPT_END = 8, /* End of the table. */
+ OPT_PROCESSARG = 4,
+ OPT_SUBTABLE = 8, /* Actually, longopt points to a subtable... */
+ OPT_END = 16, /* End of the table. */
};
struct opt_table {
@@ -334,6 +342,16 @@ struct opt_table {
typesafe_cb_cast(void (*)(char buf[], const void *), \
void (*)(char buf[], const typeof(*(arg))*), (show))
+#define OPT_CB_WITHARG(cb, show, arg) \
+ OPT_PROCESSARG, NULL, \
+ typesafe_cb_cast3(char *(*)(const char *,void *), \
+ char *(*)(const char *, typeof(*(arg))*), \
+ char *(*)(const char *, const typeof(*(arg))*), \
+ char *(*)(const char *, const void *), \
+ (cb)), \
+ typesafe_cb_cast(void (*)(char buf[], const void *), \
+ void (*)(char buf[], const typeof(*(arg))*), (show))
+
/* Non-typesafe register function. */
void _opt_register(const char *names, enum opt_type type,
char *(*cb)(void *arg),
diff --git a/ccan/opt/parse.c b/ccan/opt/parse.c
index 7b7c02c..18af157 100644
--- a/ccan/opt/parse.c
+++ b/ccan/opt/parse.c
@@ -107,6 +107,8 @@ int parse_one(int *argc, char *argv[], unsigned *offset,
if (!optarg)
return parse_err(errlog, argv[0], o, len,
"requires an argument");
+ if (opt_table[i].type == OPT_PROCESSARG)
+ opt_set_charp(optarg, opt_table[i].u.arg);
problem = opt_table[i].cb_arg(optarg, opt_table[i].u.arg);
}