Cleanup pass.

This commit is contained in:
Rob Landley 2024-03-01 21:25:17 -06:00
parent 481ec7b80e
commit 71f05097a5

View File

@ -3,7 +3,6 @@
* Copyright 2019 The Android Open Source Project * Copyright 2019 The Android Open Source Project
* *
* See https://man7.org/linux/man-pages/man1/getopt.1.html * See https://man7.org/linux/man-pages/man1/getopt.1.html
* No standard
USE_GETOPT(NEWTOY(getopt, "^a(alternative)n:(name)o:(options)l*(long)(longoptions)Tu", TOYFLAG_USR|TOYFLAG_BIN)) USE_GETOPT(NEWTOY(getopt, "^a(alternative)n:(name)o:(options)l*(long)(longoptions)Tu", TOYFLAG_USR|TOYFLAG_BIN))
@ -11,16 +10,23 @@ config GETOPT
bool "getopt" bool "getopt"
default n default n
help help
usage: getopt [OPTIONS] [--] ARG... usage: getopt [-aTu] [-lo OPTIONS] [-n NAME] [OPTIONS] ARG...
Parse command-line options for use in shell scripts. Outputs command line with recognized OPTIONS character arguments moved to
front, then "--", then non-option arguments. Returns 1 if unknown options.
OPTIONS followed by : take an argument, or :: for optional arguments (which
must be attached, ala -xblah or --long=blah).
-a Allow long options starting with a single -. -a Allow long options starting with a single -
-l OPTS Specify long options. -l Long OPTIONS (repeated or comma separated)
-n NAME Command name for error messages. -n Command NAME for error messages
-o OPTS Specify short options. -o Short OPTIONS (instead of using first argument)
-T Test whether this is a modern getopt. -T Test whether this is a modern getopt
-u Output options unquoted. -u Unquoted output (default if no other options set)
Example:
$ getopt -l long:,arg:: abc command --long -b there --arg
--long '-b' --arg '' -- 'command' 'there'
*/ */
#define FOR_getopt #define FOR_getopt
@ -55,17 +61,16 @@ static char *parse_long_opt(void *data, char *str, int len)
if (!len || lopt->has_arg>2) return str; if (!len || lopt->has_arg>2) return str;
lopt->name = xstrndup(str, len); lopt->name = xstrndup(str, len);
(*lopt_ptr)++; (*lopt_ptr)++;
return 0; return 0;
} }
void getopt_main(void) void getopt_main(void)
{ {
int argc = toys.optc+1; int argc = toys.optc+1, i = 0, j = 0, ch;
char **argv = xzalloc(sizeof(char *)*(argc+1)); char **argv = xzalloc(sizeof(char *)*(argc+1));
struct option *lopts = xzalloc(sizeof(struct option)*argc), *lopt = lopts; struct option *lopts = xzalloc(sizeof(struct option)*argc), *lopt = lopts;
int i = 0, j = 0, ch;
if (FLAG(T)) { if (FLAG(T)) {
toys.exitval = 4; toys.exitval = 4;
@ -73,25 +78,24 @@ void getopt_main(void)
} }
comma_args(TT.l, &lopt, "bad -l", parse_long_opt); comma_args(TT.l, &lopt, "bad -l", parse_long_opt);
argv[j++] = TT.n ? TT.n : "getopt"; argv[j++] = TT.n ? : "getopt";
// Legacy mode: don't quote output and take the first argument as OPTSTR.
if (!FLAG(o)) { if (!FLAG(o)) {
toys.optflags |= FLAG_u;
TT.o = toys.optargs[i++]; TT.o = toys.optargs[i++];
if (!TT.o) error_exit("no OPTSTR"); argc--;
--argc;
} }
if (!TT.o) error_exit("no OPTSTR");
if (!toys.optflags) toys.optflags = FLAG_u;
while (i<toys.optc) argv[j++] = toys.optargs[i++]; while (i<toys.optc) argv[j++] = toys.optargs[i++];
// BSD getopts don't honor argv[0] (for -n), so handle errors ourselves. // BSD getopt doesn't honor argv[0] (for -n), so handle errors ourselves.
opterr = 0; opterr = 0;
optind = 1; optind = 1;
while ((ch = (FLAG(a) ? getopt_long_only : getopt_long)(argc, argv, TT.o, while ((ch = (FLAG(a) ? getopt_long_only : getopt_long)(argc, argv, TT.o,
lopts, &i)) != -1) { lopts, &i)) != -1) {
if (ch == '?') { if (ch == '?') {
fprintf(stderr, "%s: invalid option '%c'\n", argv[0], optopt); fprintf(stderr, "%s: invalid option '%c'\n", *argv, optopt);
toys.exitval = 1; toys.exitval = 1;
} else if (!ch) { } else if (!ch) {
xprintf(" --%s", lopts[i].name); xprintf(" --%s", lopts[i].name);