opt: allow parameter names in arguments.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 5 Oct 2010 07:01:36 +0000 (17:31 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 5 Oct 2010 07:01:36 +0000 (17:31 +1030)
ccan/opt/opt.c
ccan/opt/opt.h
ccan/opt/test/run-usage.c
ccan/opt/test/utils.c
ccan/opt/usage.c

index a5180706c45e28e52394411ad5ff271f10cdeb2c..e7ebc3dd0550e2181b13c41438ddeb9e8f244dff 100644 (file)
@@ -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] != '=');
        }
 }
 
index 253d03c4098691988a8edf4ef4352d3b72931be5..65008091a0861ade804d06e8fc302bcf74a6aa51 100644 (file)
@@ -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.
index 821403444df7da6e207260ed54b3049265cfed25..943fcf6da38e6efb5e3097af46f997a3d228a486 100644 (file)
@@ -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 "));
index 6870af741b188034a5a5337ae3de66c880189d71..bafb67438247a6d381747731231fefaa3d9b6b4b 100644 (file)
@@ -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
 };
 
index cbe1231a484fedf27e826a3485a1a333dd7314dd..25678d662d7feee7120b3c21559bf10461ea41de 100644 (file)
@@ -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",