Browse Source

opt: allow parameter names in arguments.

Rusty Russell 15 years ago
parent
commit
f4b1f445a7
5 changed files with 21 additions and 6 deletions
  1. 5 2
      ccan/opt/opt.c
  2. 11 1
      ccan/opt/opt.h
  3. 1 1
      ccan/opt/test/run-usage.c
  4. 1 1
      ccan/opt/test/utils.c
  5. 3 1
      ccan/opt/usage.c

+ 5 - 2
ccan/opt/opt.c

@@ -17,14 +17,14 @@ const char *opt_argv0;
 /* Returns string after first '-'. */
 /* Returns string after first '-'. */
 static const char *first_name(const char *names, unsigned *len)
 static const char *first_name(const char *names, unsigned *len)
 {
 {
-	*len = strcspn(names + 1, "/");
+	*len = strcspn(names + 1, "/= ");
 	return names + 1;
 	return names + 1;
 }
 }
 
 
 static const char *next_name(const char *names, unsigned *len)
 static const char *next_name(const char *names, unsigned *len)
 {
 {
 	names += *len;
 	names += *len;
-	if (!names[0])
+	if (names[0] == ' ' || names[0] == '=' || names[0] == '\0')
 		return NULL;
 		return NULL;
 	return first_name(names + 1, len);
 	return first_name(names + 1, len);
 }
 }
@@ -124,6 +124,9 @@ static void check_opt(const struct opt_table *entry)
 				assert(*p != '?');
 				assert(*p != '?');
 			}
 			}
 		}
 		}
+		/* Don't document args unless there are some. */
+		if (entry->flags == OPT_NOARG)
+			assert(p[len] != ' ' && p[len] != '=');
 	}
 	}
 }
 }
 
 

+ 11 - 1
ccan/opt/opt.h

@@ -39,6 +39,10 @@ struct opt_table {
  * returned string to form an error message for errlog(), free() the
  * returned string to form an error message for errlog(), free() the
  * string and return false.
  * 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:
  * See Also:
  *	OPT_WITH_ARG()
  *	OPT_WITH_ARG()
  */
  */
@@ -47,7 +51,7 @@ struct opt_table {
 
 
 /**
 /**
  * OPT_WITH_ARG() - macro for initializing long and short option (with arg)
  * 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>).
  * @cb: the callback when the option is found (along with <arg>).
  * @show: the callback to print the value in get_usage (or NULL)
  * @show: the callback to print the value in get_usage (or NULL)
  * @arg: the argument to hand to @cb and @show
  * @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
  * argument; unless it uses the entire OPT_SHOW_LEN bytes it should
  * nul-terminate that buffer.
  * 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
  * If the @cb returns non-NULL, opt_parse() will stop parsing, use the
  * returned string to form an error message for errlog(), free() the
  * returned string to form an error message for errlog(), free() the
  * string and return false.
  * string and return false.

+ 1 - 1
ccan/opt/test/run-usage.c

@@ -32,7 +32,7 @@ int main(int argc, char *argv[])
 	ok1(strstr(output, " Description of b (default: b)\n"));
 	ok1(strstr(output, " Description of b (default: b)\n"));
 	ok1(strstr(output, "--ddd "));
 	ok1(strstr(output, "--ddd "));
 	ok1(strstr(output, " Description of ddd\n"));
 	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, " (default: eee)\n"));
 	ok1(strstr(output, "long table options:\n"));
 	ok1(strstr(output, "long table options:\n"));
 	ok1(strstr(output, "--ggg/-g "));
 	ok1(strstr(output, "--ggg/-g "));

+ 1 - 1
ccan/opt/test/utils.c

@@ -78,7 +78,7 @@ struct opt_table short_table[] = {
 struct opt_table long_table[] = {
 struct opt_table long_table[] = {
 	/* Long opts, different args. */
 	/* Long opts, different args. */
 	{ OPT_WITHOUT_ARG("--ddd", test_noarg, "ddd"), "Description of ddd" },
 	{ 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
 	OPT_ENDTABLE
 };
 };
 
 

+ 3 - 1
ccan/opt/usage.c

@@ -78,7 +78,9 @@ char *opt_usage(const char *argv0, const char *extra)
 			continue;
 			continue;
 		}
 		}
 		len = sprintf(p, "%s", opt_table[i].names);
 		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>");
 			len += sprintf(p + len, " <arg>");
 		if (opt_table[i].desc || opt_table[i].show)
 		if (opt_table[i].desc || opt_table[i].show)
 			len += sprintf(p + len, "%.*s",
 			len += sprintf(p + len, "%.*s",