Commit f4b1f445 authored by Rusty Russell's avatar Rusty Russell

opt: allow parameter names in arguments.

parent f20e4f23
......@@ -17,14 +17,14 @@ const char *opt_argv0;
/* Returns string after first '-'. */
static const char *first_name(const char *names, unsigned *len)
{
*len = strcspn(names + 1, "/");
*len = strcspn(names + 1, "/= ");
return names + 1;
}
static const char *next_name(const char *names, unsigned *len)
{
names += *len;
if (!names[0])
if (names[0] == ' ' || names[0] == '=' || names[0] == '\0')
return NULL;
return first_name(names + 1, len);
}
......@@ -124,6 +124,9 @@ static void check_opt(const struct opt_table *entry)
assert(*p != '?');
}
}
/* Don't document args unless there are some. */
if (entry->flags == OPT_NOARG)
assert(p[len] != ' ' && p[len] != '=');
}
}
......
......@@ -39,6 +39,10 @@ struct opt_table {
* returned string to form an error message for errlog(), free() the
* string and return false.
*
* Any number of equivalent short or long options can be listed in @names,
* separated by '/'. Short options are a single hyphen followed by a single
* character, long options are two hypens followed by one or more characters.
*
* See Also:
* OPT_WITH_ARG()
*/
......@@ -47,7 +51,7 @@ struct opt_table {
/**
* OPT_WITH_ARG() - macro for initializing long and short option (with arg)
* @names: the names of the option eg. "--foo", "-f" or "--foo/-f/--foobar".
* @names: the option names eg. "--foo=<arg>", "-f" or "-f/--foo <arg>".
* @cb: the callback when the option is found (along with <arg>).
* @show: the callback to print the value in get_usage (or NULL)
* @arg: the argument to hand to @cb and @show
......@@ -63,6 +67,12 @@ struct opt_table {
* argument; unless it uses the entire OPT_SHOW_LEN bytes it should
* nul-terminate that buffer.
*
* Any number of equivalent short or long options can be listed in @names,
* separated by '/'. Short options are a single hyphen followed by a single
* character, long options are two hypens followed by one or more characters.
* A space or equals in @names is ignored for parsing, and only used
* for printing the usage.
*
* If the @cb returns non-NULL, opt_parse() will stop parsing, use the
* returned string to form an error message for errlog(), free() the
* string and return false.
......
......@@ -32,7 +32,7 @@ int main(int argc, char *argv[])
ok1(strstr(output, " Description of b (default: b)\n"));
ok1(strstr(output, "--ddd "));
ok1(strstr(output, " Description of ddd\n"));
ok1(strstr(output, "--eee <arg> "));
ok1(strstr(output, "--eee <filename> "));
ok1(strstr(output, " (default: eee)\n"));
ok1(strstr(output, "long table options:\n"));
ok1(strstr(output, "--ggg/-g "));
......
......@@ -78,7 +78,7 @@ struct opt_table short_table[] = {
struct opt_table long_table[] = {
/* Long opts, different args. */
{ OPT_WITHOUT_ARG("--ddd", test_noarg, "ddd"), "Description of ddd" },
{ OPT_WITH_ARG("--eee", test_arg, show_arg, "eee"), },
{ OPT_WITH_ARG("--eee <filename>", test_arg, show_arg, "eee"), },
OPT_ENDTABLE
};
......
......@@ -78,7 +78,9 @@ char *opt_usage(const char *argv0, const char *extra)
continue;
}
len = sprintf(p, "%s", opt_table[i].names);
if (opt_table[i].flags == OPT_HASARG)
if (opt_table[i].flags == OPT_HASARG
&& !strchr(opt_table[i].names, ' ')
&& !strchr(opt_table[i].names, '='))
len += sprintf(p + len, " <arg>");
if (opt_table[i].desc || opt_table[i].show)
len += sprintf(p + len, "%.*s",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment