aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/ar.c11
-rw-r--r--archival/bzip2.c8
-rw-r--r--archival/dpkg_deb.c5
-rw-r--r--archival/lzop.c2
-rw-r--r--archival/tar.c25
-rw-r--r--console-tools/loadfont.c6
-rw-r--r--console-tools/setconsole.c3
-rw-r--r--coreutils/cat.c8
-rw-r--r--coreutils/chmod.c3
-rw-r--r--coreutils/chown.c7
-rw-r--r--coreutils/comm.c3
-rw-r--r--coreutils/cp.c18
-rw-r--r--coreutils/cut.c9
-rw-r--r--coreutils/date.c14
-rw-r--r--coreutils/df.c15
-rw-r--r--coreutils/dos2unix.c3
-rw-r--r--coreutils/du.c14
-rw-r--r--coreutils/expand.c7
-rw-r--r--coreutils/id.c9
-rw-r--r--coreutils/install.c13
-rw-r--r--coreutils/link.c3
-rw-r--r--coreutils/ln.c3
-rw-r--r--coreutils/ls.c60
-rw-r--r--coreutils/md5_sha1_sum.c7
-rw-r--r--coreutils/mktemp.c3
-rw-r--r--coreutils/mv.c6
-rw-r--r--coreutils/readlink.c3
-rw-r--r--coreutils/rm.c3
-rw-r--r--coreutils/shuf.c7
-rw-r--r--coreutils/sort.c10
-rw-r--r--coreutils/split.c7
-rw-r--r--coreutils/stat.c8
-rw-r--r--coreutils/sync.c3
-rw-r--r--coreutils/tail.c8
-rw-r--r--coreutils/tr.c4
-rw-r--r--coreutils/truncate.c3
-rw-r--r--coreutils/unlink.c3
-rw-r--r--coreutils/uudecode.c6
-rw-r--r--coreutils/uuencode.c3
-rw-r--r--coreutils/who.c3
-rw-r--r--debianutils/run_parts.c5
-rw-r--r--debianutils/start_stop_daemon.c20
-rw-r--r--debianutils/which.c3
-rw-r--r--e2fsprogs/tune2fs.c3
-rw-r--r--editors/cmp.c10
-rw-r--r--editors/diff.c4
-rw-r--r--editors/sed.c6
-rw-r--r--findutils/grep.c11
-rw-r--r--include/libbb.h3
-rw-r--r--libbb/getopt32.c74
-rw-r--r--libbb/parse_config.c5
-rw-r--r--libbb/vfork_daemon_rexec.c3
-rw-r--r--loginutils/addgroup.c7
-rw-r--r--loginutils/adduser.c13
-rw-r--r--loginutils/chpasswd.c6
-rw-r--r--loginutils/cryptpw.c7
-rw-r--r--loginutils/getty.c5
-rw-r--r--loginutils/vlock.c3
-rw-r--r--mailutils/popmaildir.c6
-rw-r--r--mailutils/reformime.c6
-rw-r--r--mailutils/sendmail.c12
-rw-r--r--miscutils/adjtimex.c7
-rw-r--r--miscutils/crond.c14
-rw-r--r--miscutils/crontab.c5
-rw-r--r--miscutils/flash_eraseall.c3
-rw-r--r--miscutils/flashcp.c3
-rw-r--r--miscutils/i2c_tools.c25
-rw-r--r--miscutils/makedevs.c3
-rw-r--r--miscutils/man.c3
-rw-r--r--miscutils/microcom.c5
-rw-r--r--miscutils/nandwrite.c9
-rw-r--r--miscutils/setserial.c3
-rw-r--r--miscutils/time.c5
-rw-r--r--miscutils/ubi_tools.c9
-rw-r--r--miscutils/watchdog.c5
-rw-r--r--modutils/modinfo.c3
-rw-r--r--modutils/modprobe-small.c3
-rw-r--r--modutils/modprobe.c8
-rw-r--r--networking/arping.c6
-rw-r--r--networking/ether-wake.c3
-rw-r--r--networking/ftpd.c17
-rw-r--r--networking/ftpgetput.c7
-rw-r--r--networking/httpd.c10
-rw-r--r--networking/ipcalc.c7
-rw-r--r--networking/nc_bloaty.c14
-rw-r--r--networking/ntpd.c9
-rw-r--r--networking/ping.c12
-rw-r--r--networking/pscan.c7
-rw-r--r--networking/slattach.c5
-rw-r--r--networking/tcpudp.c7
-rw-r--r--networking/telnetd.c10
-rw-r--r--networking/tftp.c15
-rw-r--r--networking/traceroute.c6
-rw-r--r--networking/tunctl.c18
-rw-r--r--networking/udhcp/d6_dhcpc.c7
-rw-r--r--networking/udhcp/dhcpc.c10
-rw-r--r--networking/udhcp/dhcpd.c7
-rw-r--r--networking/udhcp/dumpleases.c8
-rw-r--r--networking/wget.c8
-rw-r--r--networking/whois.c3
-rw-r--r--networking/zcip.c5
-rw-r--r--procps/fuser.c3
-rw-r--r--procps/iostat.c3
-rw-r--r--procps/pmap.c3
-rw-r--r--procps/ps.c8
-rw-r--r--procps/pstree.c3
-rw-r--r--procps/pwdx.c3
-rw-r--r--procps/watch.c6
-rw-r--r--runit/chpst.c7
-rw-r--r--runit/runsvdir.c3
-rw-r--r--runit/sv.c5
-rw-r--r--runit/svlogd.c7
-rw-r--r--selinux/chcon.c11
-rw-r--r--selinux/matchpathcon.c10
-rw-r--r--selinux/runcon.c9
-rw-r--r--selinux/sestatus.c3
-rw-r--r--selinux/setfiles.c20
-rw-r--r--sysklogd/syslogd.c3
-rw-r--r--util-linux/acpid.c8
-rw-r--r--util-linux/blkdiscard.c3
-rw-r--r--util-linux/chrt.c3
-rw-r--r--util-linux/eject.c5
-rw-r--r--util-linux/fallocate.c3
-rw-r--r--util-linux/fdformat.c3
-rw-r--r--util-linux/flock.c3
-rw-r--r--util-linux/fsck_minix.c3
-rw-r--r--util-linux/fsfreeze.c5
-rw-r--r--util-linux/fstrim.c5
-rw-r--r--util-linux/hexdump_xxd.c5
-rw-r--r--util-linux/hwclock.c7
-rw-r--r--util-linux/losetup.c3
-rw-r--r--util-linux/mkfs_reiser.c3
-rw-r--r--util-linux/mkfs_vfat.c5
-rw-r--r--util-linux/mkswap.c3
-rw-r--r--util-linux/mount.c12
-rw-r--r--util-linux/mountpoint.c3
-rw-r--r--util-linux/rdate.c3
-rw-r--r--util-linux/rtcwake.c6
-rw-r--r--util-linux/script.c6
-rw-r--r--util-linux/setsid.c4
-rw-r--r--util-linux/switch_root.c5
-rw-r--r--util-linux/taskset.c3
-rw-r--r--util-linux/unshare.c21
143 files changed, 597 insertions, 502 deletions
diff --git a/archival/ar.c b/archival/ar.c
index 46c10aad4..027cd6b5a 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -243,10 +243,13 @@ int ar_main(int argc UNUSED_PARAM, char **argv)
243 /* prepend '-' to the first argument if required */ 243 /* prepend '-' to the first argument if required */
244 if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') 244 if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0')
245 argv[1] = xasprintf("-%s", argv[1]); 245 argv[1] = xasprintf("-%s", argv[1]);
246 /* -1: at least one param is reqd */ 246 opt = getopt32(argv, "^"
247 /* one of p,t,x[,r] is required */ 247 "voc""ptx"IF_FEATURE_AR_CREATE("r")
248 opt_complementary = "-1:p:t:x"IF_FEATURE_AR_CREATE(":r"); 248 "\0"
249 opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r")); 249 /* -1: at least one arg is reqd */
250 /* one of p,t,x[,r] is required */
251 "-1:p:t:x"IF_FEATURE_AR_CREATE(":r")
252 );
250 argv += optind; 253 argv += optind;
251 254
252 t = opt / FIRST_CMD; 255 t = opt / FIRST_CMD;
diff --git a/archival/bzip2.c b/archival/bzip2.c
index 0b9c508df..d578eb7ad 100644
--- a/archival/bzip2.c
+++ b/archival/bzip2.c
@@ -195,9 +195,11 @@ int bzip2_main(int argc UNUSED_PARAM, char **argv)
195 * --best alias for -9 195 * --best alias for -9
196 */ 196 */
197 197
198 opt_complementary = "s2"; /* -s means -2 (compatibility) */ 198 opt = getopt32(argv, "^"
199 /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ 199 /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */
200 opt = getopt32(argv, "cfkv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs"); 200 "cfkv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs"
201 "\0" "s2" /* -s means -2 (compatibility) */
202 );
201#if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */ 203#if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */
202 if (opt & 0x30) // -d and/or -t 204 if (opt & 0x30) // -d and/or -t
203 return bunzip2_main(argc, argv); 205 return bunzip2_main(argc, argv);
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c
index 029bc4af1..f6bf9eb04 100644
--- a/archival/dpkg_deb.c
+++ b/archival/dpkg_deb.c
@@ -80,8 +80,9 @@ int dpkg_deb_main(int argc UNUSED_PARAM, char **argv)
80#endif 80#endif
81 81
82 /* Must have 1 or 2 args */ 82 /* Must have 1 or 2 args */
83 opt_complementary = "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; 83 opt = getopt32(argv, "^" "cefXx"
84 opt = getopt32(argv, "cefXx"); 84 "\0" "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"
85 );
85 argv += optind; 86 argv += optind;
86 //argc -= optind; 87 //argc -= optind;
87 88
diff --git a/archival/lzop.c b/archival/lzop.c
index df18ff170..1bf954f4f 100644
--- a/archival/lzop.c
+++ b/archival/lzop.c
@@ -1138,7 +1138,7 @@ int lzop_main(int argc UNUSED_PARAM, char **argv)
1138 /* -U is "anti -k", invert bit for bbunpack(): */ 1138 /* -U is "anti -k", invert bit for bbunpack(): */
1139 option_mask32 ^= OPT_KEEP; 1139 option_mask32 ^= OPT_KEEP;
1140 /* -k disables -U (if any): */ 1140 /* -k disables -U (if any): */
1141 /* opt_complementary = "k-U"; - nope, only handles -Uk, not -kU */ 1141 /* opt_complementary "k-U"? - nope, only handles -Uk, not -kU */
1142 if (option_mask32 & OPT_k) 1142 if (option_mask32 & OPT_k)
1143 option_mask32 |= OPT_KEEP; 1143 option_mask32 |= OPT_KEEP;
1144 1144
diff --git a/archival/tar.c b/archival/tar.c
index 44ab246c0..73c14ca81 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -973,18 +973,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
973 /* Prepend '-' to the first argument if required */ 973 /* Prepend '-' to the first argument if required */
974 if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') 974 if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0')
975 argv[1] = xasprintf("-%s", argv[1]); 975 argv[1] = xasprintf("-%s", argv[1]);
976 opt_complementary =
977 "tt:vv:" // count -t,-v
978#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
979 "\xff::" // --exclude=PATTERN is a list
980#endif
981 IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd
982 IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
983 IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive
984#if ENABLE_FEATURE_TAR_LONG_OPTIONS
985 ":\xf9+" // --strip-components=NUM
986#endif
987 ;
988#if ENABLE_DESKTOP 976#if ENABLE_DESKTOP
989 /* Lie to buildroot when it starts asking stupid questions. */ 977 /* Lie to buildroot when it starts asking stupid questions. */
990 if (argv[1] && strcmp(argv[1], "--version") == 0) { 978 if (argv[1] && strcmp(argv[1], "--version") == 0) {
@@ -1021,7 +1009,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1021 } 1009 }
1022 } 1010 }
1023#endif 1011#endif
1024 opt = GETOPT32(argv, 1012 opt = GETOPT32(argv, "^"
1025 "txC:f:Oopvk" 1013 "txC:f:Oopvk"
1026 IF_FEATURE_TAR_CREATE( "ch" ) 1014 IF_FEATURE_TAR_CREATE( "ch" )
1027 IF_FEATURE_SEAMLESS_BZ2( "j" ) 1015 IF_FEATURE_SEAMLESS_BZ2( "j" )
@@ -1032,6 +1020,17 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1032 IF_FEATURE_SEAMLESS_Z( "Z" ) 1020 IF_FEATURE_SEAMLESS_Z( "Z" )
1033 IF_FEATURE_TAR_NOPRESERVE_TIME("m") 1021 IF_FEATURE_TAR_NOPRESERVE_TIME("m")
1034 IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components 1022 IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components
1023 "\0"
1024 "tt:vv:" // count -t,-v
1025#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
1026 "\xff::" // --exclude=PATTERN is a list
1027#endif
1028 IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd
1029 IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
1030 IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive
1031#if ENABLE_FEATURE_TAR_LONG_OPTIONS
1032 ":\xf9+" // --strip-components=NUM
1033#endif
1035 LONGOPTS 1034 LONGOPTS
1036 , &base_dir // -C dir 1035 , &base_dir // -C dir
1037 , &tar_filename // -f filename 1036 , &tar_filename // -f filename
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c
index 623d98175..81d0c3db4 100644
--- a/console-tools/loadfont.c
+++ b/console-tools/loadfont.c
@@ -348,8 +348,7 @@ int loadfont_main(int argc UNUSED_PARAM, char **argv)
348 unsigned char *buffer; 348 unsigned char *buffer;
349 349
350 // no arguments allowed! 350 // no arguments allowed!
351 opt_complementary = "=0"; 351 getopt32(argv, "^" "" "\0" "=0");
352 getopt32(argv, "");
353 352
354 /* 353 /*
355 * We used to look at the length of the input file 354 * We used to look at the length of the input file
@@ -437,8 +436,7 @@ int setfont_main(int argc UNUSED_PARAM, char **argv)
437 char *mapfilename; 436 char *mapfilename;
438 const char *tty_name = CURRENT_TTY; 437 const char *tty_name = CURRENT_TTY;
439 438
440 opt_complementary = "=1"; 439 opts = getopt32(argv, "^" "m:C:" "\0" "=1", &mapfilename, &tty_name);
441 opts = getopt32(argv, "m:C:", &mapfilename, &tty_name);
442 argv += optind; 440 argv += optind;
443 441
444 fd = xopen_nonblocking(tty_name); 442 fd = xopen_nonblocking(tty_name);
diff --git a/console-tools/setconsole.c b/console-tools/setconsole.c
index 8f4b7b7a6..bad2b76e4 100644
--- a/console-tools/setconsole.c
+++ b/console-tools/setconsole.c
@@ -47,8 +47,7 @@ int setconsole_main(int argc UNUSED_PARAM, char **argv)
47 int reset; 47 int reset;
48 48
49 /* at most one non-option argument */ 49 /* at most one non-option argument */
50 opt_complementary = "?1"; 50 reset = getopt32(argv, "^" "r" "\0" "?1");
51 reset = getopt32(argv, "r");
52 51
53 argv += 1 + reset; 52 argv += 1 + reset;
54 if (*argv) { 53 if (*argv) {
diff --git a/coreutils/cat.c b/coreutils/cat.c
index 390254512..7e35fa5ee 100644
--- a/coreutils/cat.c
+++ b/coreutils/cat.c
@@ -170,9 +170,11 @@ int cat_main(int argc UNUSED_PARAM, char **argv)
170{ 170{
171 unsigned opts; 171 unsigned opts;
172 172
173 IF_FEATURE_CATV(opt_complementary = "Aetv"; /* -A == -vet */) 173 opts = getopt32(argv, IF_FEATURE_CATV("^")
174 /* -u is ignored ("unbuffered") */ 174 /* -u is ignored ("unbuffered") */
175 opts = getopt32(argv, IF_FEATURE_CATV("etvA") IF_FEATURE_CATN("nb") "u"); 175 IF_FEATURE_CATV("etvA")IF_FEATURE_CATN("nb")"u"
176 IF_FEATURE_CATV("\0" "Aetv" /* -A == -vet */)
177 );
176 argv += optind; 178 argv += optind;
177 179
178 /* Read from stdin if there's nothing else to do. */ 180 /* Read from stdin if there's nothing else to do. */
diff --git a/coreutils/chmod.c b/coreutils/chmod.c
index 2174334d1..88989bf67 100644
--- a/coreutils/chmod.c
+++ b/coreutils/chmod.c
@@ -123,8 +123,7 @@ int chmod_main(int argc UNUSED_PARAM, char **argv)
123 } 123 }
124 124
125 /* Parse options */ 125 /* Parse options */
126 opt_complementary = "-2"; 126 getopt32(argv, "^" OPT_STR "\0" "-2");
127 getopt32(argv, ("-"OPT_STR) + 1); /* Reuse string */
128 argv += optind; 127 argv += optind;
129 128
130 /* Restore option-like mode if needed */ 129 /* Restore option-like mode if needed */
diff --git a/coreutils/chown.c b/coreutils/chown.c
index 0c77529ec..985d18d6f 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -55,7 +55,7 @@
55/* This is a NOEXEC applet. Be very careful! */ 55/* This is a NOEXEC applet. Be very careful! */
56 56
57 57
58#define OPT_STR ("Rh" IF_DESKTOP("vcfLHP")) 58#define OPT_STR "Rh" IF_DESKTOP("vcfLHP")
59#define BIT_RECURSE 1 59#define BIT_RECURSE 1
60#define OPT_RECURSE (opt & 1) 60#define OPT_RECURSE (opt & 1)
61#define OPT_NODEREF (opt & 2) 61#define OPT_NODEREF (opt & 2)
@@ -127,11 +127,10 @@ int chown_main(int argc UNUSED_PARAM, char **argv)
127 int opt, flags; 127 int opt, flags;
128 struct param_t param; 128 struct param_t param;
129 129
130 opt_complementary = "-2";
131#if ENABLE_FEATURE_CHOWN_LONG_OPTIONS 130#if ENABLE_FEATURE_CHOWN_LONG_OPTIONS
132 opt = getopt32long(argv, OPT_STR, chown_longopts); 131 opt = getopt32long(argv, "^" OPT_STR "\0" "=2", chown_longopts);
133#else 132#else
134 opt = getopt32(argv, OPT_STR); 133 opt = getopt32(argv, "^" OPT_STR "\0" "=2");
135#endif 134#endif
136 argv += optind; 135 argv += optind;
137 136
diff --git a/coreutils/comm.c b/coreutils/comm.c
index 5be11468c..4bee77677 100644
--- a/coreutils/comm.c
+++ b/coreutils/comm.c
@@ -62,8 +62,7 @@ int comm_main(int argc UNUSED_PARAM, char **argv)
62 int i; 62 int i;
63 int order; 63 int order;
64 64
65 opt_complementary = "=2"; 65 getopt32(argv, "^" "123" "\0" "=2");
66 getopt32(argv, "123");
67 argv += optind; 66 argv += optind;
68 67
69 for (i = 0; i < 2; ++i) { 68 for (i = 0; i < 2; ++i) {
diff --git a/coreutils/cp.c b/coreutils/cp.c
index fe408950a..5b34c27e7 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -73,15 +73,17 @@ int cp_main(int argc, char **argv)
73#endif 73#endif
74 }; 74 };
75 75
76 // Need at least two arguments
77 // Soft- and hardlinking doesn't mix
78 // -P and -d are the same (-P is POSIX, -d is GNU)
79 // -r and -R are the same
80 // -R (and therefore -r) turns on -d (coreutils does this)
81 // -a = -pdR
82 opt_complementary = "-2:l--s:s--l:Pd:rRd:Rd:apdR";
83#if ENABLE_FEATURE_CP_LONG_OPTIONS 76#if ENABLE_FEATURE_CP_LONG_OPTIONS
84 flags = getopt32long(argv, FILEUTILS_CP_OPTSTR, 77 flags = getopt32long(argv, "^"
78 FILEUTILS_CP_OPTSTR
79 "\0"
80 // Need at least two arguments
81 // Soft- and hardlinking doesn't mix
82 // -P and -d are the same (-P is POSIX, -d is GNU)
83 // -r and -R are the same
84 // -R (and therefore -r) turns on -d (coreutils does this)
85 // -a = -pdR
86 "-2:l--s:s--l:Pd:rRd:Rd:apdR",
85 "archive\0" No_argument "a" 87 "archive\0" No_argument "a"
86 "force\0" No_argument "f" 88 "force\0" No_argument "f"
87 "interactive\0" No_argument "i" 89 "interactive\0" No_argument "i"
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 6578ce8ce..cdd90ab44 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -42,7 +42,7 @@
42 42
43 43
44/* option vars */ 44/* option vars */
45static const char optstring[] ALIGN1 = "b:c:f:d:sn"; 45#define OPT_STR "b:c:f:d:sn"
46#define CUT_OPT_BYTE_FLGS (1 << 0) 46#define CUT_OPT_BYTE_FLGS (1 << 0)
47#define CUT_OPT_CHAR_FLGS (1 << 1) 47#define CUT_OPT_CHAR_FLGS (1 << 1)
48#define CUT_OPT_FIELDS_FLGS (1 << 2) 48#define CUT_OPT_FIELDS_FLGS (1 << 2)
@@ -201,8 +201,11 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
201 char *sopt, *ltok; 201 char *sopt, *ltok;
202 unsigned opt; 202 unsigned opt;
203 203
204 opt_complementary = "b--bcf:c--bcf:f--bcf"; 204 opt = getopt32(argv, "^"
205 opt = getopt32(argv, optstring, &sopt, &sopt, &sopt, &ltok); 205 OPT_STR
206 "\0" "b--bcf:c--bcf:f--bcf",
207 &sopt, &sopt, &sopt, &ltok
208 );
206// argc -= optind; 209// argc -= optind;
207 argv += optind; 210 argv += optind;
208 if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) 211 if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
diff --git a/coreutils/date.c b/coreutils/date.c
index 33f210434..5b15ce778 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -192,12 +192,16 @@ int date_main(int argc UNUSED_PARAM, char **argv)
192 char *filename; 192 char *filename;
193 char *isofmt_arg = NULL; 193 char *isofmt_arg = NULL;
194 194
195 opt_complementary = "d--s:s--d" 195 opt = getopt32long(argv, "^"
196 IF_FEATURE_DATE_ISOFMT(":R--I:I--R"); 196 "Rs:ud:r:"
197 opt = getopt32long(argv, "Rs:ud:r:" 197 IF_FEATURE_DATE_ISOFMT("I::D:")
198 IF_FEATURE_DATE_ISOFMT("I::D:"), date_longopts, 198 "\0"
199 "d--s:s--d"
200 IF_FEATURE_DATE_ISOFMT(":R--I:I--R"),
201 date_longopts,
199 &date_str, &date_str, &filename 202 &date_str, &date_str, &filename
200 IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)); 203 IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)
204 );
201 argv += optind; 205 argv += optind;
202 maybe_set_utc(opt); 206 maybe_set_utc(opt);
203 207
diff --git a/coreutils/df.c b/coreutils/df.c
index 4d6534bc2..121da970b 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -115,15 +115,18 @@ int df_main(int argc UNUSED_PARAM, char **argv)
115 115
116 init_unicode(); 116 init_unicode();
117 117
118 opt = getopt32(argv, "^"
119 "kPT"
120 IF_FEATURE_DF_FANCY("aiB:")
121 IF_FEATURE_HUMAN_READABLE("hm")
122 "\0"
118#if ENABLE_FEATURE_HUMAN_READABLE && ENABLE_FEATURE_DF_FANCY 123#if ENABLE_FEATURE_HUMAN_READABLE && ENABLE_FEATURE_DF_FANCY
119 opt_complementary = "k-mB:m-Bk:B-km"; 124 "k-mB:m-Bk:B-km"
120#elif ENABLE_FEATURE_HUMAN_READABLE 125#elif ENABLE_FEATURE_HUMAN_READABLE
121 opt_complementary = "k-m:m-k"; 126 "k-m:m-k"
122#endif 127#endif
123 opt = getopt32(argv, "kPT" 128 IF_FEATURE_DF_FANCY(, &chp)
124 IF_FEATURE_DF_FANCY("aiB:") 129 );
125 IF_FEATURE_HUMAN_READABLE("hm")
126 IF_FEATURE_DF_FANCY(, &chp));
127 if (opt & OPT_MEGA) 130 if (opt & OPT_MEGA)
128 df_disp_hr = 1024*1024; 131 df_disp_hr = 1024*1024;
129 132
diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c
index a3d008051..9f098e41e 100644
--- a/coreutils/dos2unix.c
+++ b/coreutils/dos2unix.c
@@ -120,8 +120,7 @@ int dos2unix_main(int argc UNUSED_PARAM, char **argv)
120 } 120 }
121 121
122 /* -u convert to unix, -d convert to dos */ 122 /* -u convert to unix, -d convert to dos */
123 opt_complementary = "u--d:d--u"; /* mutually exclusive */ 123 o = getopt32(argv, "^" "du" "\0" "u--d:d--u"); /* mutually exclusive */
124 o = getopt32(argv, "du");
125 124
126 /* Do the conversion requested by an argument else do the default 125 /* Do the conversion requested by an argument else do the default
127 * conversion depending on our name. */ 126 * conversion depending on our name. */
diff --git a/coreutils/du.c b/coreutils/du.c
index 947c46e74..d5ce46cf2 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -242,8 +242,11 @@ int du_main(int argc UNUSED_PARAM, char **argv)
242 * ignore -a. This is consistent with -s being equivalent to -d 0. 242 * ignore -a. This is consistent with -s being equivalent to -d 0.
243 */ 243 */
244#if ENABLE_FEATURE_HUMAN_READABLE 244#if ENABLE_FEATURE_HUMAN_READABLE
245 opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s"; 245 opt = getopt32(argv, "^"
246 opt = getopt32(argv, "aHkLsx" "d:+" "lc" "hm", &G.max_print_depth); 246 "aHkLsxd:+lchm"
247 "\0" "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s",
248 &G.max_print_depth
249 );
247 argv += optind; 250 argv += optind;
248 if (opt & OPT_h_for_humans) { 251 if (opt & OPT_h_for_humans) {
249 G.disp_unit = 0; 252 G.disp_unit = 0;
@@ -255,8 +258,11 @@ int du_main(int argc UNUSED_PARAM, char **argv)
255 G.disp_unit = 1024; 258 G.disp_unit = 1024;
256 } 259 }
257#else 260#else
258 opt_complementary = "H-L:L-H:s-d:d-s"; 261 opt = getopt32(argv, "^"
259 opt = getopt32(argv, "aHkLsx" "d:+" "lc", &G.max_print_depth); 262 "aHkLsxd:+lc"
263 "\0" "H-L:L-H:s-d:d-s",
264 &G.max_print_depth
265 );
260 argv += optind; 266 argv += optind;
261#if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K 267#if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
262 if (opt & OPT_k_kbytes) { 268 if (opt & OPT_k_kbytes) {
diff --git a/coreutils/expand.c b/coreutils/expand.c
index fa3ff18f4..91084b80b 100644
--- a/coreutils/expand.c
+++ b/coreutils/expand.c
@@ -174,9 +174,10 @@ int expand_main(int argc UNUSED_PARAM, char **argv)
174 , &opt_t 174 , &opt_t
175 ); 175 );
176 } else { 176 } else {
177 /* -t NUM sets also -a */ 177 opt = getopt32long(argv, "^"
178 opt_complementary = "ta"; 178 "ft:a"
179 opt = getopt32long(argv, "ft:a", 179 "\0"
180 "ta" /* -t NUM sets -a */,
180 "first-only\0" No_argument "i" 181 "first-only\0" No_argument "i"
181 "tabs\0" Required_argument "t" 182 "tabs\0" Required_argument "t"
182 "all\0" No_argument "a" 183 "all\0" No_argument "a"
diff --git a/coreutils/id.c b/coreutils/id.c
index 6043bca61..5a7fb9aaf 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -170,9 +170,12 @@ int id_main(int argc UNUSED_PARAM, char **argv)
170 } else { 170 } else {
171 /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/ 171 /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/
172 /* Don't allow more than one username */ 172 /* Don't allow more than one username */
173 opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" 173 opt = getopt32(argv, "^"
174 IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); 174 "rnugG" IF_SELINUX("Z")
175 opt = getopt32(argv, "rnugG" IF_SELINUX("Z")); 175 "\0"
176 "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG"
177 IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G")
178 );
176 } 179 }
177 180
178 username = argv[optind]; 181 username = argv[optind];
diff --git a/coreutils/install.c b/coreutils/install.c
index c01750f81..2e4dc257f 100644
--- a/coreutils/install.c
+++ b/coreutils/install.c
@@ -140,13 +140,16 @@ int install_main(int argc, char **argv)
140#endif 140#endif
141 }; 141 };
142 142
143 opt_complementary = "t--d:d--t:s--d:d--s" IF_FEATURE_INSTALL_LONG_OPTIONS(IF_SELINUX(":Z--\xff:\xff--Z"));
144 /* -c exists for backwards compatibility, it's needed */ 143 /* -c exists for backwards compatibility, it's needed */
145 /* -b is ignored ("make a backup of each existing destination file") */ 144 /* -b is ignored ("make a backup of each existing destination file") */
146 opts = GETOPT32(argv, "cvb" "Ddpsg:m:o:t:" IF_SELINUX("Z:"), 145 opts = GETOPT32(argv, "^"
147 LONGOPTS 146 "cvb" "Ddpsg:m:o:t:" IF_SELINUX("Z:")
148 &gid_str, &mode_str, &uid_str, &last 147 "\0"
149 IF_SELINUX(, &scontext) 148 "t--d:d--t:s--d:d--s"
149 IF_FEATURE_INSTALL_LONG_OPTIONS(IF_SELINUX(":Z--\xff:\xff--Z")),
150 LONGOPTS
151 &gid_str, &mode_str, &uid_str, &last
152 IF_SELINUX(, &scontext)
150 ); 153 );
151 argc -= optind; 154 argc -= optind;
152 argv += optind; 155 argv += optind;
diff --git a/coreutils/link.c b/coreutils/link.c
index 6e20dafe3..81808b778 100644
--- a/coreutils/link.c
+++ b/coreutils/link.c
@@ -27,8 +27,7 @@
27int link_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 27int link_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
28int link_main(int argc UNUSED_PARAM, char **argv) 28int link_main(int argc UNUSED_PARAM, char **argv)
29{ 29{
30 opt_complementary = "=2"; /* exactly 2 params */ 30 getopt32(argv, "^" "" "\0" "=2");
31 getopt32(argv, "");
32 argv += optind; 31 argv += optind;
33 if (link(argv[0], argv[1]) != 0) { 32 if (link(argv[0], argv[1]) != 0) {
34 /* shared message */ 33 /* shared message */
diff --git a/coreutils/ln.c b/coreutils/ln.c
index fed96af42..2dda5dae9 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -62,8 +62,7 @@ int ln_main(int argc, char **argv)
62 struct stat statbuf; 62 struct stat statbuf;
63 int (*link_func)(const char *, const char *); 63 int (*link_func)(const char *, const char *);
64 64
65 opt_complementary = "-1"; /* min one arg */ 65 opts = getopt32(argv, "^" "sfnbS:vT" "\0" "-1", &suffix);
66 opts = getopt32(argv, "sfnbS:vT", &suffix);
67 66
68 last = argv[argc - 1]; 67 last = argv[argc - 1];
69 argv += optind; 68 argv += optind;
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 0834cdc63..af5e6cb51 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -206,18 +206,18 @@ SPLIT_SUBDIR = 2,
206/* -SXvhTw GNU options, busybox optionally supports */ 206/* -SXvhTw GNU options, busybox optionally supports */
207/* -T WIDTH Ignored (we don't use tabs on output) */ 207/* -T WIDTH Ignored (we don't use tabs on output) */
208/* -Z SELinux mandated option, busybox optionally supports */ 208/* -Z SELinux mandated option, busybox optionally supports */
209static const char ls_options[] ALIGN1 = 209#define ls_options \
210 "Cadi1lgnsxAk" /* 12 opts, total 12 */ 210 "Cadi1lgnsxAk" /* 12 opts, total 12 */ \
211 IF_FEATURE_LS_FILETYPES("Fp") /* 2, 14 */ 211 IF_FEATURE_LS_FILETYPES("Fp") /* 2, 14 */ \
212 IF_FEATURE_LS_RECURSIVE("R") /* 1, 15 */ 212 IF_FEATURE_LS_RECURSIVE("R") /* 1, 15 */ \
213 IF_SELINUX("Z") /* 1, 16 */ 213 IF_SELINUX("Z") /* 1, 16 */ \
214 "Q" /* 1, 17 */ 214 "Q" /* 1, 17 */ \
215 IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 20 */ 215 IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 20 */ \
216 IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 24 */ 216 IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 24 */ \
217 IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ 217 IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ \
218 IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ 218 IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ \
219 IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */ 219 IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */
220; 220
221enum { 221enum {
222 OPT_C = (1 << 0), 222 OPT_C = (1 << 0),
223 OPT_a = (1 << 1), 223 OPT_a = (1 << 1),
@@ -1093,24 +1093,26 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1093#endif 1093#endif
1094 1094
1095 /* process options */ 1095 /* process options */
1096 opt_complementary = 1096 opt = getopt32long(argv, "^"
1097 /* -n and -g imply -l */ 1097 ls_options
1098 "nl:gl" 1098 "\0"
1099 /* --full-time implies -l */ 1099 /* -n and -g imply -l */
1100 IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS(":\xff""l")) 1100 "nl:gl"
1101 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: 1101 /* --full-time implies -l */
1102 * in some pairs of opts, only last one takes effect: 1102 IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS(":\xff""l"))
1103 */ 1103 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html:
1104 IF_FEATURE_LS_TIMESTAMPS(IF_FEATURE_LS_SORTFILES(":t-S:S-t")) /* time/size */ 1104 * in some pairs of opts, only last one takes effect:
1105 // ":m-l:l-m" - we don't have -m 1105 */
1106 IF_FEATURE_LS_FOLLOWLINKS(":H-L:L-H") 1106 IF_FEATURE_LS_TIMESTAMPS(IF_FEATURE_LS_SORTFILES(":t-S:S-t")) /* time/size */
1107 ":C-xl:x-Cl:l-xC" /* bycols/bylines/long */ 1107 // ":m-l:l-m" - we don't have -m
1108 ":C-1:1-C" /* bycols/oneline */ 1108 IF_FEATURE_LS_FOLLOWLINKS(":H-L:L-H")
1109 ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */ 1109 ":C-xl:x-Cl:l-xC" /* bycols/bylines/long */
1110 IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ 1110 ":C-1:1-C" /* bycols/oneline */
1111 /* -w NUM: */ 1111 ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */
1112 IF_FEATURE_LS_WIDTH(":w+"); 1112 IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */
1113 opt = getopt32long(argv, ls_options, ls_longopts 1113 /* -w NUM: */
1114 IF_FEATURE_LS_WIDTH(":w+")
1115 , ls_longopts
1114 IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width) 1116 IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width)
1115 IF_FEATURE_LS_COLOR(, &color_opt) 1117 IF_FEATURE_LS_COLOR(, &color_opt)
1116 ); 1118 );
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index bcccdd64f..89d6cec0b 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -258,15 +258,14 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
258#endif 258#endif
259 259
260 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) { 260 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) {
261 /* -s and -w require -c */
262 opt_complementary = "s?c:w?c";
263 /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ 261 /* -b "binary", -t "text" are ignored (shaNNNsum compat) */
262 /* -s and -w require -c */
264#if ENABLE_SHA3SUM 263#if ENABLE_SHA3SUM
265 if (applet_name[3] == HASH_SHA3) 264 if (applet_name[3] == HASH_SHA3)
266 flags = getopt32(argv, "scwbta:+", &sha3_width); 265 flags = getopt32(argv, "^" "scwbta:+" "\0" "s?c:w?c", &sha3_width);
267 else 266 else
268#endif 267#endif
269 flags = getopt32(argv, "scwbt"); 268 flags = getopt32(argv, "^" "scwbt" "\0" "s?c:w?c");
270 } else { 269 } else {
271#if ENABLE_SHA3SUM 270#if ENABLE_SHA3SUM
272 if (applet_name[3] == HASH_SHA3) 271 if (applet_name[3] == HASH_SHA3)
diff --git a/coreutils/mktemp.c b/coreutils/mktemp.c
index 944eb0e06..d4ff883fa 100644
--- a/coreutils/mktemp.c
+++ b/coreutils/mktemp.c
@@ -80,8 +80,7 @@ int mktemp_main(int argc UNUSED_PARAM, char **argv)
80 if (!path || path[0] == '\0') 80 if (!path || path[0] == '\0')
81 path = "/tmp"; 81 path = "/tmp";
82 82
83 opt_complementary = "?1"; /* 1 argument max */ 83 opts = getopt32(argv, "^" "dqtp:u" "\0" "?1"/*1 arg max*/, &path);
84 opts = getopt32(argv, "dqtp:u", &path);
85 84
86 chp = argv[optind]; 85 chp = argv[optind];
87 if (!chp) { 86 if (!chp) {
diff --git a/coreutils/mv.c b/coreutils/mv.c
index 7f6e9fef5..10cbc506f 100644
--- a/coreutils/mv.c
+++ b/coreutils/mv.c
@@ -55,8 +55,10 @@ int mv_main(int argc, char **argv)
55 * If more than one of -f, -i, -n is specified , only the final one 55 * If more than one of -f, -i, -n is specified , only the final one
56 * takes effect (it unsets previous options). 56 * takes effect (it unsets previous options).
57 */ 57 */
58 opt_complementary = "-2:f-in:i-fn:n-fi"; 58 flags = getopt32long(argv, "^"
59 flags = getopt32long(argv, "finv", 59 "finv"
60 "\0"
61 "-2:f-in:i-fn:n-fi",
60 "interactive\0" No_argument "i" 62 "interactive\0" No_argument "i"
61 "force\0" No_argument "f" 63 "force\0" No_argument "f"
62 "no-clobber\0" No_argument "n" 64 "no-clobber\0" No_argument "n"
diff --git a/coreutils/readlink.c b/coreutils/readlink.c
index 7f8d6b239..b8e327d11 100644
--- a/coreutils/readlink.c
+++ b/coreutils/readlink.c
@@ -71,8 +71,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
71 IF_FEATURE_READLINK_FOLLOW( 71 IF_FEATURE_READLINK_FOLLOW(
72 unsigned opt; 72 unsigned opt;
73 /* We need exactly one non-option argument. */ 73 /* We need exactly one non-option argument. */
74 opt_complementary = "=1"; 74 opt = getopt32(argv, "^" "fnvsq" "\0" "=1");
75 opt = getopt32(argv, "fnvsq");
76 fname = argv[optind]; 75 fname = argv[optind];
77 ) 76 )
78 IF_NOT_FEATURE_READLINK_FOLLOW( 77 IF_NOT_FEATURE_READLINK_FOLLOW(
diff --git a/coreutils/rm.c b/coreutils/rm.c
index 5e4acab8c..b68a82dc4 100644
--- a/coreutils/rm.c
+++ b/coreutils/rm.c
@@ -46,8 +46,7 @@ int rm_main(int argc UNUSED_PARAM, char **argv)
46 int flags = 0; 46 int flags = 0;
47 unsigned opt; 47 unsigned opt;
48 48
49 opt_complementary = "f-i:i-f"; 49 opt = getopt32(argv, "^" "fiRrv" "\0" "f-i:i-f");
50 opt = getopt32(argv, "fiRrv");
51 argv += optind; 50 argv += optind;
52 if (opt & 1) 51 if (opt & 1)
53 flags |= FILEUTILS_FORCE; 52 flags |= FILEUTILS_FORCE;
diff --git a/coreutils/shuf.c b/coreutils/shuf.c
index 403041534..d0caaa2ce 100644
--- a/coreutils/shuf.c
+++ b/coreutils/shuf.c
@@ -70,8 +70,11 @@ int shuf_main(int argc, char **argv)
70 unsigned numlines; 70 unsigned numlines;
71 char eol; 71 char eol;
72 72
73 opt_complementary = "e--i:i--e"; /* mutually exclusive */ 73 opts = getopt32(argv, "^"
74 opts = getopt32(argv, OPT_STR, &opt_i_str, &opt_n_str, &opt_o_str); 74 OPT_STR
75 "\0" "e--i:i--e"/* mutually exclusive */,
76 &opt_i_str, &opt_n_str, &opt_o_str
77 );
75 78
76 argc -= optind; 79 argc -= optind;
77 argv += optind; 80 argv += optind;
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 9860dca64..ceea24491 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -94,7 +94,7 @@
94*/ 94*/
95 95
96/* These are sort types */ 96/* These are sort types */
97static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:*t:"; 97#define OPT_STR "ngMucszbrdfimS:T:o:k:*t:"
98enum { 98enum {
99 FLAG_n = 1, /* Numeric sort */ 99 FLAG_n = 1, /* Numeric sort */
100 FLAG_g = 2, /* Sort using strtod() */ 100 FLAG_g = 2, /* Sort using strtod() */
@@ -378,9 +378,11 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
378 xfunc_error_retval = 2; 378 xfunc_error_retval = 2;
379 379
380 /* Parse command line options */ 380 /* Parse command line options */
381 /* -o and -t can be given at most once */ 381 opts = getopt32(argv, "^"
382 opt_complementary = "o--o:t--t"; /* -t, -o: at most one of each */ 382 OPT_STR
383 opts = getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); 383 "\0" "o--o:t--t"/*-t, -o: at most one of each*/,
384 &str_ignored, &str_ignored, &str_o, &lst_k, &str_t
385 );
384 /* global b strips leading and trailing spaces */ 386 /* global b strips leading and trailing spaces */
385 if (opts & FLAG_b) 387 if (opts & FLAG_b)
386 option_mask32 |= FLAG_bb; 388 option_mask32 |= FLAG_bb;
diff --git a/coreutils/split.c b/coreutils/split.c
index d0c63573a..4e1db190c 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -100,8 +100,11 @@ int split_main(int argc UNUSED_PARAM, char **argv)
100 100
101 setup_common_bufsiz(); 101 setup_common_bufsiz();
102 102
103 opt_complementary = "?2"; /* max 2 args; -a N */ 103 opt = getopt32(argv, "^"
104 opt = getopt32(argv, "l:b:a:+", &count_p, &count_p, &suffix_len); 104 "l:b:a:+" /* -a N */
105 "\0" "?2"/*max 2 args*/,
106 &count_p, &count_p, &suffix_len
107 );
105 108
106 if (opt & SPLIT_OPT_l) 109 if (opt & SPLIT_OPT_l)
107 cnt = XATOOFF(count_p); 110 cnt = XATOOFF(count_p);
diff --git a/coreutils/stat.c b/coreutils/stat.c
index 4e926a908..dafbd4e9f 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -762,11 +762,13 @@ int stat_main(int argc UNUSED_PARAM, char **argv)
762 unsigned opts; 762 unsigned opts;
763 statfunc_ptr statfunc = do_stat; 763 statfunc_ptr statfunc = do_stat;
764 764
765 opt_complementary = "-1"; /* min one arg */ 765 opts = getopt32(argv, "^"
766 opts = getopt32(argv, "tL" 766 "tL"
767 IF_FEATURE_STAT_FILESYSTEM("f") 767 IF_FEATURE_STAT_FILESYSTEM("f")
768 IF_SELINUX("Z") 768 IF_SELINUX("Z")
769 IF_FEATURE_STAT_FORMAT("c:", &format) 769 IF_FEATURE_STAT_FORMAT("c:")
770 "\0" "-1" /* min one arg */
771 IF_FEATURE_STAT_FORMAT(,&format)
770 ); 772 );
771#if ENABLE_FEATURE_STAT_FILESYSTEM 773#if ENABLE_FEATURE_STAT_FILESYSTEM
772 if (opts & OPT_FILESYS) /* -f */ 774 if (opts & OPT_FILESYS) /* -f */
diff --git a/coreutils/sync.c b/coreutils/sync.c
index 66445281a..9be47ab64 100644
--- a/coreutils/sync.c
+++ b/coreutils/sync.c
@@ -59,8 +59,7 @@ int sync_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
59 OPT_SYNCFS = (1 << 1), 59 OPT_SYNCFS = (1 << 1),
60 }; 60 };
61 61
62 opt_complementary = "d--f:f--d"; 62 opts = getopt32(argv, "^" "df" "\0" "d--f:f--d");
63 opts = getopt32(argv, "df");
64 argv += optind; 63 argv += optind;
65 64
66 /* Handle the no-argument case. */ 65 /* Handle the no-argument case. */
diff --git a/coreutils/tail.c b/coreutils/tail.c
index fd310f422..7335ba11e 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -140,9 +140,11 @@ int tail_main(int argc, char **argv)
140#endif 140#endif
141 141
142 /* -s NUM, -F imlies -f */ 142 /* -s NUM, -F imlies -f */
143 IF_FEATURE_FANCY_TAIL(opt_complementary = "Ff";) 143 opt = getopt32(argv, IF_FEATURE_FANCY_TAIL("^")
144 opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:+vF"), 144 "fc:n:"IF_FEATURE_FANCY_TAIL("qs:+vF")
145 &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period)); 145 IF_FEATURE_FANCY_TAIL("\0" "Ff"),
146 &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period)
147 );
146#define FOLLOW (opt & 0x1) 148#define FOLLOW (opt & 0x1)
147#define COUNT_BYTES (opt & 0x2) 149#define COUNT_BYTES (opt & 0x2)
148 //if (opt & 0x1) // -f 150 //if (opt & 0x1) // -f
diff --git a/coreutils/tr.c b/coreutils/tr.c
index 64e4efc91..c5872434a 100644
--- a/coreutils/tr.c
+++ b/coreutils/tr.c
@@ -298,8 +298,8 @@ int tr_main(int argc UNUSED_PARAM, char **argv)
298 * In POSIX locale, these are the same. 298 * In POSIX locale, these are the same.
299 */ 299 */
300 300
301 opt_complementary = "-1"; 301 /* '+': stop at first non-option */
302 opts = getopt32(argv, "+Ccds"); /* '+': stop at first non-option */ 302 opts = getopt32(argv, "^+" "Ccds" "\0" "-1");
303 argv += optind; 303 argv += optind;
304 304
305 str1_length = expand(*argv++, &str1); 305 str1_length = expand(*argv++, &str1);
diff --git a/coreutils/truncate.c b/coreutils/truncate.c
index f67abaf40..f693570aa 100644
--- a/coreutils/truncate.c
+++ b/coreutils/truncate.c
@@ -50,8 +50,7 @@ int truncate_main(int argc UNUSED_PARAM, char **argv)
50 OPT_SIZE = (1 << 1), 50 OPT_SIZE = (1 << 1),
51 }; 51 };
52 52
53 opt_complementary = "s:-1"; 53 opts = getopt32(argv, "^" "cs:" "\0" "s:-1", &size_str);
54 opts = getopt32(argv, "cs:", &size_str);
55 54
56 if (!(opts & OPT_NOCREATE)) 55 if (!(opts & OPT_NOCREATE))
57 flags |= O_CREAT; 56 flags |= O_CREAT;
diff --git a/coreutils/unlink.c b/coreutils/unlink.c
index e32a9743c..56309b1c7 100644
--- a/coreutils/unlink.c
+++ b/coreutils/unlink.c
@@ -25,8 +25,7 @@
25int unlink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 25int unlink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
26int unlink_main(int argc UNUSED_PARAM, char **argv) 26int unlink_main(int argc UNUSED_PARAM, char **argv)
27{ 27{
28 opt_complementary = "=1"; /* must have exactly 1 param */ 28 getopt32(argv, "^" "" "\0" "=1");
29 getopt32(argv, "");
30 argv += optind; 29 argv += optind;
31 xunlink(argv[0]); 30 xunlink(argv[0]);
32 return 0; 31 return 0;
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 4e72e86ee..5ef05ee4d 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -120,8 +120,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv)
120 char *outname = NULL; 120 char *outname = NULL;
121 char *line; 121 char *line;
122 122
123 opt_complementary = "?1"; /* 1 argument max */ 123 getopt32(argv, "^" "o:" "\0" "?1"/* 1 arg max*/, &outname);
124 getopt32(argv, "o:", &outname);
125 argv += optind; 124 argv += optind;
126 125
127 if (!argv[0]) 126 if (!argv[0])
@@ -196,8 +195,7 @@ int base64_main(int argc UNUSED_PARAM, char **argv)
196 FILE *src_stream; 195 FILE *src_stream;
197 unsigned opts; 196 unsigned opts;
198 197
199 opt_complementary = "?1"; /* 1 argument max */ 198 opts = getopt32(argv, "^" "d" "\0" "?1"/* 1 arg max*/);
200 opts = getopt32(argv, "d");
201 argv += optind; 199 argv += optind;
202 200
203 if (!argv[0]) 201 if (!argv[0])
diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c
index 7164f838a..d6e077430 100644
--- a/coreutils/uuencode.c
+++ b/coreutils/uuencode.c
@@ -49,8 +49,7 @@ int uuencode_main(int argc UNUSED_PARAM, char **argv)
49 49
50 tbl = bb_uuenc_tbl_std; 50 tbl = bb_uuenc_tbl_std;
51 mode = 0666 & ~umask(0666); 51 mode = 0666 & ~umask(0666);
52 opt_complementary = "-1:?2"; /* must have 1 or 2 args */ 52 if (getopt32(argv, "^" "m" "\0" "-1:?2"/*must have 1 or 2 args*/)) {
53 if (getopt32(argv, "m")) {
54 tbl = bb_uuenc_tbl_base64; 53 tbl = bb_uuenc_tbl_base64;
55 } 54 }
56 argv += optind; 55 argv += optind;
diff --git a/coreutils/who.c b/coreutils/who.c
index 6be3d692e..cfe0c921e 100644
--- a/coreutils/who.c
+++ b/coreutils/who.c
@@ -117,8 +117,7 @@ int who_main(int argc UNUSED_PARAM, char **argv)
117 unsigned opt; 117 unsigned opt;
118 const char *fmt = "%s"; 118 const char *fmt = "%s";
119 119
120 opt_complementary = "=0"; 120 opt = getopt32(argv, do_who ? "^" "aH" "\0" "=0": "^" "" "\0" "=0");
121 opt = getopt32(argv, do_who ? "aH" : "");
122 if ((opt & 2) || do_w) /* -H or we are w */ 121 if ((opt & 2) || do_w) /* -H or we are w */
123 puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); 122 puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST");
124 123
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index b770383c4..e4d61df35 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -181,8 +181,9 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv)
181 INIT_G(); 181 INIT_G();
182 182
183 /* We require exactly one argument: the directory name */ 183 /* We require exactly one argument: the directory name */
184 opt_complementary = "=1"; 184 GETOPT32(argv, "^" "a:*u:" "\0" "=1" LONGOPTS,
185 GETOPT32(argv, "a:*u:" LONGOPTS, &arg_list, &umask_p); 185 &arg_list, &umask_p
186 );
186 187
187 umask(xstrtou_range(umask_p, 8, 0, 07777)); 188 umask(xstrtou_range(umask_p, 8, 0, 07777));
188 189
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 45c277a53..12cf6c3a5 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -451,15 +451,17 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
451 451
452 INIT_G(); 452 INIT_G();
453 453
454 /* -K or -S is required; they are mutually exclusive */ 454 opt = GETOPT32(argv, "^"
455 /* -p is required if -m is given */ 455 "KSbqtma:n:s:u:c:x:p:"
456 /* -xpun (at least one) is required if -K is given */ 456 IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:")
457 /* -xa (at least one) is required if -S is given */ 457 /* -K or -S is required; they are mutually exclusive */
458 /* -q turns off -v */ 458 /* -p is required if -m is given */
459 opt_complementary = "K:S:K--S:S--K:m?p:K?xpun:S?xa" 459 /* -xpun (at least one) is required if -K is given */
460 IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"); 460 /* -xa (at least one) is required if -S is given */
461 opt = GETOPT32(argv, "KSbqtma:n:s:u:c:x:p:" 461 /* -q turns off -v */
462 IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"), 462 "\0"
463 "K:S:K--S:S--K:m?p:K?xpun:S?xa"
464 IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"),
463 LONGOPTS 465 LONGOPTS
464 &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile 466 &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile
465 IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) 467 IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
diff --git a/debianutils/which.c b/debianutils/which.c
index b31d61871..3bd54ac42 100644
--- a/debianutils/which.c
+++ b/debianutils/which.c
@@ -37,8 +37,7 @@ int which_main(int argc UNUSED_PARAM, char **argv)
37 if (!env_path) 37 if (!env_path)
38 env_path = bb_default_root_path; 38 env_path = bb_default_root_path;
39 39
40 opt_complementary = "-1"; /* at least one argument */ 40 getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/);
41 getopt32(argv, "a");
42 argv += optind; 41 argv += optind;
43 42
44 do { 43 do {
diff --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c
index 9f14b26ec..a1caf011c 100644
--- a/e2fsprogs/tune2fs.c
+++ b/e2fsprogs/tune2fs.c
@@ -71,8 +71,7 @@ int tune2fs_main(int argc UNUSED_PARAM, char **argv)
71 struct ext2_super_block *sb; 71 struct ext2_super_block *sb;
72 int fd; 72 int fd;
73 73
74 opt_complementary = "=1"; 74 opts = getopt32(argv, "^" "L:c:i:C:" "\0" "=1", &label, &str_c, &str_i, &str_C);
75 opts = getopt32(argv, "L:c:i:C:", &label, &str_c, &str_i, &str_C);
76 if (!opts) 75 if (!opts)
77 bb_show_usage(); 76 bb_show_usage();
78 argv += optind; // argv[0] -- device 77 argv += optind; // argv[0] -- device
diff --git a/editors/cmp.c b/editors/cmp.c
index f53d9603c..ec86c0ce2 100644
--- a/editors/cmp.c
+++ b/editors/cmp.c
@@ -36,7 +36,7 @@ static const char fmt_differ[] ALIGN1 = "%s %s differ: char %"OFF_FMT"u, line %u
36// This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"u %o %o\n" 36// This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"u %o %o\n"
37static const char fmt_l_opt[] ALIGN1 = "%.0s%.0s%"OFF_FMT"u %3o %3o\n"; 37static const char fmt_l_opt[] ALIGN1 = "%.0s%.0s%"OFF_FMT"u %3o %3o\n";
38 38
39static const char opt_chars[] ALIGN1 = "sl"; 39#define OPT_STR "sl"
40#define CMP_OPT_s (1<<0) 40#define CMP_OPT_s (1<<0)
41#define CMP_OPT_l (1<<1) 41#define CMP_OPT_l (1<<1)
42 42
@@ -52,11 +52,13 @@ int cmp_main(int argc UNUSED_PARAM, char **argv)
52 unsigned opt; 52 unsigned opt;
53 int retval = 0; 53 int retval = 0;
54 54
55 opt_complementary = "-1" 55 opt = getopt32(argv, "^"
56 OPT_STR
57 "\0" "-1"
56 IF_DESKTOP(":?4") 58 IF_DESKTOP(":?4")
57 IF_NOT_DESKTOP(":?2") 59 IF_NOT_DESKTOP(":?2")
58 ":l--s:s--l"; 60 ":l--s:s--l"
59 opt = getopt32(argv, opt_chars); 61 );
60 argv += optind; 62 argv += optind;
61 63
62 filename1 = *argv; 64 filename1 = *argv;
diff --git a/editors/diff.c b/editors/diff.c
index d90ac8f94..2f254575c 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -984,8 +984,8 @@ int diff_main(int argc UNUSED_PARAM, char **argv)
984 INIT_G(); 984 INIT_G();
985 985
986 /* exactly 2 params; collect multiple -L <label>; -U N */ 986 /* exactly 2 params; collect multiple -L <label>; -U N */
987 opt_complementary = "=2"; 987 GETOPT32(argv, "^" "abdiL:*NqrsS:tTU:+wupBE" "\0" "=2"
988 GETOPT32(argv, "abdiL:*NqrsS:tTU:+wupBE" LONGOPTS, 988 LONGOPTS,
989 &L_arg, &s_start, &opt_U_context); 989 &L_arg, &s_start, &opt_U_context);
990 argv += optind; 990 argv += optind;
991 while (L_arg) 991 while (L_arg)
diff --git a/editors/sed.c b/editors/sed.c
index 1a1098859..f68f44724 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -1507,13 +1507,15 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
1507 /* do normal option parsing */ 1507 /* do normal option parsing */
1508 opt_e = opt_f = NULL; 1508 opt_e = opt_f = NULL;
1509 opt_i = NULL; 1509 opt_i = NULL;
1510 opt_complementary = "nn"; /* count -n */
1511 /* -i must be first, to match OPT_in_place definition */ 1510 /* -i must be first, to match OPT_in_place definition */
1512 /* -E is a synonym of -r: 1511 /* -E is a synonym of -r:
1513 * GNU sed 4.2.1 mentions it in neither --help 1512 * GNU sed 4.2.1 mentions it in neither --help
1514 * nor manpage, but does recognize it. 1513 * nor manpage, but does recognize it.
1515 */ 1514 */
1516 opt = getopt32long(argv, "i::rEne:*f:*", sed_longopts, 1515 opt = getopt32long(argv, "^"
1516 "i::rEne:*f:*"
1517 "\0" "nn"/*count -n*/,
1518 sed_longopts,
1517 &opt_i, &opt_e, &opt_f, 1519 &opt_i, &opt_e, &opt_f,
1518 &G.be_quiet); /* counter for -n */ 1520 &G.be_quiet); /* counter for -n */
1519 //argc -= optind; 1521 //argc -= optind;
diff --git a/findutils/grep.c b/findutils/grep.c
index 568ab12c2..7c5f73d2f 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -107,6 +107,7 @@
107//usage:#define fgrep_trivial_usage NOUSAGE_STR 107//usage:#define fgrep_trivial_usage NOUSAGE_STR
108//usage:#define fgrep_full_usage "" 108//usage:#define fgrep_full_usage ""
109 109
110/* -e,-f are lists; -m,-A,-B,-C have numeric param */
110#define OPTSTR_GREP \ 111#define OPTSTR_GREP \
111 "lnqvscFiHhe:*f:*Lorm:+wx" \ 112 "lnqvscFiHhe:*f:*Lorm:+wx" \
112 IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \ 113 IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \
@@ -686,11 +687,9 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
686 687
687 /* do normal option parsing */ 688 /* do normal option parsing */
688#if ENABLE_FEATURE_GREP_CONTEXT 689#if ENABLE_FEATURE_GREP_CONTEXT
689 /* -H unsets -h; -C unsets -A,-B; -e,-f are lists; 690 /* -H unsets -h; -C unsets -A,-B */
690 * -m,-A,-B,-C have numeric param */
691 opt_complementary = "H-h:C-AB";
692 opts = getopt32(argv, 691 opts = getopt32(argv,
693 OPTSTR_GREP, 692 "^" OPTSTR_GREP "\0" "H-h:C-AB",
694 &pattern_head, &fopt, &max_matches, 693 &pattern_head, &fopt, &max_matches,
695 &lines_after, &lines_before, &Copt); 694 &lines_after, &lines_before, &Copt);
696 695
@@ -716,9 +715,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
716 } 715 }
717#else 716#else
718 /* with auto sanity checks */ 717 /* with auto sanity checks */
719 /* -H unsets -h; -c,-q or -l unset -n; -e,-f are lists; -m N */ 718 getopt32(argv, "^" OPTSTR_GREP "\0" "H-h:c-n:q-n:l-n:", // why trailing ":"?
720 opt_complementary = "H-h:c-n:q-n:l-n:";
721 getopt32(argv, OPTSTR_GREP,
722 &pattern_head, &fopt, &max_matches); 719 &pattern_head, &fopt, &max_matches);
723#endif 720#endif
724 invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ 721 invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */
diff --git a/include/libbb.h b/include/libbb.h
index 64d1f2fcb..2eb1fef33 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1185,9 +1185,6 @@ void make_all_argv_opts(char **argv) FAST_FUNC;
1185char* single_argv(char **argv) FAST_FUNC; 1185char* single_argv(char **argv) FAST_FUNC;
1186extern const char *const bb_argv_dash[]; /* { "-", NULL } */ 1186extern const char *const bb_argv_dash[]; /* { "-", NULL } */
1187extern uint32_t option_mask32; 1187extern uint32_t option_mask32;
1188//TODO: get rid of this global variable. How about a trick where optstring can be
1189// "^optchars""\0""complementary" (the leading "^" is an indicator)?
1190extern const char *opt_complementary;
1191uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; 1188uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
1192# define No_argument "\0" 1189# define No_argument "\0"
1193# define Required_argument "\001" 1190# define Required_argument "\001"
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index b2b4de8cb..f778c6e89 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -96,9 +96,11 @@ getopt32(char **argv, const char *applet_opts, ...)
96 env -i ls -d / 96 env -i ls -d /
97 Here we want env to process just the '-i', not the '-d'. 97 Here we want env to process just the '-i', not the '-d'.
98 98
99 "!" Report bad option, missing required options, 99 "!" Report bad options, missing required options,
100 inconsistent options with all-ones return value (instead of abort). 100 inconsistent options with all-ones return value (instead of abort).
101 101
102 "^" options string is "^optchars""\0""opt_complementary".
103
102uint32_t 104uint32_t
103getopt32long(char **argv, const char *applet_opts, const char *logopts...) 105getopt32long(char **argv, const char *applet_opts, const char *logopts...)
104 106
@@ -121,7 +123,7 @@ getopt32long(char **argv, const char *applet_opts, const char *logopts...)
121 config process and not a required feature. The current standard 123 config process and not a required feature. The current standard
122 is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS. 124 is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS.
123 125
124const char *opt_complementary 126opt_complementary - option modifiers.
125 127
126 ":" The colon (":") is used to separate groups of two or more chars 128 ":" The colon (":") is used to separate groups of two or more chars
127 and/or groups of chars and special characters (stating some 129 and/or groups of chars and special characters (stating some
@@ -132,8 +134,7 @@ const char *opt_complementary
132 Their flags will be turned on if the main option is found even 134 Their flags will be turned on if the main option is found even
133 if they are not specified on the command line. For example: 135 if they are not specified on the command line. For example:
134 136
135 opt_complementary = "abc"; 137 flags = getopt32(argv, "^abcd""\0""abc")
136 flags = getopt32(argv, "abcd")
137 138
138 If getopt() finds "-a" on the command line, then 139 If getopt() finds "-a" on the command line, then
139 getopt32's return value will be as if "-a -b -c" were 140 getopt32's return value will be as if "-a -b -c" were
@@ -146,8 +147,7 @@ const char *opt_complementary
146 if w is given more than once, it is "unlimited" 147 if w is given more than once, it is "unlimited"
147 148
148 int w_counter = 0; // must be initialized! 149 int w_counter = 0; // must be initialized!
149 opt_complementary = "ww"; 150 getopt32(argv, "^w""\0""ww", &w_counter);
150 getopt32(argv, "w", &w_counter);
151 if (w_counter) 151 if (w_counter)
152 width = (w_counter == 1) ? 132 : INT_MAX; 152 width = (w_counter == 1) ? 132 : INT_MAX;
153 else 153 else
@@ -162,8 +162,9 @@ const char *opt_complementary
162 162
163 llist_t *my_b = NULL; 163 llist_t *my_b = NULL;
164 int verbose_level = 0; 164 int verbose_level = 0;
165 opt_complementary = "vv:b-c:c-b"; 165 f = getopt32(argv, "^vb:*c"
166 f = getopt32(argv, "vb:*c", &my_b, &verbose_level); 166 "\0""vv:b-c:c-b"
167 , &my_b, &verbose_level);
167 if (f & 2) // -c after -b unsets -b flag 168 if (f & 2) // -c after -b unsets -b flag
168 while (my_b) dosomething_with(llist_pop(&my_b)); 169 while (my_b) dosomething_with(llist_pop(&my_b));
169 if (my_b) // but llist is stored if -b is specified 170 if (my_b) // but llist is stored if -b is specified
@@ -199,7 +200,7 @@ Special characters:
199 getopt32 finds -s, then -d is unset or if it finds -d 200 getopt32 finds -s, then -d is unset or if it finds -d
200 then -s is unset. (Note: busybox implements the GNU 201 then -s is unset. (Note: busybox implements the GNU
201 "--max-depth" option as "-d".) To obtain this behavior, you 202 "--max-depth" option as "-d".) To obtain this behavior, you
202 set opt_complementary = "s-d:d-s". Only one flag value is 203 set opt_complementary to "s-d:d-s". Only one flag value is
203 added to getopt32's return value depending on the 204 added to getopt32's return value depending on the
204 position of the options on the command line. If one of the 205 position of the options on the command line. If one of the
205 two options requires an argument pointer (":" in applet_opts 206 two options requires an argument pointer (":" in applet_opts
@@ -207,8 +208,7 @@ Special characters:
207 208
208 char *smax_print_depth; 209 char *smax_print_depth;
209 210
210 opt_complementary = "s-d:d-s:x-x"; 211 opt = getopt32(argv, "^sd:x""\0""s-d:d-s:x-x", &smax_print_depth);
211 opt = getopt32(argv, "sd:x", &smax_print_depth);
212 212
213 if (opt & 2) 213 if (opt & 2)
214 max_print_depth = atoi(smax_print_depth); 214 max_print_depth = atoi(smax_print_depth);
@@ -224,7 +224,7 @@ Special characters:
224 The cut applet must have only one type of list specified, so 224 The cut applet must have only one type of list specified, so
225 -b, -c and -f are mutually exclusive and should raise an error 225 -b, -c and -f are mutually exclusive and should raise an error
226 if specified together. In this case you must set 226 if specified together. In this case you must set
227 opt_complementary = "b--cf:c--bf:f--bc". If two of the 227 opt_complementary to "b--cf:c--bf:f--bc". If two of the
228 mutually exclusive options are found, getopt32 will call 228 mutually exclusive options are found, getopt32 will call
229 bb_show_usage() and die. 229 bb_show_usage() and die.
230 230
@@ -236,8 +236,7 @@ Special characters:
236 with xatoi_positive() - allowed range is 0..INT_MAX. 236 with xatoi_positive() - allowed range is 0..INT_MAX.
237 237
238 int param; // "unsigned param;" will also work 238 int param; // "unsigned param;" will also work
239 opt_complementary = "p+"; 239 getopt32(argv, "^p:""\0""p+", &param);
240 getopt32(argv, "p:", &param);
241 240
242 "o::" A double colon after a char in opt_complementary means that the 241 "o::" A double colon after a char in opt_complementary means that the
243 option can occur multiple times. Each occurrence will be saved as 242 option can occur multiple times. Each occurrence will be saved as
@@ -252,8 +251,7 @@ Special characters:
252 (this pointer must be initializated to NULL if the list is empty 251 (this pointer must be initializated to NULL if the list is empty
253 as required by llist_add_to_end(llist_t **old_head, char *new_item).) 252 as required by llist_add_to_end(llist_t **old_head, char *new_item).)
254 253
255 opt_complementary = "e::"; 254 getopt32(argv, "^e:""\0""e::", &patterns);
256 getopt32(argv, "e:", &patterns);
257 255
258 $ grep -e user -e root /etc/passwd 256 $ grep -e user -e root /etc/passwd
259 root:x:0:0:root:/root:/bin/bash 257 root:x:0:0:root:/root:/bin/bash
@@ -271,8 +269,7 @@ Special characters:
271 For example from "id" applet: 269 For example from "id" applet:
272 270
273 // Don't allow -n -r -rn -ug -rug -nug -rnug 271 // Don't allow -n -r -rn -ug -rug -nug -rnug
274 opt_complementary = "r?ug:n?ug:u--g:g--u"; 272 flags = getopt32(argv, "^rnug""\0""r?ug:n?ug:u--g:g--u");
275 flags = getopt32(argv, "rnug");
276 273
277 This example allowed only: 274 This example allowed only:
278 $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng 275 $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng
@@ -283,8 +280,7 @@ Special characters:
283 For example from "start-stop-daemon" applet: 280 For example from "start-stop-daemon" applet:
284 281
285 // Don't allow -KS -SK, but -S or -K is required 282 // Don't allow -KS -SK, but -S or -K is required
286 opt_complementary = "K:S:K--S:S--K"; 283 flags = getopt32(argv, "^KS...""\0""K:S:K--S:S--K");
287 flags = getopt32(argv, "KS...);
288 284
289 285
290 Don't forget to use ':'. For example, "?322-22-23X-x-a" 286 Don't forget to use ':'. For example, "?322-22-23X-x-a"
@@ -299,8 +295,6 @@ Special characters:
299 295
300const char *const bb_argv_dash[] = { "-", NULL }; 296const char *const bb_argv_dash[] = { "-", NULL };
301 297
302const char *opt_complementary;
303
304enum { 298enum {
305 PARAM_STRING, 299 PARAM_STRING,
306 PARAM_LIST, 300 PARAM_LIST,
@@ -337,10 +331,12 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options,
337 int argc; 331 int argc;
338 unsigned flags = 0; 332 unsigned flags = 0;
339 unsigned requires = 0; 333 unsigned requires = 0;
334 unsigned len;
340 t_complementary complementary[33]; /* last stays zero-filled */ 335 t_complementary complementary[33]; /* last stays zero-filled */
341 char first_char; 336 char dont_die_flag;
342 int c; 337 int c;
343 const unsigned char *s; 338 const unsigned char *s;
339 const char *opt_complementary;
344 t_complementary *on_off; 340 t_complementary *on_off;
345#if ENABLE_LONG_OPTS 341#if ENABLE_LONG_OPTS
346 const struct option *l_o; 342 const struct option *l_o;
@@ -349,23 +345,29 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options,
349 unsigned trigger; 345 unsigned trigger;
350 int min_arg = 0; 346 int min_arg = 0;
351 int max_arg = -1; 347 int max_arg = -1;
352
353#define SHOW_USAGE_IF_ERROR 1
354
355 int spec_flgs = 0; 348 int spec_flgs = 0;
356 349
357 /* skip 0: some applets cheat: they do not actually HAVE argv[0] */ 350#define SHOW_USAGE_IF_ERROR 1
358 argc = 1 + string_array_len(argv + 1);
359 351
360 on_off = complementary; 352 on_off = complementary;
361 memset(on_off, 0, sizeof(complementary)); 353 memset(on_off, 0, sizeof(complementary));
362 354
363 applet_opts = strcpy(alloca(strlen(applet_opts) + 1), applet_opts); 355 len = strlen(applet_opts);
364 356
365 /* skip bbox extension */ 357 /* skip bbox extension */
366 first_char = applet_opts[0]; 358 opt_complementary = NULL;
367 if (first_char == '!') 359 if (applet_opts[0] == '^') {
368 applet_opts++; 360 applet_opts++;
361 /* point it past terminating NUL */
362 opt_complementary = applet_opts + len;
363 }
364
365 /* skip another bbox extension */
366 dont_die_flag = applet_opts[0];
367 if (dont_die_flag == '!')
368 applet_opts++;
369
370 applet_opts = strcpy(alloca(len + 1), applet_opts);
369 371
370 /* skip GNU extension */ 372 /* skip GNU extension */
371 s = (const unsigned char *)applet_opts; 373 s = (const unsigned char *)applet_opts;
@@ -435,7 +437,8 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options,
435 } 437 }
436#endif /* ENABLE_LONG_OPTS */ 438#endif /* ENABLE_LONG_OPTS */
437 439
438 for (s = (const unsigned char *)opt_complementary; s && *s; s++) { 440 s = (const unsigned char *)opt_complementary;
441 if (s) for (; *s; s++) {
439 t_complementary *pair; 442 t_complementary *pair;
440 unsigned *pair_switch; 443 unsigned *pair_switch;
441 444
@@ -513,8 +516,6 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options,
513 s--; 516 s--;
514 } 517 }
515 518
516 /* Make it unnecessary to clear it by hand after each getopt32 call */
517 opt_complementary = NULL;
518 /* In case getopt32 was already called: 519 /* In case getopt32 was already called:
519 * reset the libc getopt() function, which keeps internal state. 520 * reset the libc getopt() function, which keeps internal state.
520 * run_nofork_applet() does this, but we might end up here 521 * run_nofork_applet() does this, but we might end up here
@@ -522,6 +523,9 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options,
522 */ 523 */
523 GETOPT_RESET(); 524 GETOPT_RESET();
524 525
526 /* skip 0: some applets cheat: they do not actually HAVE argv[0] */
527 argc = 1 + string_array_len(argv + 1);
528
525 /* Note: just "getopt() <= 0" will not work well for 529 /* Note: just "getopt() <= 0" will not work well for
526 * "fake" short options, like this one: 530 * "fake" short options, like this one:
527 * wget $'-\203' "Test: test" http://kernel.org/ 531 * wget $'-\203' "Test: test" http://kernel.org/
@@ -583,7 +587,7 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options,
583 return flags; 587 return flags;
584 588
585 error: 589 error:
586 if (first_char != '!') 590 if (dont_die_flag != '!')
587 bb_show_usage(); 591 bb_show_usage();
588 return (int32_t)-1; 592 return (int32_t)-1;
589} 593}
diff --git a/libbb/parse_config.c b/libbb/parse_config.c
index eaf69d97f..8701b010c 100644
--- a/libbb/parse_config.c
+++ b/libbb/parse_config.c
@@ -42,8 +42,9 @@ int parse_main(int argc UNUSED_PARAM, char **argv)
42 int mintokens = 0, ntokens = 128; 42 int mintokens = 0, ntokens = 128;
43 unsigned noout; 43 unsigned noout;
44 44
45 opt_complementary = "-1"; 45 noout = 1 & getopt32(argv, "^" "xn:+m:+d:f:+" "\0" "-1",
46 noout = 1 & getopt32(argv, "xn:+m:+d:f:+", &ntokens, &mintokens, &delims, &flags); 46 &ntokens, &mintokens, &delims, &flags
47 );
47 //argc -= optind; 48 //argc -= optind;
48 argv += optind; 49 argv += optind;
49 50
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index 15c92a7cd..6125983ce 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -98,7 +98,6 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
98 * (getopt32() does it itself, but getopt() doesn't (and can't)) 98 * (getopt32() does it itself, but getopt() doesn't (and can't))
99 */ 99 */
100 GETOPT_RESET(); 100 GETOPT_RESET();
101 /* opt_complementary = NULL; - cleared by each getopt32() call anyway */
102 101
103 argc = string_array_len(argv); 102 argc = string_array_len(argv);
104 103
@@ -123,7 +122,6 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
123 restore_nofork_data(&old); 122 restore_nofork_data(&old);
124 /* Other globals can be simply reset to defaults */ 123 /* Other globals can be simply reset to defaults */
125 GETOPT_RESET(); 124 GETOPT_RESET();
126 /* opt_complementary = NULL; - cleared by each getopt32() call anyway */
127 125
128 return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ 126 return rc & 0xff; /* don't confuse people with "exitcodes" >255 */
129} 127}
@@ -138,7 +136,6 @@ void FAST_FUNC run_noexec_applet_and_exit(int a, const char *name, char **argv)
138 xfunc_error_retval = EXIT_FAILURE; 136 xfunc_error_retval = EXIT_FAILURE;
139 die_func = NULL; 137 die_func = NULL;
140 GETOPT_RESET(); 138 GETOPT_RESET();
141 /* opt_complementary = NULL; - cleared by each getopt32() call anyway */
142 139
143//TODO: think pidof, pgrep, pkill! 140//TODO: think pidof, pgrep, pkill!
144//set_task_comm() makes our pidof find NOEXECs (e.g. "yes >/dev/null"), 141//set_task_comm() makes our pidof find NOEXECs (e.g. "yes >/dev/null"),
diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c
index 5a2b04352..adef2328d 100644
--- a/loginutils/addgroup.c
+++ b/loginutils/addgroup.c
@@ -152,11 +152,12 @@ int addgroup_main(int argc UNUSED_PARAM, char **argv)
152 } 152 }
153 /* Syntax: 153 /* Syntax:
154 * addgroup group 154 * addgroup group
155 * addgroup -g num group 155 * addgroup --gid num group
156 * addgroup user group 156 * addgroup user group
157 * Check for min, max and missing args */ 157 * Check for min, max and missing args */
158 opt_complementary = "-1:?2"; 158 opts = getopt32long(argv, "^" "g:S" "\0" "-1:?2", addgroup_longopts,
159 opts = getopt32long(argv, "g:S", addgroup_longopts, &gid); 159 &gid
160 );
160 /* move past the commandline options */ 161 /* move past the commandline options */
161 argv += optind; 162 argv += optind;
162 //argc -= optind; 163 //argc -= optind;
diff --git a/loginutils/adduser.c b/loginutils/adduser.c
index 8b92df923..b2b5be5b3 100644
--- a/loginutils/adduser.c
+++ b/loginutils/adduser.c
@@ -201,12 +201,15 @@ int adduser_main(int argc UNUSED_PARAM, char **argv)
201 pw.pw_shell = (char *)get_shell_name(); 201 pw.pw_shell = (char *)get_shell_name();
202 pw.pw_dir = NULL; 202 pw.pw_dir = NULL;
203 203
204 /* at least one and at most two non-option args */ 204 opts = getopt32long(argv, "^"
205 /* disable interactive passwd for system accounts */ 205 "h:g:s:G:DSHu:k:"
206 opt_complementary = "-1:?2:SD"; 206 /* at least one and at most two non-option args */
207 opts = getopt32long(argv, "h:g:s:G:DSHu:k:", adduser_longopts, 207 /* disable interactive passwd for system accounts */
208 "\0" "-1:?2:SD",
209 adduser_longopts,
208 &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, 210 &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell,
209 &usegroup, &uid, &skel); 211 &usegroup, &uid, &skel
212 );
210 if (opts & OPT_UID) 213 if (opts & OPT_UID)
211 pw.pw_uid = xatou_range(uid, 0, CONFIG_LAST_ID); 214 pw.pw_uid = xatou_range(uid, 0, CONFIG_LAST_ID);
212 215
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c
index 3c9ed68b9..652e4f127 100644
--- a/loginutils/chpasswd.c
+++ b/loginutils/chpasswd.c
@@ -61,8 +61,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv)
61 if (getuid() != 0) 61 if (getuid() != 0)
62 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 62 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
63 63
64 opt_complementary = "m--ec:e--mc:c--em"; 64 opt = getopt32long(argv, "^" "emc:" "\0" "m--ec:e--mc:c--em",
65 opt = getopt32long(argv, "emc:", chpasswd_longopts, &algo); 65 chpasswd_longopts,
66 &algo
67 );
66 68
67 while ((name = xmalloc_fgetline(stdin)) != NULL) { 69 while ((name = xmalloc_fgetline(stdin)) != NULL) {
68 char *free_me; 70 char *free_me;
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c
index c10a0c8bd..76138a61f 100644
--- a/loginutils/cryptpw.c
+++ b/loginutils/cryptpw.c
@@ -111,9 +111,10 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv)
111 opt_m = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO; 111 opt_m = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO;
112 opt_S = NULL; 112 opt_S = NULL;
113 /* at most two non-option arguments; -P NUM */ 113 /* at most two non-option arguments; -P NUM */
114 opt_complementary = "?2"; 114 getopt32long(argv, "^" "sP:+S:m:a:" "\0" "?2",
115 getopt32long(argv, "sP:+S:m:a:", mkpasswd_longopts, 115 mkpasswd_longopts,
116 &fd, &opt_S, &opt_m, &opt_m); 116 &fd, &opt_S, &opt_m, &opt_m
117 );
117 argv += optind; 118 argv += optind;
118 119
119 /* have no idea how to handle -s... */ 120 /* have no idea how to handle -s... */
diff --git a/loginutils/getty.c b/loginutils/getty.c
index fd5116d08..23e92bc77 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -131,7 +131,7 @@ struct globals {
131//usage: "\n" 131//usage: "\n"
132//usage: "\nBAUD_RATE of 0 leaves it unchanged" 132//usage: "\nBAUD_RATE of 0 leaves it unchanged"
133 133
134static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:+wn"; 134#define OPT_STR "I:LH:f:hil:mt:+wn"
135#define F_INITSTRING (1 << 0) /* -I */ 135#define F_INITSTRING (1 << 0) /* -I */
136#define F_LOCAL (1 << 1) /* -L */ 136#define F_LOCAL (1 << 1) /* -L */
137#define F_FAKEHOST (1 << 2) /* -H */ 137#define F_FAKEHOST (1 << 2) /* -H */
@@ -179,8 +179,7 @@ static void parse_args(char **argv)
179 char *ts; 179 char *ts;
180 int flags; 180 int flags;
181 181
182 opt_complementary = "-2"; /* at least 2 args; -t N */ 182 flags = getopt32(argv, "^" OPT_STR "\0" "-2"/* at least 2 args*/,
183 flags = getopt32(argv, opt_string,
184 &G.initstring, &G.fakehost, &G.issue, 183 &G.initstring, &G.fakehost, &G.issue,
185 &G.login, &G.timeout 184 &G.login, &G.timeout
186 ); 185 );
diff --git a/loginutils/vlock.c b/loginutils/vlock.c
index bf46d085c..9e319fe61 100644
--- a/loginutils/vlock.c
+++ b/loginutils/vlock.c
@@ -66,8 +66,7 @@ int vlock_main(int argc UNUSED_PARAM, char **argv)
66 struct passwd *pw; 66 struct passwd *pw;
67 67
68 pw = xgetpwuid(getuid()); 68 pw = xgetpwuid(getuid());
69 opt_complementary = "=0"; /* no params! */ 69 getopt32(argv, "^" "a" "\0" "=0"/* no args!*/);
70 getopt32(argv, "a");
71 70
72 /* Ignore some signals so that we don't get killed by them */ 71 /* Ignore some signals so that we don't get killed by them */
73 bb_signals(0 72 bb_signals(0
diff --git a/mailutils/popmaildir.c b/mailutils/popmaildir.c
index 1695a9bb8..5756eaa76 100644
--- a/mailutils/popmaildir.c
+++ b/mailutils/popmaildir.c
@@ -125,9 +125,9 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv)
125 INIT_G(); 125 INIT_G();
126 126
127 // parse options 127 // parse options
128 opt_complementary = "-1:dd"; 128 opts = getopt32(argv, "^"
129 opts = getopt32(argv, 129 "bdmVcasTkt:+" "R:+Z:L:+H:+" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:")
130 "bdmVcasTkt:+" "R:+Z:L:+H:+" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:"), 130 "\0" "-1:dd",
131 &timeout, NULL, NULL, NULL, &opt_nlines 131 &timeout, NULL, NULL, NULL, &opt_nlines
132 IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same 132 IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same
133 ); 133 );
diff --git a/mailutils/reformime.c b/mailutils/reformime.c
index 6a0254803..321729e0a 100644
--- a/mailutils/reformime.c
+++ b/mailutils/reformime.c
@@ -280,9 +280,9 @@ int reformime_main(int argc UNUSED_PARAM, char **argv)
280 280
281 // parse options 281 // parse options
282 // N.B. only -x and -X are supported so far 282 // N.B. only -x and -X are supported so far
283 opt_complementary = "x--X:X--x"; 283 opts = getopt32(argv, "^"
284 opts = getopt32(argv, 284 "x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:*h:o:O:")
285 "x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:*h:o:O:"), 285 "\0" "x--X:X--x",
286 &opt_prefix 286 &opt_prefix
287 IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL) 287 IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL)
288 ); 288 );
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c
index 65895f0ec..f440e6319 100644
--- a/mailutils/sendmail.c
+++ b/mailutils/sendmail.c
@@ -256,13 +256,17 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv)
256 G.fp0 = xfdopen_for_read(3); 256 G.fp0 = xfdopen_for_read(3);
257 257
258 // parse options 258 // parse options
259 // -v is a counter, -H and -S are mutually exclusive, -a is a list
260 opt_complementary = "vv:H--S:S--H";
261 // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect 259 // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect
262 // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility, 260 // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility,
263 // it is still under development. 261 // it is still under development.
264 opts = getopt32(argv, "tf:o:iw:+H:S:a:*:v", &opt_from, NULL, 262 opts = getopt32(argv, "^"
265 &timeout, &opt_connect, &opt_connect, &list, &verbose); 263 "tf:o:iw:+H:S:a:*:v"
264 "\0"
265 // -v is a counter, -H and -S are mutually exclusive, -a is a list
266 "vv:H--S:S--H",
267 &opt_from, NULL,
268 &timeout, &opt_connect, &opt_connect, &list, &verbose
269 );
266 //argc -= optind; 270 //argc -= optind;
267 argv += optind; 271 argv += optind;
268 272
diff --git a/miscutils/adjtimex.c b/miscutils/adjtimex.c
index ce6f8ccd8..c1718e909 100644
--- a/miscutils/adjtimex.c
+++ b/miscutils/adjtimex.c
@@ -95,9 +95,10 @@ int adjtimex_main(int argc UNUSED_PARAM, char **argv)
95 95
96 memset(&txc, 0, sizeof(txc)); 96 memset(&txc, 0, sizeof(txc));
97 97
98 opt_complementary = "=0"; /* no valid non-option parameters */ 98 opt = getopt32(argv, "^" "qo:f:p:t:"
99 opt = getopt32(argv, "qo:f:p:t:", 99 "\0" "=0"/*no valid non-option args*/,
100 &opt_o, &opt_f, &opt_p, &opt_t); 100 &opt_o, &opt_f, &opt_p, &opt_t
101 );
101 //if (opt & 0x1) // -q 102 //if (opt & 0x1) // -q
102 if (opt & 0x2) { // -o 103 if (opt & 0x2) { // -o
103 txc.offset = xatol(opt_o); 104 txc.offset = xatol(opt_o);
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 48e429976..f6580a9d4 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -1021,13 +1021,17 @@ int crond_main(int argc UNUSED_PARAM, char **argv)
1021 1021
1022 INIT_G(); 1022 INIT_G();
1023 1023
1024 /* "-b after -f is ignored", and so on for every pair a-b */ 1024 opts = getopt32(argv, "^"
1025 opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") 1025 "l:L:fbSc:" IF_FEATURE_CROND_D("d:")
1026 "\0"
1027 /* "-b after -f is ignored", and so on for every pair a-b */
1028 "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l")
1026 /* -l and -d have numeric param */ 1029 /* -l and -d have numeric param */
1027 ":l+" IF_FEATURE_CROND_D(":d+"); 1030 ":l+" IF_FEATURE_CROND_D(":d+")
1028 opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), 1031 ,
1029 &G.log_level, &G.log_filename, &G.crontab_dir_name 1032 &G.log_level, &G.log_filename, &G.crontab_dir_name
1030 IF_FEATURE_CROND_D(,&G.log_level)); 1033 IF_FEATURE_CROND_D(,&G.log_level)
1034 );
1031 /* both -d N and -l N set the same variable: G.log_level */ 1035 /* both -d N and -l N set the same variable: G.log_level */
1032 1036
1033 if (!(opts & OPT_f)) { 1037 if (!(opts & OPT_f)) {
diff --git a/miscutils/crontab.c b/miscutils/crontab.c
index 804cb57f2..4787fa08f 100644
--- a/miscutils/crontab.c
+++ b/miscutils/crontab.c
@@ -99,8 +99,9 @@ int crontab_main(int argc UNUSED_PARAM, char **argv)
99 OPT_ler = OPT_l + OPT_e + OPT_r, 99 OPT_ler = OPT_l + OPT_e + OPT_r,
100 }; 100 };
101 101
102 opt_complementary = "?1:dr"; /* max one argument; -d implies -r */ 102 opt_ler = getopt32(argv, "^" "u:c:lerd" "\0" "?1:dr"/*max one arg; -d implies -r*/,
103 opt_ler = getopt32(argv, "u:c:lerd", &user_name, &crontab_dir); 103 &user_name, &crontab_dir
104 );
104 argv += optind; 105 argv += optind;
105 106
106 if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */ 107 if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */
diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c
index 3ddd9dd99..a6ce41f27 100644
--- a/miscutils/flash_eraseall.c
+++ b/miscutils/flash_eraseall.c
@@ -82,8 +82,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
82 unsigned int flags; 82 unsigned int flags;
83 char *mtd_name; 83 char *mtd_name;
84 84
85 opt_complementary = "=1"; 85 flags = getopt32(argv, "^" "jNq" "\0" "=1");
86 flags = getopt32(argv, "jNq");
87 86
88 mtd_name = argv[optind]; 87 mtd_name = argv[optind];
89 fd = xopen(mtd_name, O_RDWR); 88 fd = xopen(mtd_name, O_RDWR);
diff --git a/miscutils/flashcp.c b/miscutils/flashcp.c
index c10b96ee8..858cee194 100644
--- a/miscutils/flashcp.c
+++ b/miscutils/flashcp.c
@@ -69,8 +69,7 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv)
69 RESERVE_CONFIG_UBUFFER(buf, BUFSIZE); 69 RESERVE_CONFIG_UBUFFER(buf, BUFSIZE);
70 RESERVE_CONFIG_UBUFFER(buf2, BUFSIZE); 70 RESERVE_CONFIG_UBUFFER(buf2, BUFSIZE);
71 71
72 opt_complementary = "=2"; /* exactly 2 non-option args: file, dev */ 72 /*opts =*/ getopt32(argv, "^" "v" "\0" "=2"/*exactly 2 non-option args: file,dev*/);
73 /*opts =*/ getopt32(argv, "v");
74 argv += optind; 73 argv += optind;
75// filename = *argv++; 74// filename = *argv++;
76// devicename = *argv; 75// devicename = *argv;
diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c
index 8d04d2259..30f606e8e 100644
--- a/miscutils/i2c_tools.c
+++ b/miscutils/i2c_tools.c
@@ -455,14 +455,12 @@ int i2cget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
455int i2cget_main(int argc UNUSED_PARAM, char **argv) 455int i2cget_main(int argc UNUSED_PARAM, char **argv)
456{ 456{
457 const unsigned opt_f = (1 << 0), opt_y = (1 << 1); 457 const unsigned opt_f = (1 << 0), opt_y = (1 << 1);
458 const char *const optstr = "fy";
459 458
460 int bus_num, bus_addr, data_addr = -1, status; 459 int bus_num, bus_addr, data_addr = -1, status;
461 int mode = I2C_SMBUS_BYTE, pec = 0, fd; 460 int mode = I2C_SMBUS_BYTE, pec = 0, fd;
462 unsigned opts; 461 unsigned opts;
463 462
464 opt_complementary = "-2:?4"; /* from 2 to 4 args */ 463 opts = getopt32(argv, "^" "fy" "\0" "-2:?4"/*from 2 to 4 args*/);
465 opts = getopt32(argv, optstr);
466 argv += optind; 464 argv += optind;
467 465
468 bus_num = i2c_bus_lookup(argv[0]); 466 bus_num = i2c_bus_lookup(argv[0]);
@@ -544,7 +542,6 @@ int i2cset_main(int argc, char **argv)
544{ 542{
545 const unsigned opt_f = (1 << 0), opt_y = (1 << 1), 543 const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
546 opt_m = (1 << 2), opt_r = (1 << 3); 544 opt_m = (1 << 2), opt_r = (1 << 3);
547 const char *const optstr = "fym:r";
548 545
549 int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0; 546 int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0;
550 int val, blen = 0, mask = 0, fd, status; 547 int val, blen = 0, mask = 0, fd, status;
@@ -552,8 +549,7 @@ int i2cset_main(int argc, char **argv)
552 char *opt_m_arg = NULL; 549 char *opt_m_arg = NULL;
553 unsigned opts; 550 unsigned opts;
554 551
555 opt_complementary = "-3"; /* from 3 to ? args */ 552 opts = getopt32(argv, "^" "fym:r" "\0" "-3"/*from 3 to ? args*/, &opt_m_arg);
556 opts = getopt32(argv, optstr, &opt_m_arg);
557 argv += optind; 553 argv += optind;
558 argc -= optind; 554 argc -= optind;
559 555
@@ -905,7 +901,6 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
905{ 901{
906 const unsigned opt_f = (1 << 0), opt_y = (1 << 1), 902 const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
907 opt_r = (1 << 2); 903 opt_r = (1 << 2);
908 const char *const optstr = "fyr:";
909 904
910 int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0; 905 int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0;
911 unsigned first = 0x00, last = 0xff, opts; 906 unsigned first = 0x00, last = 0xff, opts;
@@ -913,8 +908,11 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
913 char *opt_r_str, *dash; 908 char *opt_r_str, *dash;
914 int fd, res; 909 int fd, res;
915 910
916 opt_complementary = "-2:?3"; /* from 2 to 3 args */ 911 opts = getopt32(argv, "^"
917 opts = getopt32(argv, optstr, &opt_r_str); 912 "fyr:"
913 "\0" "-2:?3" /* from 2 to 3 args */,
914 &opt_r_str
915 );
918 argv += optind; 916 argv += optind;
919 917
920 bus_num = i2c_bus_lookup(argv[0]); 918 bus_num = i2c_bus_lookup(argv[0]);
@@ -1208,15 +1206,16 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv)
1208 const unsigned opt_y = (1 << 0), opt_a = (1 << 1), 1206 const unsigned opt_y = (1 << 0), opt_a = (1 << 1),
1209 opt_q = (1 << 2), opt_r = (1 << 3), 1207 opt_q = (1 << 2), opt_r = (1 << 3),
1210 opt_F = (1 << 4), opt_l = (1 << 5); 1208 opt_F = (1 << 4), opt_l = (1 << 5);
1211 const char *const optstr = "yaqrFl";
1212 1209
1213 int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status, cmd; 1210 int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status, cmd;
1214 unsigned first = 0x03, last = 0x77, opts; 1211 unsigned first = 0x03, last = 0x77, opts;
1215 unsigned long funcs; 1212 unsigned long funcs;
1216 1213
1217 opt_complementary = "q--r:r--q:" /* mutually exclusive */ 1214 opts = getopt32(argv, "^"
1218 "?3"; /* up to 3 args */ 1215 "yaqrFl"
1219 opts = getopt32(argv, optstr); 1216 "\0"
1217 "q--r:r--q:"/*mutually exclusive*/ "?3"/*up to 3 args*/
1218 );
1220 argv += optind; 1219 argv += optind;
1221 1220
1222 if (opts & opt_l) 1221 if (opts & opt_l)
diff --git a/miscutils/makedevs.c b/miscutils/makedevs.c
index c13ad1442..80975c652 100644
--- a/miscutils/makedevs.c
+++ b/miscutils/makedevs.c
@@ -183,8 +183,7 @@ int makedevs_main(int argc UNUSED_PARAM, char **argv)
183 char *line = (char *)"-"; 183 char *line = (char *)"-";
184 int ret = EXIT_SUCCESS; 184 int ret = EXIT_SUCCESS;
185 185
186 opt_complementary = "=1"; /* exactly one param */ 186 getopt32(argv, "^" "d:" "\0" "=1", &line);
187 getopt32(argv, "d:", &line);
188 argv += optind; 187 argv += optind;
189 188
190 xchdir(*argv); /* ensure root dir exists */ 189 xchdir(*argv); /* ensure root dir exists */
diff --git a/miscutils/man.c b/miscutils/man.c
index a16202f25..ba6bb4c01 100644
--- a/miscutils/man.c
+++ b/miscutils/man.c
@@ -253,8 +253,7 @@ int man_main(int argc UNUSED_PARAM, char **argv)
253 253
254 INIT_G(); 254 INIT_G();
255 255
256 opt_complementary = "-1"; /* at least one argument */ 256 opt = getopt32(argv, "^+" "aw" "\0" "-1"/*at least one arg*/);
257 opt = getopt32(argv, "+aw");
258 argv += optind; 257 argv += optind;
259 258
260 sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9"); 259 sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9");
diff --git a/miscutils/microcom.c b/miscutils/microcom.c
index f382edebb..b87f3273f 100644
--- a/miscutils/microcom.c
+++ b/miscutils/microcom.c
@@ -74,8 +74,9 @@ int microcom_main(int argc UNUSED_PARAM, char **argv)
74 unsigned opts; 74 unsigned opts;
75 75
76 // fetch options 76 // fetch options
77 opt_complementary = "=1"; 77 opts = getopt32(argv, "^" "Xs:+d:+t:+" "\0" "=1",
78 opts = getopt32(argv, "Xs:+d:+t:+", &speed, &delay, &timeout); 78 &speed, &delay, &timeout
79 );
79// argc -= optind; 80// argc -= optind;
80 argv += optind; 81 argv += optind;
81 82
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c
index 5986ab272..80a005821 100644
--- a/miscutils/nandwrite.c
+++ b/miscutils/nandwrite.c
@@ -123,13 +123,12 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv)
123 const char *opt_s = "0", *opt_f = "-", *opt_l, *opt_bb; 123 const char *opt_s = "0", *opt_f = "-", *opt_l, *opt_bb;
124 124
125 if (IS_NANDDUMP) { 125 if (IS_NANDDUMP) {
126 opt_complementary = "=1"; 126 opts = getopt32long(argv, "^" "ons:f:l:" "\0" "=1",
127 opts = getopt32long(argv, "ons:f:l:",
128 "bb\0" Required_argument "\xff", /* no short equivalent */ 127 "bb\0" Required_argument "\xff", /* no short equivalent */
129 &opt_s, &opt_f, &opt_l, &opt_bb); 128 &opt_s, &opt_f, &opt_l, &opt_bb
129 );
130 } else { /* nandwrite */ 130 } else { /* nandwrite */
131 opt_complementary = "-1:?2"; 131 opts = getopt32(argv, "^" "pns:" "\0" "-1:?2", &opt_s);
132 opts = getopt32(argv, "pns:", &opt_s);
133 } 132 }
134 argv += optind; 133 argv += optind;
135 134
diff --git a/miscutils/setserial.c b/miscutils/setserial.c
index 2000de7b1..f217c3beb 100644
--- a/miscutils/setserial.c
+++ b/miscutils/setserial.c
@@ -742,8 +742,7 @@ int setserial_main(int argc UNUSED_PARAM, char **argv)
742{ 742{
743 int opts; 743 int opts;
744 744
745 opt_complementary = "-1:b-aG:G-ab:a-bG"; 745 opts = getopt32(argv, "^" "bGavzgq" "\0" "-1:b-aG:G-ab:a-bG");
746 opts = getopt32(argv, "bGavzgq");
747 argv += optind; 746 argv += optind;
748 747
749 if (!argv[1]) /* one arg only? (nothing to change?) */ 748 if (!argv[1]) /* one arg only? (nothing to change?) */
diff --git a/miscutils/time.c b/miscutils/time.c
index 0ecdac1a6..65dbcdcf3 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -430,9 +430,10 @@ int time_main(int argc UNUSED_PARAM, char **argv)
430 OPT_f = (1 << 4), 430 OPT_f = (1 << 4),
431 }; 431 };
432 432
433 opt_complementary = "-1"; /* at least one arg */
434 /* "+": stop on first non-option */ 433 /* "+": stop on first non-option */
435 opt = getopt32(argv, "+vpao:f:", &output_filename, &output_format); 434 opt = getopt32(argv, "^+" "vpao:f:" "\0" "-1"/*at least one arg*/,
435 &output_filename, &output_format
436 );
436 argv += optind; 437 argv += optind;
437 if (opt & OPT_v) 438 if (opt & OPT_v)
438 output_format = long_format; 439 output_format = long_format;
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c
index 123551e94..d142d1144 100644
--- a/miscutils/ubi_tools.c
+++ b/miscutils/ubi_tools.c
@@ -145,20 +145,17 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
145#define OPTION_a (1 << 5) 145#define OPTION_a (1 << 5)
146#define OPTION_t (1 << 6) 146#define OPTION_t (1 << 6)
147 if (do_mkvol) { 147 if (do_mkvol) {
148 opt_complementary = "-1"; 148 opts = getopt32(argv, "^" "md:+n:+N:s:a:+t:O:+" "\0" "-1",
149 opts = getopt32(argv, "md:+n:+N:s:a:+t:O:+",
150 &dev_num, &vol_id, 149 &dev_num, &vol_id,
151 &vol_name, &size_bytes_str, &alignment, &type, 150 &vol_name, &size_bytes_str, &alignment, &type,
152 &vid_hdr_offset 151 &vid_hdr_offset
153 ); 152 );
154 } else 153 } else
155 if (do_update) { 154 if (do_update) {
156 opt_complementary = "-1"; 155 opts = getopt32(argv, "^" "s:at" "\0" "-1", &size_bytes_str);
157 opts = getopt32(argv, "s:at", &size_bytes_str);
158 opts *= OPTION_s; 156 opts *= OPTION_s;
159 } else { 157 } else {
160 opt_complementary = "-1"; 158 opts = getopt32(argv, "^" "m:+d:+n:+N:s:a:+t:" "\0" "-1",
161 opts = getopt32(argv, "m:+d:+n:+N:s:a:+t:",
162 &mtd_num, &dev_num, &vol_id, 159 &mtd_num, &dev_num, &vol_id,
163 &vol_name, &size_bytes_str, &alignment, &type 160 &vol_name, &size_bytes_str, &alignment, &type
164 ); 161 );
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index ec06bcb51..392d05646 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -101,8 +101,9 @@ int watchdog_main(int argc UNUSED_PARAM, char **argv)
101 char *st_arg; 101 char *st_arg;
102 char *ht_arg; 102 char *ht_arg;
103 103
104 opt_complementary = "=1"; /* must have exactly 1 argument */ 104 opts = getopt32(argv, "^" "Ft:T:" "\0" "=1"/*must have exactly 1 arg*/,
105 opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg); 105 &st_arg, &ht_arg
106 );
106 107
107 /* We need to daemonize *before* opening the watchdog as many drivers 108 /* We need to daemonize *before* opening the watchdog as many drivers
108 * will only allow one process at a time to do so. Since daemonizing 109 * will only allow one process at a time to do so. Since daemonizing
diff --git a/modutils/modinfo.c b/modutils/modinfo.c
index 0f1d3ee47..3f91622a9 100644
--- a/modutils/modinfo.c
+++ b/modutils/modinfo.c
@@ -148,8 +148,7 @@ int modinfo_main(int argc UNUSED_PARAM, char **argv)
148 unsigned i; 148 unsigned i;
149 149
150 field = NULL; 150 field = NULL;
151 opt_complementary = "-1"; /* minimum one param */ 151 opts = getopt32(argv, "^" "0F:nadlp" "\0" "-1"/*minimum one arg*/, &field);
152 opts = getopt32(argv, "0F:nadlp", &field);
153 /* If no field selected, show all */ 152 /* If no field selected, show all */
154 if (!(opts & (OPT_TAGS|OPT_F))) 153 if (!(opts & (OPT_TAGS|OPT_F)))
155 option_mask32 |= OPT_TAGS; 154 option_mask32 |= OPT_TAGS;
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c
index cd4f554f3..a94b0b9a6 100644
--- a/modutils/modprobe-small.c
+++ b/modutils/modprobe-small.c
@@ -988,10 +988,9 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
988 988
989#if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD 989#if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD
990 /* modprobe, insmod, rmmod require at least one argument */ 990 /* modprobe, insmod, rmmod require at least one argument */
991 opt_complementary = "-1";
992 /* only -q (quiet) and -r (rmmod), 991 /* only -q (quiet) and -r (rmmod),
993 * the rest are accepted and ignored (compat) */ 992 * the rest are accepted and ignored (compat) */
994 getopt32(argv, "qrfsvwb"); 993 getopt32(argv, "^" "qrfsvwb" "\0" "-1");
995 argv += optind; 994 argv += optind;
996 995
997 if (is_modprobe) { 996 if (is_modprobe) {
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index 2dac8a895..59f6d54f3 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -133,7 +133,7 @@
133 */ 133 */
134#define MODPROBE_OPTS "alrDb" 134#define MODPROBE_OPTS "alrDb"
135/* -a and -D _are_ in fact compatible */ 135/* -a and -D _are_ in fact compatible */
136#define MODPROBE_COMPLEMENTARY ("q-v:v-q:l--arD:r--alD:a--lr:D--rl") 136#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--arD:r--alD:a--lr:D--rl"
137//#define MODPROBE_OPTS "acd:lnrt:C:b" 137//#define MODPROBE_OPTS "acd:lnrt:C:b"
138//#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--acr:a--lr:r--al" 138//#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--acr:a--lr:r--al"
139enum { 139enum {
@@ -566,8 +566,10 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
566 566
567 INIT_G(); 567 INIT_G();
568 568
569 opt_complementary = MODPROBE_COMPLEMENTARY; 569 opt = getopt32long(argv, "^" INSMOD_OPTS MODPROBE_OPTS "\0" MODPROBE_COMPLEMENTARY,
570 opt = getopt32long(argv, INSMOD_OPTS MODPROBE_OPTS, modprobe_longopts INSMOD_ARGS); 570 modprobe_longopts
571 INSMOD_ARGS
572 );
571 argv += optind; 573 argv += optind;
572 574
573 /* Goto modules location */ 575 /* Goto modules location */
diff --git a/networking/arping.c b/networking/arping.c
index 3fd54a287..f9967d81e 100644
--- a/networking/arping.c
+++ b/networking/arping.c
@@ -306,9 +306,9 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
306 /* Dad also sets quit_on_reply. 306 /* Dad also sets quit_on_reply.
307 * Advert also sets unsolicited. 307 * Advert also sets unsolicited.
308 */ 308 */
309 opt_complementary = "=1:Df:AU"; 309 opt = getopt32(argv, "^" "DUAqfbc:+w:I:s:" "\0" "=1:Df:AU",
310 opt = getopt32(argv, "DUAqfbc:+w:I:s:", 310 &count, &str_timeout, &device, &source
311 &count, &str_timeout, &device, &source); 311 );
312 if (opt & 0x80) /* -w: timeout */ 312 if (opt & 0x80) /* -w: timeout */
313 timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; 313 timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000;
314 //if (opt & 0x200) /* -s: source */ 314 //if (opt & 0x200) /* -s: source */
diff --git a/networking/ether-wake.c b/networking/ether-wake.c
index 52522e76d..6677f07d5 100644
--- a/networking/ether-wake.c
+++ b/networking/ether-wake.c
@@ -212,8 +212,7 @@ int ether_wake_main(int argc UNUSED_PARAM, char **argv)
212 struct whereto_t whereto; /* who to wake up */ 212 struct whereto_t whereto; /* who to wake up */
213 213
214 /* handle misc user options */ 214 /* handle misc user options */
215 opt_complementary = "=1"; 215 flags = getopt32(argv, "^" "bi:p:" "\0" "=1", &ifname, &pass);
216 flags = getopt32(argv, "bi:p:", &ifname, &pass);
217 if (flags & 4) /* -p */ 216 if (flags & 4) /* -p */
218 wol_passwd_sz = get_wol_pw(pass, wol_passwd); 217 wol_passwd_sz = get_wol_pw(pass, wol_passwd);
219 flags &= 1; /* we further interested only in -b [bcast] flag */ 218 flags &= 1; /* we further interested only in -b [bcast] flag */
diff --git a/networking/ftpd.c b/networking/ftpd.c
index c562c2886..8af5acac2 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -1174,17 +1174,20 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
1174 abs_timeout = 1 * 60 * 60; 1174 abs_timeout = 1 * 60 * 60;
1175 verbose_S = 0; 1175 verbose_S = 0;
1176 G.timeout = 2 * 60; 1176 G.timeout = 2 * 60;
1177 opt_complementary = "vv:SS";
1178#if BB_MMU 1177#if BB_MMU
1179 opts = getopt32(argv, "vS" 1178 opts = getopt32(argv, "^" "vS"
1180 IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:"), 1179 IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:")
1180 "\0" "vv:SS",
1181 &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,) 1181 &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,)
1182 &G.verbose, &verbose_S); 1182 &G.verbose, &verbose_S
1183 );
1183#else 1184#else
1184 opts = getopt32(argv, "l1AvS" 1185 opts = getopt32(argv, "^" "l1AvS"
1185 IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:"), 1186 IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:")
1187 "\0" "vv:SS",
1186 &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,) 1188 &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,)
1187 &G.verbose, &verbose_S); 1189 &G.verbose, &verbose_S
1190 );
1188 if (opts & (OPT_l|OPT_1)) { 1191 if (opts & (OPT_l|OPT_1)) {
1189 /* Our secret backdoor to ls */ 1192 /* Our secret backdoor to ls */
1190 if (fchdir(3) != 0) 1193 if (fchdir(3) != 0)
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c
index 1fc20364f..2cce07ac2 100644
--- a/networking/ftpgetput.c
+++ b/networking/ftpgetput.c
@@ -361,11 +361,12 @@ int ftpgetput_main(int argc UNUSED_PARAM, char **argv)
361 /* 361 /*
362 * Decipher the command line 362 * Decipher the command line
363 */ 363 */
364 opt_complementary = "-2:vv:cc"; /* must have 2 to 3 params; -v and -c count */ 364 /* must have 2 to 3 params; -v and -c count */
365#define OPTSTRING "^cvu:p:P:" "\0" "-2:?3:vv:cc"
365#if ENABLE_FEATURE_FTPGETPUT_LONG_OPTIONS 366#if ENABLE_FEATURE_FTPGETPUT_LONG_OPTIONS
366 getopt32long(argv, "cvu:p:P:", ftpgetput_longopts, 367 getopt32long(argv, OPTSTRING, ftpgetput_longopts,
367#else 368#else
368 getopt32(argv, "cvu:p:P:", 369 getopt32(argv, OPTSTRING,
369#endif 370#endif
370 &user, &password, &port, &verbose_flag, &do_continue 371 &user, &password, &port, &verbose_flag, &do_continue
371 ); 372 );
diff --git a/networking/httpd.c b/networking/httpd.c
index 079145757..9369de824 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -2636,17 +2636,19 @@ int httpd_main(int argc UNUSED_PARAM, char **argv)
2636#endif 2636#endif
2637 2637
2638 home_httpd = xrealloc_getcwd_or_warn(NULL); 2638 home_httpd = xrealloc_getcwd_or_warn(NULL);
2639 /* -v counts, -i implies -f */
2640 opt_complementary = "vv:if";
2641 /* We do not "absolutize" path given by -h (home) opt. 2639 /* We do not "absolutize" path given by -h (home) opt.
2642 * If user gives relative path in -h, 2640 * If user gives relative path in -h,
2643 * $SCRIPT_FILENAME will not be set. */ 2641 * $SCRIPT_FILENAME will not be set. */
2644 opt = getopt32(argv, "c:d:h:" 2642 opt = getopt32(argv, "^"
2643 "c:d:h:"
2645 IF_FEATURE_HTTPD_ENCODE_URL_STR("e:") 2644 IF_FEATURE_HTTPD_ENCODE_URL_STR("e:")
2646 IF_FEATURE_HTTPD_BASIC_AUTH("r:") 2645 IF_FEATURE_HTTPD_BASIC_AUTH("r:")
2647 IF_FEATURE_HTTPD_AUTH_MD5("m:") 2646 IF_FEATURE_HTTPD_AUTH_MD5("m:")
2648 IF_FEATURE_HTTPD_SETUID("u:") 2647 IF_FEATURE_HTTPD_SETUID("u:")
2649 "p:ifv", 2648 "p:ifv"
2649 "\0"
2650 /* -v counts, -i implies -f */
2651 "vv:if",
2650 &opt_c_configFile, &url_for_decode, &home_httpd 2652 &opt_c_configFile, &url_for_decode, &home_httpd
2651 IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) 2653 IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode)
2652 IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) 2654 IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm)
diff --git a/networking/ipcalc.c b/networking/ipcalc.c
index 1d5db969c..cdae8eea8 100644
--- a/networking/ipcalc.c
+++ b/networking/ipcalc.c
@@ -130,8 +130,11 @@ int ipcalc_main(int argc UNUSED_PARAM, char **argv)
130#define ipaddr (s_ipaddr.s_addr) 130#define ipaddr (s_ipaddr.s_addr)
131 char *ipstr; 131 char *ipstr;
132 132
133 opt_complementary = "-1:?2"; /* minimum 1 arg, maximum 2 args */ 133 opt = GETOPT32(argv, "^"
134 opt = GETOPT32(argv, "mbn" IF_FEATURE_IPCALC_FANCY("phs") LONGOPTS); 134 "mbn" IF_FEATURE_IPCALC_FANCY("phs")
135 "\0" "-1:?2"/*min 1, max 2 args*/
136 LONGOPTS
137 );
135 argv += optind; 138 argv += optind;
136 if (opt & SILENT) 139 if (opt & SILENT)
137 logmode = LOGMODE_NONE; /* suppress error_msg() output */ 140 logmode = LOGMODE_NONE; /* suppress error_msg() output */
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c
index 3db784982..64098648a 100644
--- a/networking/nc_bloaty.c
+++ b/networking/nc_bloaty.c
@@ -787,11 +787,15 @@ int nc_main(int argc UNUSED_PARAM, char **argv)
787 e_found: 787 e_found:
788 788
789 // -g -G -t -r deleted, unimplemented -a deleted too 789 // -g -G -t -r deleted, unimplemented -a deleted too
790 opt_complementary = "?2:vv:ll"; /* max 2 params; -v and -l are counters; -w N */ 790 getopt32(argv, "^"
791 getopt32(argv, "np:s:uvw:+" IF_NC_SERVER("lk") 791 "np:s:uvw:+"/* -w N */ IF_NC_SERVER("lk")
792 IF_NC_EXTRA("i:o:z"), 792 IF_NC_EXTRA("i:o:z")
793 &str_p, &str_s, &o_wait 793 "\0"
794 IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l)); 794 "?2:vv:ll", /* max 2 params; -v and -l are counters */
795 &str_p, &str_s, &o_wait
796 IF_NC_EXTRA(, &str_i, &str_o)
797 , &o_verbose IF_NC_SERVER(, &cnt_l)
798 );
795 argv += optind; 799 argv += optind;
796#if ENABLE_NC_EXTRA 800#if ENABLE_NC_EXTRA
797 if (option_mask32 & OPT_i) /* line-interval time */ 801 if (option_mask32 & OPT_i) /* line-interval time */
diff --git a/networking/ntpd.c b/networking/ntpd.c
index f21f9513d..25fa44389 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -2230,15 +2230,16 @@ static NOINLINE void ntp_init(char **argv)
2230 2230
2231 /* Parse options */ 2231 /* Parse options */
2232 peers = NULL; 2232 peers = NULL;
2233 opt_complementary = "dd:wn" /* -d: counter; -p: list; -w implies -n */ 2233 opts = getopt32(argv, "^"
2234 IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */
2235 opts = getopt32(argv,
2236 "nqNx" /* compat */ 2234 "nqNx" /* compat */
2237 "wp:*S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ 2235 "wp:*S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */
2238 IF_FEATURE_NTPD_SERVER("I:") /* compat */ 2236 IF_FEATURE_NTPD_SERVER("I:") /* compat */
2239 "d" /* compat */ 2237 "d" /* compat */
2240 "46aAbgL", /* compat, ignored */ 2238 "46aAbgL", /* compat, ignored */
2241 &peers, &G.script_name, 2239 "\0"
2240 "dd:wn" /* -d: counter; -p: list; -w implies -n */
2241 IF_FEATURE_NTPD_SERVER(":Il") /* -I implies -l */
2242 , &peers, &G.script_name,
2242#if ENABLE_FEATURE_NTPD_SERVER 2243#if ENABLE_FEATURE_NTPD_SERVER
2243 &G.if_name, 2244 &G.if_name,
2244#endif 2245#endif
diff --git a/networking/ping.c b/networking/ping.c
index 2e8bef023..7460e4414 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -340,7 +340,8 @@ static int common_ping_main(sa_family_t af, char **argv)
340 340
341/* Full(er) version */ 341/* Full(er) version */
342 342
343#define OPT_STRING ("qvc:+s:t:+w:+W:+I:np:4" IF_PING6("6")) 343/* -c NUM, -t NUM, -w NUM, -W NUM */
344#define OPT_STRING "qvc:+s:t:+w:+W:+I:np:4"IF_PING6("6")
344enum { 345enum {
345 OPT_QUIET = 1 << 0, 346 OPT_QUIET = 1 << 0,
346 OPT_VERBOSE = 1 << 1, 347 OPT_VERBOSE = 1 << 1,
@@ -863,9 +864,12 @@ static int common_ping_main(int opt, char **argv)
863 864
864 INIT_G(); 865 INIT_G();
865 866
866 /* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */ 867 opt |= getopt32(argv, "^"
867 opt_complementary = "=1:q--v:v--q"; 868 OPT_STRING
868 opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p); 869 /* exactly one arg; -v and -q don't mix */
870 "\0" "=1:q--v:v--q",
871 &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p
872 );
869 if (opt & OPT_s) 873 if (opt & OPT_s)
870 datalen = xatou16(str_s); // -s 874 datalen = xatou16(str_s); // -s
871 if (opt & OPT_I) { // -I 875 if (opt & OPT_I) { // -I
diff --git a/networking/pscan.c b/networking/pscan.c
index 17985d2c8..95b0a937d 100644
--- a/networking/pscan.c
+++ b/networking/pscan.c
@@ -75,8 +75,11 @@ int pscan_main(int argc UNUSED_PARAM, char **argv)
75 unsigned rtt_4; 75 unsigned rtt_4;
76 unsigned start, diff; 76 unsigned start, diff;
77 77
78 opt_complementary = "=1"; /* exactly one non-option */ 78 opt = getopt32(argv, "^"
79 opt = getopt32(argv, "cbp:P:t:T:", &opt_min_port, &opt_max_port, &opt_timeout, &opt_min_rtt); 79 "cbp:P:t:T:"
80 "\0" "=1", /* exactly one non-option */
81 &opt_min_port, &opt_max_port, &opt_timeout, &opt_min_rtt
82 );
80 argv += optind; 83 argv += optind;
81 max_port = xatou_range(opt_max_port, 1, 65535); 84 max_port = xatou_range(opt_max_port, 1, 65535);
82 port = xatou_range(opt_min_port, 1, max_port); 85 port = xatou_range(opt_min_port, 1, max_port);
diff --git a/networking/slattach.c b/networking/slattach.c
index d4659a314..e0a388926 100644
--- a/networking/slattach.c
+++ b/networking/slattach.c
@@ -128,8 +128,9 @@ int slattach_main(int argc UNUSED_PARAM, char **argv)
128 INIT_G(); 128 INIT_G();
129 129
130 /* Parse command line options */ 130 /* Parse command line options */
131 opt_complementary = "=1"; 131 opt = getopt32(argv, "^" "p:s:c:ehmLF" "\0" "=1",
132 opt = getopt32(argv, "p:s:c:ehmLF", &proto, &baud_str, &extcmd); 132 &proto, &baud_str, &extcmd
133 );
133 /*argc -= optind;*/ 134 /*argc -= optind;*/
134 argv += optind; 135 argv += optind;
135 136
diff --git a/networking/tcpudp.c b/networking/tcpudp.c
index 270325164..d4c69e0f7 100644
--- a/networking/tcpudp.c
+++ b/networking/tcpudp.c
@@ -269,10 +269,11 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
269 269
270 tcp = (applet_name[0] == 't'); 270 tcp = (applet_name[0] == 't');
271 271
272 /* 3+ args, -i at most once, -p implies -h, -v is counter, -b N, -c N */
273 opt_complementary = "-3:i--i:ph:vv";
274#ifdef SSLSVD 272#ifdef SSLSVD
275 opts = getopt32(argv, "+c:+C:i:x:u:l:Eb:+hpt:vU:/:Z:K:", 273 opts = getopt32(argv, "^+"
274 "c:+C:i:x:u:l:Eb:+hpt:vU:/:Z:K:" /* -c NUM, -b NUM */
275 /* 3+ args, -i at most once, -p implies -h, -v is a counter */
276 "\0" "-3:i--i:ph:vv",
276 &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname, 277 &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname,
277 &backlog, &str_t, &ssluser, &root, &cert, &key, &verbose 278 &backlog, &str_t, &ssluser, &root, &cert, &key, &verbose
278 ); 279 );
diff --git a/networking/telnetd.c b/networking/telnetd.c
index 16c572e8d..a6bafa21d 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -659,13 +659,15 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv)
659#endif 659#endif
660 INIT_G(); 660 INIT_G();
661 661
662 /* -w NUM, and implies -F. -w and -i don't mix */
663 IF_FEATURE_TELNETD_INETD_WAIT(opt_complementary = "wF:i--w:w--i";)
664 /* Even if !STANDALONE, we accept (and ignore) -i, thus people 662 /* Even if !STANDALONE, we accept (and ignore) -i, thus people
665 * don't need to guess whether it's ok to pass -i to us */ 663 * don't need to guess whether it's ok to pass -i to us */
666 opt = getopt32(argv, "f:l:Ki" 664 opt = getopt32(argv, "^"
665 "f:l:Ki"
667 IF_FEATURE_TELNETD_STANDALONE("p:b:F") 666 IF_FEATURE_TELNETD_STANDALONE("p:b:F")
668 IF_FEATURE_TELNETD_INETD_WAIT("Sw:+"), 667 IF_FEATURE_TELNETD_INETD_WAIT("Sw:+") /* -w NUM */
668 "\0"
669 /* -w implies -F. -w and -i don't mix */
670 IF_FEATURE_TELNETD_INETD_WAIT("wF:i--w:w--i"),
669 &G.issuefile, &G.loginpath 671 &G.issuefile, &G.loginpath
670 IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr) 672 IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr)
671 IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger) 673 IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger)
diff --git a/networking/tftp.c b/networking/tftp.c
index 5baa80448..73a9829aa 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -761,15 +761,16 @@ int tftp_main(int argc UNUSED_PARAM, char **argv)
761 761
762 INIT_G(); 762 INIT_G();
763 763
764 /* -p or -g is mandatory, and they are mutually exclusive */ 764 IF_GETPUT(opt =) getopt32(argv, "^"
765 opt_complementary = "" IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:")
766 IF_GETPUT("g--p:p--g:");
767
768 IF_GETPUT(opt =) getopt32(argv,
769 IF_FEATURE_TFTP_GET("g") IF_FEATURE_TFTP_PUT("p") 765 IF_FEATURE_TFTP_GET("g") IF_FEATURE_TFTP_PUT("p")
770 "l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:"), 766 "l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:")
767 "\0"
768 /* -p or -g is mandatory, and they are mutually exclusive */
769 IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:")
770 IF_GETPUT("g--p:p--g:"),
771 &local_file, &remote_file 771 &local_file, &remote_file
772 IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)); 772 IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)
773 );
773 argv += optind; 774 argv += optind;
774 775
775# if ENABLE_FEATURE_TFTP_BLOCKSIZE 776# if ENABLE_FEATURE_TFTP_BLOCKSIZE
diff --git a/networking/traceroute.c b/networking/traceroute.c
index d9c62f7f9..8b6247482 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -833,9 +833,9 @@ common_traceroute_main(int op, char **argv)
833 833
834 INIT_G(); 834 INIT_G();
835 835
836 /* minimum 1 arg */ 836 op |= getopt32(argv, "^"
837 opt_complementary = "-1:x-x"; 837 OPT_STRING
838 op |= getopt32(argv, OPT_STRING 838 "\0" "-1:x-x" /* minimum 1 arg */
839 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str 839 , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
840 , &source, &waittime_str, &pausemsecs_str, &first_ttl_str 840 , &source, &waittime_str, &pausemsecs_str, &first_ttl_str
841 ); 841 );
diff --git a/networking/tunctl.c b/networking/tunctl.c
index 4c3220025..f2dc645a1 100644
--- a/networking/tunctl.c
+++ b/networking/tunctl.c
@@ -83,10 +83,13 @@ int tunctl_main(int argc UNUSED_PARAM, char **argv)
83#endif 83#endif
84 }; 84 };
85 85
86 opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d 86 opts = getopt32(argv, "^"
87 opts = getopt32(argv, "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b"), 87 "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b")
88 "\0"
89 "=0:t--d:d--t", // no arguments; t ^ d
88 &opt_device, &opt_name, &opt_name 90 &opt_device, &opt_name, &opt_name
89 IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)); 91 IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)
92 );
90 93
91 // select device 94 // select device
92 memset(&ifr, 0, sizeof(ifr)); 95 memset(&ifr, 0, sizeof(ifr));
@@ -153,9 +156,12 @@ int tunctl_main(int argc UNUSED_PARAM, char **argv)
153 OPT_d = 1 << 2, // delete named interface 156 OPT_d = 1 << 2, // delete named interface
154 }; 157 };
155 158
156 opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d 159 opts = getopt32(argv, "^"
157 opts = getopt32(argv, "f:t:d:u:g:b", // u, g, b accepted and ignored 160 "f:t:d:u:g:b" // u, g, b accepted and ignored
158 &opt_device, &opt_name, &opt_name, NULL, NULL); 161 "\0"
162 "=0:t--d:d--t", // no arguments; t ^ d
163 &opt_device, &opt_name, &opt_name, NULL, NULL
164 );
159 165
160 // set interface name 166 // set interface name
161 memset(&ifr, 0, sizeof(ifr)); 167 memset(&ifr, 0, sizeof(ifr));
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 84969aa81..849ca1388 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -1101,13 +1101,14 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1101 client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; 1101 client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
1102 1102
1103 /* Parse command line */ 1103 /* Parse command line */
1104 /* O,x: list; -T,-t,-A take numeric param */ 1104 opt = getopt32long(argv, "^"
1105 IF_UDHCP_VERBOSE(opt_complementary = "vv";) 1105 /* O,x: list; -T,-t,-A take numeric param */
1106 opt = getopt32long(argv, "i:np:qRr:s:T:+t:+SA:+O:*ox:*f" 1106 "i:np:qRr:s:T:+t:+SA:+O:*ox:*f"
1107 USE_FOR_MMU("b") 1107 USE_FOR_MMU("b")
1108 ///IF_FEATURE_UDHCPC_ARPING("a") 1108 ///IF_FEATURE_UDHCPC_ARPING("a")
1109 IF_FEATURE_UDHCP_PORT("P:") 1109 IF_FEATURE_UDHCP_PORT("P:")
1110 "v" 1110 "v"
1111 "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */
1111 , udhcpc6_longopts 1112 , udhcpc6_longopts
1112 , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ 1113 , &client_config.interface, &client_config.pidfile, &str_r /* i,p */
1113 , &client_config.script /* s */ 1114 , &client_config.script /* s */
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 5f87f8586..55e0400b9 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -1295,16 +1295,18 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1295 str_V = "udhcp "BB_VER; 1295 str_V = "udhcp "BB_VER;
1296 1296
1297 /* Parse command line */ 1297 /* Parse command line */
1298 /* O,x: list; -T,-t,-A take numeric param */ 1298 opt = getopt32long(argv, "^"
1299 IF_UDHCP_VERBOSE(opt_complementary = "vv";) 1299 /* O,x: list; -T,-t,-A take numeric param */
1300 opt = getopt32long(argv, "CV:H:h:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB" 1300 "CV:H:h:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB"
1301 USE_FOR_MMU("b") 1301 USE_FOR_MMU("b")
1302 IF_FEATURE_UDHCPC_ARPING("a::") 1302 IF_FEATURE_UDHCPC_ARPING("a::")
1303 IF_FEATURE_UDHCP_PORT("P:") 1303 IF_FEATURE_UDHCP_PORT("P:")
1304 "v" 1304 "v"
1305 "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */
1305 , udhcpc_longopts 1306 , udhcpc_longopts
1306 , &str_V, &str_h, &str_h, &str_F 1307 , &str_V, &str_h, &str_h, &str_F
1307 , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ 1308 , &client_config.interface, &client_config.pidfile /* i,p */
1309 , &str_r /* r */
1308 , &client_config.script /* s */ 1310 , &client_config.script /* s */
1309 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ 1311 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
1310 , &list_O 1312 , &list_O
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 3a5fc2db7..05ddc8649 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -814,11 +814,12 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
814 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) 814 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
815 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) 815 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
816 816
817 opt = getopt32(argv, "^"
818 "fSI:va:"IF_FEATURE_UDHCP_PORT("P:")
819 "\0"
817#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 820#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
818 opt_complementary = "vv"; 821 "vv"
819#endif 822#endif
820 opt = getopt32(argv, "fSI:va:"
821 IF_FEATURE_UDHCP_PORT("P:")
822 , &str_I 823 , &str_I
823 , &str_a 824 , &str_a
824 IF_FEATURE_UDHCP_PORT(, &str_P) 825 IF_FEATURE_UDHCP_PORT(, &str_P)
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c
index fb1860ff6..70d2d1434 100644
--- a/networking/udhcp/dumpleases.c
+++ b/networking/udhcp/dumpleases.c
@@ -54,8 +54,12 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
54#endif 54#endif
55 init_unicode(); 55 init_unicode();
56 56
57 opt_complementary = "=0:a--r:r--a"; 57 opt = getopt32long(argv, "^"
58 opt = getopt32long(argv, "arf:d", dumpleases_longopts, &file); 58 "arf:d"
59 "\0" "=0:a--r:r--a",
60 dumpleases_longopts,
61 &file
62 );
59 63
60 fd = xopen(file, O_RDONLY); 64 fd = xopen(file, O_RDONLY);
61 65
diff --git a/networking/wget.c b/networking/wget.c
index b661f727b..e1b40d3fd 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -1387,9 +1387,8 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0")
1387 1387
1388#if ENABLE_FEATURE_WGET_LONG_OPTIONS 1388#if ENABLE_FEATURE_WGET_LONG_OPTIONS
1389#endif 1389#endif
1390 opt_complementary = "-1" /* at least one URL */ 1390 GETOPT32(argv, "^"
1391 IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ 1391 "cqSO:P:Y:U:T:+"
1392 GETOPT32(argv, "cqSO:P:Y:U:T:+"
1393 /*ignored:*/ "t:" 1392 /*ignored:*/ "t:"
1394 /*ignored:*/ "n::" 1393 /*ignored:*/ "n::"
1395 /* wget has exactly four -n<letter> opts, all of which we can ignore: 1394 /* wget has exactly four -n<letter> opts, all of which we can ignore:
@@ -1400,6 +1399,9 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0")
1400 * "n::" above says that we accept -n[ARG]. 1399 * "n::" above says that we accept -n[ARG].
1401 * Specifying "n:" would be a bug: "-n ARG" would eat ARG! 1400 * Specifying "n:" would be a bug: "-n ARG" would eat ARG!
1402 */ 1401 */
1402 "\0"
1403 "-1" /* at least one URL */
1404 IF_FEATURE_WGET_LONG_OPTIONS(":\xff::") /* --header is a list */
1403 LONGOPTS 1405 LONGOPTS
1404 , &G.fname_out, &G.dir_prefix, 1406 , &G.fname_out, &G.dir_prefix,
1405 &G.proxy_flag, &G.user_agent, 1407 &G.proxy_flag, &G.user_agent,
diff --git a/networking/whois.c b/networking/whois.c
index 0cb7e5411..fd1cdf43e 100644
--- a/networking/whois.c
+++ b/networking/whois.c
@@ -167,8 +167,7 @@ int whois_main(int argc UNUSED_PARAM, char **argv)
167 int port = 43; 167 int port = 43;
168 const char *host = "whois.iana.org"; 168 const char *host = "whois.iana.org";
169 169
170 opt_complementary = "-1"; 170 getopt32(argv, "^" "ih:p:+" "\0" "-1", &host, &port);
171 getopt32(argv, "ih:p:+", &host, &port);
172 argv += optind; 171 argv += optind;
173 172
174 do { 173 do {
diff --git a/networking/zcip.c b/networking/zcip.c
index 94174a165..55440285f 100644
--- a/networking/zcip.c
+++ b/networking/zcip.c
@@ -253,8 +253,9 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
253#define QUIT (opts & 2) 253#define QUIT (opts & 2)
254 // Parse commandline: prog [options] ifname script 254 // Parse commandline: prog [options] ifname script
255 // exactly 2 args; -v accumulates and implies -f 255 // exactly 2 args; -v accumulates and implies -f
256 opt_complementary = "=2:vv:vf"; 256 opts = getopt32(argv, "^" "fqr:l:v" "\0" "=2:vv:vf",
257 opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose); 257 &r_opt, &l_opt, &verbose
258 );
258#if !BB_MMU 259#if !BB_MMU
259 // on NOMMU reexec early (or else we will rerun things twice) 260 // on NOMMU reexec early (or else we will rerun things twice)
260 if (!FOREGROUND) 261 if (!FOREGROUND)
diff --git a/procps/fuser.c b/procps/fuser.c
index 2585a4203..418f57b57 100644
--- a/procps/fuser.c
+++ b/procps/fuser.c
@@ -299,8 +299,7 @@ int fuser_main(int argc UNUSED_PARAM, char **argv)
299 break; 299 break;
300 } 300 }
301 301
302 opt_complementary = "-1"; /* at least one param */ 302 getopt32(argv, "^" OPTION_STRING "\0" "-1"/*at least one arg*/);
303 getopt32(argv, OPTION_STRING);
304 argv += optind; 303 argv += optind;
305 304
306 pp = argv; 305 pp = argv;
diff --git a/procps/iostat.c b/procps/iostat.c
index 608d41364..fbf685568 100644
--- a/procps/iostat.c
+++ b/procps/iostat.c
@@ -418,8 +418,7 @@ int iostat_main(int argc UNUSED_PARAM, char **argv)
418 418
419 /* Parse and process arguments */ 419 /* Parse and process arguments */
420 /* -k and -m are mutually exclusive */ 420 /* -k and -m are mutually exclusive */
421 opt_complementary = "k--m:m--k"; 421 opt = getopt32(argv, "^" "cdtzkm" "\0" "k--m:m--k");
422 opt = getopt32(argv, "cdtzkm");
423 if (!(opt & (OPT_c + OPT_d))) 422 if (!(opt & (OPT_c + OPT_d)))
424 /* Default is -cd */ 423 /* Default is -cd */
425 opt |= OPT_c + OPT_d; 424 opt |= OPT_c + OPT_d;
diff --git a/procps/pmap.c b/procps/pmap.c
index 3dc733974..5c2d1ad59 100644
--- a/procps/pmap.c
+++ b/procps/pmap.c
@@ -96,8 +96,7 @@ int pmap_main(int argc UNUSED_PARAM, char **argv)
96 unsigned opts; 96 unsigned opts;
97 int ret; 97 int ret;
98 98
99 opt_complementary = "-1"; /* min one arg */ 99 opts = getopt32(argv, "^" "xq" "\0" "-1"); /* min one arg */
100 opts = getopt32(argv, "xq");
101 argv += optind; 100 argv += optind;
102 101
103 ret = 0; 102 ret = 0;
diff --git a/procps/ps.c b/procps/ps.c
index afd981313..e004d25bb 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -718,9 +718,11 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
718 /* -w is a bit complicated */ 718 /* -w is a bit complicated */
719 int w_count = 0; 719 int w_count = 0;
720 make_all_argv_opts(argv); 720 make_all_argv_opts(argv);
721 opt_complementary = "ww"; 721 opts = getopt32(argv, "^"
722 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") 722 IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")"w"
723 "w", &w_count); 723 "\0" "ww",
724 &w_count
725 );
724 /* if w is given once, GNU ps sets the width to 132, 726 /* if w is given once, GNU ps sets the width to 132,
725 * if w is given more than once, it is "unlimited" 727 * if w is given more than once, it is "unlimited"
726 */ 728 */
diff --git a/procps/pstree.c b/procps/pstree.c
index 824907997..4fda1c21c 100644
--- a/procps/pstree.c
+++ b/procps/pstree.c
@@ -386,8 +386,7 @@ int pstree_main(int argc UNUSED_PARAM, char **argv)
386 386
387 G.output_width = get_terminal_width(0); 387 G.output_width = get_terminal_width(0);
388 388
389 opt_complementary = "?1"; 389 getopt32(argv, "^" "p" "\0" "?1");
390 getopt32(argv, "p");
391 argv += optind; 390 argv += optind;
392 391
393 if (argv[0]) { 392 if (argv[0]) {
diff --git a/procps/pwdx.c b/procps/pwdx.c
index 84802bbcd..c72cf804a 100644
--- a/procps/pwdx.c
+++ b/procps/pwdx.c
@@ -28,8 +28,7 @@
28int pwdx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 28int pwdx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
29int pwdx_main(int argc UNUSED_PARAM, char **argv) 29int pwdx_main(int argc UNUSED_PARAM, char **argv)
30{ 30{
31 opt_complementary = "-1"; 31 getopt32(argv, "^" "" "\0" "-1");
32 getopt32(argv, "");
33 argv += optind; 32 argv += optind;
34 33
35 do { 34 do {
diff --git a/procps/watch.c b/procps/watch.c
index 2bb7cca90..6fc9f7db7 100644
--- a/procps/watch.c
+++ b/procps/watch.c
@@ -62,9 +62,9 @@ int watch_main(int argc UNUSED_PARAM, char **argv)
62 xopen("/dev/null", O_RDONLY); 62 xopen("/dev/null", O_RDONLY);
63#endif 63#endif
64 64
65 opt_complementary = "-1"; // at least one param; -n NUM 65 // "+": stop at first non-option (procps 3.x only); -n NUM
66 // "+": stop at first non-option (procps 3.x only) 66 // at least one param
67 opt = getopt32(argv, "+dtn:+", &period); 67 opt = getopt32(argv, "^+" "dtn:+" "\0" "-1", &period);
68 argv += optind; 68 argv += optind;
69 69
70 // watch from both procps 2.x and 3.x does concatenation. Example: 70 // watch from both procps 2.x and 3.x does concatenation. Example:
diff --git a/runit/chpst.c b/runit/chpst.c
index c061a91ea..3ecb85cba 100644
--- a/runit/chpst.c
+++ b/runit/chpst.c
@@ -301,9 +301,10 @@ int chpst_main(int argc UNUSED_PARAM, char **argv)
301 // FIXME: can we live with int-sized limits? 301 // FIXME: can we live with int-sized limits?
302 // can we live with 40000 days? 302 // can we live with 40000 days?
303 // if yes -> getopt converts strings to numbers for us 303 // if yes -> getopt converts strings to numbers for us
304 opt_complementary = "-1"; 304 opt = getopt32(argv, "^+"
305 opt = getopt32(argv, "+a:+c:+d:+f:+l:+m:+o:+p:+r:+s:+t:+u:U:e:" 305 "a:+c:+d:+f:+l:+m:+o:+p:+r:+s:+t:+u:U:e:"
306 IF_CHPST("/:n:vP012"), 306 IF_CHPST("/:n:vP012")
307 "\0" "-1",
307 &limita, &limitc, &limitd, &limitf, &limitl, 308 &limita, &limitc, &limitd, &limitf, &limitl,
308 &limitm, &limito, &limitp, &limitr, &limits, &limitt, 309 &limitm, &limito, &limitp, &limitr, &limits, &limitt,
309 &set_user, &set_user, &env_dir 310 &set_user, &set_user, &env_dir
diff --git a/runit/runsvdir.c b/runit/runsvdir.c
index abba2e8e4..11ab40abf 100644
--- a/runit/runsvdir.c
+++ b/runit/runsvdir.c
@@ -248,10 +248,9 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
248 248
249 INIT_G(); 249 INIT_G();
250 250
251 opt_complementary = "-1";
252 opt_s_argv[0] = NULL; 251 opt_s_argv[0] = NULL;
253 opt_s_argv[2] = NULL; 252 opt_s_argv[2] = NULL;
254 getopt32(argv, "Ps:", &opt_s_argv[0]); 253 getopt32(argv, "^" "Ps:" "\0" "-1", &opt_s_argv[0]);
255 argv += optind; 254 argv += optind;
256 255
257 i_am_init = (getpid() == 1); 256 i_am_init = (getpid() == 1);
diff --git a/runit/sv.c b/runit/sv.c
index 477c1ac6e..1d0809be8 100644
--- a/runit/sv.c
+++ b/runit/sv.c
@@ -506,8 +506,9 @@ static int sv(char **argv)
506 x = getenv("SVWAIT"); 506 x = getenv("SVWAIT");
507 if (x) waitsec = xatou(x); 507 if (x) waitsec = xatou(x);
508 508
509 opt_complementary = "vv"; /* -w N, -v is a counter */ 509 getopt32(argv, "^" "w:+v" "\0" "vv" /* -w N, -v is a counter */,
510 getopt32(argv, "w:+v", &waitsec, &verbose); 510 &waitsec, &verbose
511 );
511 argv += optind; 512 argv += optind;
512 action = *argv++; 513 action = *argv++;
513 if (!action || !*argv) bb_show_usage(); 514 if (!action || !*argv) bb_show_usage();
diff --git a/runit/svlogd.c b/runit/svlogd.c
index 831873d86..739483356 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -1037,9 +1037,10 @@ int svlogd_main(int argc, char **argv)
1037 1037
1038 INIT_G(); 1038 INIT_G();
1039 1039
1040 opt_complementary = "tt:vv"; 1040 opt = getopt32(argv, "^"
1041 opt = getopt32(argv, "r:R:l:b:tv", 1041 "r:R:l:b:tv" "\0" "tt:vv",
1042 &r, &replace, &l, &b, &timestamp, &verbose); 1042 &r, &replace, &l, &b, &timestamp, &verbose
1043 );
1043 if (opt & 1) { // -r 1044 if (opt & 1) { // -r
1044 repl = r[0]; 1045 repl = r[0];
1045 if (!repl || r[1]) 1046 if (!repl || r[1])
diff --git a/selinux/chcon.c b/selinux/chcon.c
index 3cf9e928a..e77e9ded5 100644
--- a/selinux/chcon.c
+++ b/selinux/chcon.c
@@ -163,13 +163,16 @@ int chcon_main(int argc UNUSED_PARAM, char **argv)
163 char *fname; 163 char *fname;
164 int i, errors = 0; 164 int i, errors = 0;
165 165
166 opt_complementary = "-1" /* at least 1 param */ 166 getopt32long(argv, "^"
167 ":?" /* error if exclusivity constraints are violated */ 167 "Rchfu:r:t:l:v"
168 "\0"
169 "-1" /* at least 1 arg */
170 ":?" /* error if exclusivity constraints are violated */
168#if ENABLE_LONG_OPTS 171#if ENABLE_LONG_OPTS
169 ":\xff--urtl:u--\xff:r--\xff:t--\xff:l--\xff" 172 ":\xff--urtl:u--\xff:r--\xff:t--\xff:l--\xff"
170#endif 173#endif
171 ":f--v:v--f"; /* 'verbose' and 'quiet' are exclusive */ 174 ":f--v:v--f" /* 'verbose' and 'quiet' are exclusive */
172 getopt32long(argv, "Rchfu:r:t:l:v", chcon_longopts, 175 , chcon_longopts,
173 &user, &role, &type, &range, &reference_file 176 &user, &role, &type, &range, &reference_file
174 ); 177 );
175 argv += optind; 178 argv += optind;
diff --git a/selinux/matchpathcon.c b/selinux/matchpathcon.c
index 3388d0857..e57120d3b 100644
--- a/selinux/matchpathcon.c
+++ b/selinux/matchpathcon.c
@@ -58,9 +58,13 @@ int matchpathcon_main(int argc UNUSED_PARAM, char **argv)
58 unsigned opts; 58 unsigned opts;
59 char *fcontext, *prefix, *path; 59 char *fcontext, *prefix, *path;
60 60
61 opt_complementary = "-1" /* at least one param reqd */ 61 opts = getopt32(argv, "^"
62 ":?:f--p:p--f"; /* mutually exclusive */ 62 "nNf:p:V"
63 opts = getopt32(argv, "nNf:p:V", &fcontext, &prefix); 63 "\0"
64 "-1" /* at least one param reqd */
65 ":?:f--p:p--f" /* mutually exclusive */
66 , &fcontext, &prefix
67 );
64 argv += optind; 68 argv += optind;
65 69
66 if (opts & OPT_NOT_TRANS) { 70 if (opts & OPT_NOT_TRANS) {
diff --git a/selinux/runcon.c b/selinux/runcon.c
index 199da25c6..a5a394427 100644
--- a/selinux/runcon.c
+++ b/selinux/runcon.c
@@ -126,9 +126,12 @@ int runcon_main(int argc UNUSED_PARAM, char **argv)
126 126
127 selinux_or_die(); 127 selinux_or_die();
128 128
129 opt_complementary = "-1"; 129 opts = getopt32long(argv, "^"
130 opts = getopt32long(argv, "r:t:u:l:ch", runcon_longopts, 130 "r:t:u:l:ch"
131 &role, &type, &user, &range); 131 "\0" "-1",
132 runcon_longopts,
133 &role, &type, &user, &range
134 );
132 argv += optind; 135 argv += optind;
133 136
134 if (!(opts & OPTS_CONTEXT_COMPONENT)) { 137 if (!(opts & OPTS_CONTEXT_COMPONENT)) {
diff --git a/selinux/sestatus.c b/selinux/sestatus.c
index daf4b223b..6954aca70 100644
--- a/selinux/sestatus.c
+++ b/selinux/sestatus.c
@@ -167,8 +167,7 @@ int sestatus_main(int argc UNUSED_PARAM, char **argv)
167 const char *pol_path; 167 const char *pol_path;
168 int rc; 168 int rc;
169 169
170 opt_complementary = "?0"; /* no arguments are required. */ 170 opts = getopt32(argv, "^" "vb" "\0" "=0"/*no arguments*/);
171 opts = getopt32(argv, "vb");
172 171
173 /* SELinux status: line */ 172 /* SELinux status: line */
174 rc = is_selinux_enabled(); 173 rc = is_selinux_enabled();
diff --git a/selinux/setfiles.c b/selinux/setfiles.c
index 01106bd67..fca698296 100644
--- a/selinux/setfiles.c
+++ b/selinux/setfiles.c
@@ -610,17 +610,23 @@ int setfiles_main(int argc UNUSED_PARAM, char **argv)
610 610
611 set_matchpathcon_flags(matchpathcon_flags); 611 set_matchpathcon_flags(matchpathcon_flags);
612 612
613 opt_complementary = "vv:v--p:p--v:v--q:q--v";
614 /* Option order must match OPT_x definitions! */ 613 /* Option order must match OPT_x definitions! */
615 if (applet_name[0] == 'r') { /* restorecon */ 614 if (applet_name[0] == 'r') { /* restorecon */
616 flags = getopt32(argv, "de:*f:ilnpqrsvo:FWR", 615 flags = getopt32(argv, "^"
617 &exclude_dir, &input_filename, &out_filename, &verbose); 616 "de:*f:ilnpqrsvo:FWR",
617 "\0" "vv:v--p:p--v:v--q:q--v";
618 &exclude_dir, &input_filename, &out_filename,
619 &verbose
620 );
618 } else { /* setfiles */ 621 } else { /* setfiles */
619 flags = getopt32(argv, "de:*f:ilnpqr:svo:FW" 622 flags = getopt32(argv, "^"
620 IF_FEATURE_SETFILES_CHECK_OPTION("c:"), 623 "de:*f:ilnpqr:svo:FW"
624 IF_FEATURE_SETFILES_CHECK_OPTION("c:"),
625 "\0" "vv:v--p:p--v:v--q:q--v";
621 &exclude_dir, &input_filename, &rootpath, &out_filename, 626 &exclude_dir, &input_filename, &rootpath, &out_filename,
622 IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) 627 IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,)
623 &verbose); 628 &verbose
629 );
624 } 630 }
625 argv += optind; 631 argv += optind;
626 632
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 31730a7f9..2b85234a7 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -1109,8 +1109,7 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv)
1109 INIT_G(); 1109 INIT_G();
1110 1110
1111 /* No non-option params */ 1111 /* No non-option params */
1112 opt_complementary = "=0"; 1112 opts = getopt32(argv, "^"OPTION_STR"\0""=0", OPTION_PARAM);
1113 opts = getopt32(argv, OPTION_STR, OPTION_PARAM);
1114#if ENABLE_FEATURE_REMOTE_LOG 1113#if ENABLE_FEATURE_REMOTE_LOG
1115 while (remoteAddrList) { 1114 while (remoteAddrList) {
1116 remoteHost_t *rh = xzalloc(sizeof(*rh)); 1115 remoteHost_t *rh = xzalloc(sizeof(*rh));
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 3c3811752..4f491fa14 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -264,8 +264,12 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
264 264
265 INIT_G(); 265 INIT_G();
266 266
267 opt_complementary = "df:e--e"; 267 opts = getopt32(argv, "^"
268 opts = getopt32(argv, "c:de:fl:a:M:" IF_FEATURE_PIDFILE("p:") IF_FEATURE_ACPID_COMPAT("g:m:s:S:v"), 268 "c:de:fl:a:M:"
269 IF_FEATURE_PIDFILE("p:")
270 IF_FEATURE_ACPID_COMPAT("g:m:s:S:v")
271 "\0"
272 "df:e--e",
269 &opt_dir, &opt_input, &opt_logfile, &opt_action, &opt_map 273 &opt_dir, &opt_input, &opt_logfile, &opt_action, &opt_map
270 IF_FEATURE_PIDFILE(, &opt_pidfile) 274 IF_FEATURE_PIDFILE(, &opt_pidfile)
271 IF_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL) 275 IF_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL)
diff --git a/util-linux/blkdiscard.c b/util-linux/blkdiscard.c
index 048d39e83..5863f0aab 100644
--- a/util-linux/blkdiscard.c
+++ b/util-linux/blkdiscard.c
@@ -53,8 +53,7 @@ int blkdiscard_main(int argc UNUSED_PARAM, char **argv)
53 OPT_SECURE = (1 << 2), 53 OPT_SECURE = (1 << 2),
54 }; 54 };
55 55
56 opt_complementary = "=1"; 56 opts = getopt32(argv, "^" "o:l:s" "\0" "=1", &offset_str, &length_str);
57 opts = getopt32(argv, "o:l:s", &offset_str, &length_str);
58 argv += optind; 57 argv += optind;
59 58
60 fd = xopen(argv[0], O_RDWR|O_EXCL); 59 fd = xopen(argv[0], O_RDWR|O_EXCL);
diff --git a/util-linux/chrt.c b/util-linux/chrt.c
index 52523df02..2712ea3e3 100644
--- a/util-linux/chrt.c
+++ b/util-linux/chrt.c
@@ -77,8 +77,7 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
77 int policy = SCHED_RR; 77 int policy = SCHED_RR;
78 78
79 /* only one policy accepted */ 79 /* only one policy accepted */
80 opt_complementary = "r--fo:f--ro:o--rf"; 80 opt = getopt32(argv, "^+" "mprfo" "\0" "r--fo:f--ro:o--rf");
81 opt = getopt32(argv, "+mprfo");
82 if (opt & OPT_m) { /* print min/max and exit */ 81 if (opt & OPT_m) { /* print min/max and exit */
83 show_min_max(SCHED_FIFO); 82 show_min_max(SCHED_FIFO);
84 show_min_max(SCHED_RR); 83 show_min_max(SCHED_RR);
diff --git a/util-linux/eject.c b/util-linux/eject.c
index 8095cbef0..6c30facd2 100644
--- a/util-linux/eject.c
+++ b/util-linux/eject.c
@@ -124,8 +124,9 @@ int eject_main(int argc UNUSED_PARAM, char **argv)
124 unsigned flags; 124 unsigned flags;
125 const char *device; 125 const char *device;
126 126
127 opt_complementary = "?1:t--T:T--t"; 127 flags = getopt32(argv, "^" "tT"IF_FEATURE_EJECT_SCSI("s")
128 flags = getopt32(argv, "tT" IF_FEATURE_EJECT_SCSI("s")); 128 "\0" "?1:t--T:T--t"
129 );
129 device = argv[optind] ? argv[optind] : "/dev/cdrom"; 130 device = argv[optind] ? argv[optind] : "/dev/cdrom";
130 131
131 /* We used to do "umount <device>" here, but it was buggy 132 /* We used to do "umount <device>" here, but it was buggy
diff --git a/util-linux/fallocate.c b/util-linux/fallocate.c
index 70e7e178f..1a02a322f 100644
--- a/util-linux/fallocate.c
+++ b/util-linux/fallocate.c
@@ -82,8 +82,7 @@ int fallocate_main(int argc UNUSED_PARAM, char **argv)
82 int fd; 82 int fd;
83 83
84 /* exactly one non-option arg */ 84 /* exactly one non-option arg */
85 opt_complementary = "=1"; 85 opts = getopt32(argv, "^" "l:o:" "\0" "=1", &str_l, &str_o);
86 opts = getopt32(argv, "l:o:", &str_l, &str_o);
87 if (!(opts & 1)) 86 if (!(opts & 1))
88 bb_show_usage(); 87 bb_show_usage();
89 88
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c
index 6faaf1b10..855269c30 100644
--- a/util-linux/fdformat.c
+++ b/util-linux/fdformat.c
@@ -66,8 +66,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv)
66 struct floppy_struct param; 66 struct floppy_struct param;
67 struct format_descr descr; 67 struct format_descr descr;
68 68
69 opt_complementary = "=1"; /* must have 1 param */ 69 verify = !getopt32(argv, "^" "n" "\0" "=1");
70 verify = !getopt32(argv, "n");
71 argv += optind; 70 argv += optind;
72 71
73 xstat(*argv, &st); 72 xstat(*argv, &st);
diff --git a/util-linux/flock.c b/util-linux/flock.c
index 0c9158508..dd0bfd430 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -45,9 +45,8 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
45 "nonblock\0" No_argument "n" 45 "nonblock\0" No_argument "n"
46 ; 46 ;
47#endif 47#endif
48 opt_complementary = "-1";
49 48
50 opt = getopt32long(argv, "+sxnu", flock_longopts); 49 opt = getopt32long(argv, "^+" "sxnu" "\0" "-1", flock_longopts);
51 argv += optind; 50 argv += optind;
52 51
53 if (argv[1]) { 52 if (argv[1]) {
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index 8c2b7d8de..608048983 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -1232,8 +1232,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
1232 1232
1233 INIT_G(); 1233 INIT_G();
1234 1234
1235 opt_complementary = "=1:ar"; /* one argument; -a assumes -r */ 1235 getopt32(argv, "^" OPTION_STR "\0" "=1:ar" /* one arg; -a assumes -r */);
1236 getopt32(argv, OPTION_STR);
1237 argv += optind; 1236 argv += optind;
1238 device_name = argv[0]; 1237 device_name = argv[0];
1239 1238
diff --git a/util-linux/fsfreeze.c b/util-linux/fsfreeze.c
index af715da5e..2e2257337 100644
--- a/util-linux/fsfreeze.c
+++ b/util-linux/fsfreeze.c
@@ -39,8 +39,9 @@ int fsfreeze_main(int argc UNUSED_PARAM, char **argv)
39 /* exactly one non-option arg: the mountpoint */ 39 /* exactly one non-option arg: the mountpoint */
40 /* one of opts is required */ 40 /* one of opts is required */
41 /* opts are mutually exclusive */ 41 /* opts are mutually exclusive */
42 opt_complementary = "=1:""\xff:\xfe:""\xff--\xfe:\xfe--\xff"; 42 opts = getopt32long(argv, "^"
43 opts = getopt32long(argv, "", 43 "" /* no opts */
44 "\0" "=1:""\xff:\xfe:""\xff--\xfe:\xfe--\xff",
44 "freeze\0" No_argument "\xff" 45 "freeze\0" No_argument "\xff"
45 "unfreeze\0" No_argument "\xfe" 46 "unfreeze\0" No_argument "\xfe"
46 ); 47 );
diff --git a/util-linux/fstrim.c b/util-linux/fstrim.c
index 8f0a0538f..4acfa567a 100644
--- a/util-linux/fstrim.c
+++ b/util-linux/fstrim.c
@@ -71,8 +71,9 @@ int fstrim_main(int argc UNUSED_PARAM, char **argv)
71 ; 71 ;
72#endif 72#endif
73 73
74 opt_complementary = "=1"; /* exactly one non-option arg: the mountpoint */ 74 opts = getopt32long(argv, "^" "o:l:m:v" "\0" "=1", fstrim_longopts,
75 opts = getopt32long(argv, "o:l:m:v", fstrim_longopts, &arg_o, &arg_l, &arg_m); 75 &arg_o, &arg_l, &arg_m
76 );
76 77
77 memset(&range, 0, sizeof(range)); 78 memset(&range, 0, sizeof(range));
78 range.len = ULLONG_MAX; 79 range.len = ULLONG_MAX;
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c
index 37e58f2d0..6cf6d0297 100644
--- a/util-linux/hexdump_xxd.c
+++ b/util-linux/hexdump_xxd.c
@@ -73,8 +73,9 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
73#define OPT_s (1 << 1) 73#define OPT_s (1 << 1)
74#define OPT_a (1 << 2) 74#define OPT_a (1 << 2)
75#define OPT_p (1 << 3) 75#define OPT_p (1 << 3)
76 opt_complementary = "?1"; /* 1 argument max */ 76 opt = getopt32(argv, "^" "l:s:apg:+c:+" "\0" "?1" /* 1 argument max */,
77 opt = getopt32(argv, "l:s:apg:+c:+", &opt_l, &opt_s, &bytes, &cols); 77 &opt_l, &opt_s, &bytes, &cols
78 );
78 argv += optind; 79 argv += optind;
79 80
80 dumper->dump_vflag = ALL; 81 dumper->dump_vflag = ALL;
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index 50f83d8c4..29f51021e 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -343,8 +343,11 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
343 /* Initialize "timezone" (libc global variable) */ 343 /* Initialize "timezone" (libc global variable) */
344 tzset(); 344 tzset();
345 345
346 opt_complementary = "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l"; 346 opt = getopt32long(argv,
347 opt = getopt32long(argv, "lurswtf:", hwclock_longopts, &rtcname); 347 "^lurswtf:" "\0" "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l",
348 hwclock_longopts,
349 &rtcname
350 );
348 351
349 /* If -u or -l wasn't given check if we are using utc */ 352 /* If -u or -l wasn't given check if we are using utc */
350 if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) 353 if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME))
diff --git a/util-linux/losetup.c b/util-linux/losetup.c
index 2f7dc10f5..6b171d710 100644
--- a/util-linux/losetup.c
+++ b/util-linux/losetup.c
@@ -57,8 +57,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
57 OPT_r = (1 << 4), /* must be last */ 57 OPT_r = (1 << 4), /* must be last */
58 }; 58 };
59 59
60 opt_complementary = "?2:d--ofar:a--ofr"; 60 opt = getopt32(argv, "^" "do:far" "\0" "?2:d--ofar:a--ofr", &opt_o);
61 opt = getopt32(argv, "do:far", &opt_o);
62 argv += optind; 61 argv += optind;
63 62
64 /* LOOPDEV */ 63 /* LOOPDEV */
diff --git a/util-linux/mkfs_reiser.c b/util-linux/mkfs_reiser.c
index c7d99b018..390aef86c 100644
--- a/util-linux/mkfs_reiser.c
+++ b/util-linux/mkfs_reiser.c
@@ -180,8 +180,7 @@ int mkfs_reiser_main(int argc UNUSED_PARAM, char **argv)
180 180
181 // using global "option_mask32" instead of local "opts": 181 // using global "option_mask32" instead of local "opts":
182 // we are register starved here 182 // we are register starved here
183 opt_complementary = "-1"; 183 /*opts =*/ getopt32(argv, "^" "b:+j:s:o:t:B:h:u:l:fqd" "\0" "-1",
184 /*opts =*/ getopt32(argv, "b:+j:s:o:t:B:h:u:l:fqd",
185 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label); 184 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label);
186 argv += optind; // argv[0] -- device 185 argv += optind; // argv[0] -- device
187 186
diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c
index f9768ed56..426854b1e 100644
--- a/util-linux/mkfs_vfat.c
+++ b/util-linux/mkfs_vfat.c
@@ -269,8 +269,9 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv)
269 OPT_v = 1 << 16, // verbose 269 OPT_v = 1 << 16, // verbose
270 }; 270 };
271 271
272 opt_complementary = "-1";//:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c"; 272 opts = getopt32(argv, "^"
273 opts = getopt32(argv, "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v", 273 "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v"
274 "\0" "-1", //:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c
274 NULL, NULL, NULL, NULL, NULL, 275 NULL, NULL, NULL, NULL, NULL,
275 NULL, NULL, &volume_label, NULL, NULL, NULL, NULL); 276 NULL, NULL, &volume_label, NULL, NULL, NULL, NULL);
276 argv += optind; 277 argv += optind;
diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c
index e44e13c0d..71449882d 100644
--- a/util-linux/mkswap.c
+++ b/util-linux/mkswap.c
@@ -119,9 +119,8 @@ int mkswap_main(int argc UNUSED_PARAM, char **argv)
119 119
120 INIT_G(); 120 INIT_G();
121 121
122 opt_complementary = "-1"; /* at least one param */
123 /* TODO: -p PAGESZ, -U UUID */ 122 /* TODO: -p PAGESZ, -U UUID */
124 getopt32(argv, "L:", &label); 123 getopt32(argv, "^" "L:" "\0" "-1"/*at least one arg*/, &label);
125 argv += optind; 124 argv += optind;
126 125
127 fd = xopen(argv[0], O_WRONLY); 126 fd = xopen(argv[0], O_WRONLY);
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 4d5c2243a..b8dd8a925 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -2205,10 +2205,14 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
2205 2205
2206 // Parse remaining options 2206 // Parse remaining options
2207 // Max 2 params; -o is a list, -v is a counter 2207 // Max 2 params; -o is a list, -v is a counter
2208 opt_complementary = "?2" IF_FEATURE_MOUNT_VERBOSE("vv"); 2208 opt = getopt32(argv, "^"
2209 opt = getopt32(argv, OPTION_STR, &lst_o, &fstype, &O_optmatch 2209 OPTION_STR
2210 IF_FEATURE_MOUNT_OTHERTAB(, &fstabname) 2210 "\0" "?2"IF_FEATURE_MOUNT_VERBOSE("vv"),
2211 IF_FEATURE_MOUNT_VERBOSE(, &verbose)); 2211 &lst_o, &fstype, &O_optmatch
2212 IF_FEATURE_MOUNT_OTHERTAB(, &fstabname)
2213 IF_FEATURE_MOUNT_VERBOSE(, &verbose)
2214 );
2215
2212 while (lst_o) append_mount_options(&cmdopts, llist_pop(&lst_o)); // -o 2216 while (lst_o) append_mount_options(&cmdopts, llist_pop(&lst_o)); // -o
2213 if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r 2217 if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r
2214 if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w 2218 if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w
diff --git a/util-linux/mountpoint.c b/util-linux/mountpoint.c
index 50772533f..6b21a5fb3 100644
--- a/util-linux/mountpoint.c
+++ b/util-linux/mountpoint.c
@@ -43,8 +43,7 @@ int mountpoint_main(int argc UNUSED_PARAM, char **argv)
43 char *arg; 43 char *arg;
44 int rc, opt; 44 int rc, opt;
45 45
46 opt_complementary = "=1"; /* must have one argument */ 46 opt = getopt32(argv, "^" "qdxn" "\0" "=1");
47 opt = getopt32(argv, "qdxn");
48#define OPT_q (1) 47#define OPT_q (1)
49#define OPT_d (2) 48#define OPT_d (2)
50#define OPT_x (4) 49#define OPT_x (4)
diff --git a/util-linux/rdate.c b/util-linux/rdate.c
index 14ce591e9..f27294e25 100644
--- a/util-linux/rdate.c
+++ b/util-linux/rdate.c
@@ -81,8 +81,7 @@ int rdate_main(int argc UNUSED_PARAM, char **argv)
81 time_t remote_time; 81 time_t remote_time;
82 unsigned flags; 82 unsigned flags;
83 83
84 opt_complementary = "-1"; 84 flags = getopt32(argv, "^" "sp" "\0" "-1");
85 flags = getopt32(argv, "sp");
86 85
87 remote_time = askremotedate(argv[optind]); 86 remote_time = askremotedate(argv[optind]);
88 87
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c
index 2a3d61f21..8ffa4f3a6 100644
--- a/util-linux/rtcwake.c
+++ b/util-linux/rtcwake.c
@@ -155,9 +155,9 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
155 "time\0" Required_argument "t" 155 "time\0" Required_argument "t"
156 ; 156 ;
157#endif 157#endif
158 /* Must have -s or -t, exclusive */ 158 opt = getopt32long(argv,
159 opt_complementary = "s:t:s--t:t--s"; 159 /* Must have -s or -t, exclusive */
160 opt = getopt32long(argv, "alud:m:s:t:", rtcwake_longopts, 160 "^alud:m:s:t:" "\0" "s:t:s--t:t--s", rtcwake_longopts,
161 &rtcname, &suspend, &opt_seconds, &opt_time); 161 &rtcname, &suspend, &opt_seconds, &opt_time);
162 162
163 /* this is the default 163 /* this is the default
diff --git a/util-linux/script.c b/util-linux/script.c
index 8174c65bf..aac77c3ba 100644
--- a/util-linux/script.c
+++ b/util-linux/script.c
@@ -80,8 +80,10 @@ int script_main(int argc UNUSED_PARAM, char **argv)
80 ; 80 ;
81#endif 81#endif
82 82
83 opt_complementary = "?1"; /* max one arg */ 83 opt = getopt32long(argv, "^" "ac:fqt::" "\0" "?1"/* max one arg */,
84 opt = getopt32long(argv, "ac:fqt::", script_longopts, &shell_arg, &str_t); 84 script_longopts,
85 &shell_arg, &str_t
86 );
85 //argc -= optind; 87 //argc -= optind;
86 argv += optind; 88 argv += optind;
87 if (argv[0]) { 89 if (argv[0]) {
diff --git a/util-linux/setsid.c b/util-linux/setsid.c
index 60cab2fcf..8385a9115 100644
--- a/util-linux/setsid.c
+++ b/util-linux/setsid.c
@@ -37,8 +37,8 @@ int setsid_main(int argc UNUSED_PARAM, char **argv)
37{ 37{
38 unsigned opt; 38 unsigned opt;
39 39
40 opt_complementary = "-1"; /* at least one arg */ 40 /* +: stop on first non-opt */
41 opt = getopt32(argv, "+c"); /* +: stop on first non-opt */ 41 opt = getopt32(argv, "^+" "c" "\0" "-1"/* at least one arg */);
42 argv += optind; 42 argv += optind;
43 43
44 /* setsid() is allowed only when we are not a process group leader. 44 /* setsid() is allowed only when we are not a process group leader.
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c
index 32708934e..fb6057a02 100644
--- a/util-linux/switch_root.c
+++ b/util-linux/switch_root.c
@@ -97,9 +97,8 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv)
97 struct statfs stfs; 97 struct statfs stfs;
98 dev_t rootdev; 98 dev_t rootdev;
99 99
100 // Parse args (-c console) 100 // Parse args (-c console). '+': stop at first non-option
101 opt_complementary = "-2"; // minimum 2 params 101 getopt32(argv, "^+" "c:" "\0" "-2" /* minimum 2 args */, &console);
102 getopt32(argv, "+c:", &console); // '+': stop at first non-option
103 argv += optind; 102 argv += optind;
104 newroot = *argv++; 103 newroot = *argv++;
105 104
diff --git a/util-linux/taskset.c b/util-linux/taskset.c
index 89dea176e..401a1bcb7 100644
--- a/util-linux/taskset.c
+++ b/util-linux/taskset.c
@@ -123,8 +123,7 @@ int taskset_main(int argc UNUSED_PARAM, char **argv)
123 * Indeed, util-linux-2.13-pre7 uses: 123 * Indeed, util-linux-2.13-pre7 uses:
124 * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ 124 * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */
125 125
126 opt_complementary = "-1"; /* at least 1 arg */ 126 opt_p = getopt32(argv, "^+" "p" "\0" "-1" /* at least 1 arg */);
127 opt_p = getopt32(argv, "+p");
128 argv += optind; 127 argv += optind;
129 128
130 aff = *argv++; 129 aff = *argv++;
diff --git a/util-linux/unshare.c b/util-linux/unshare.c
index df377478f..6a3da9f91 100644
--- a/util-linux/unshare.c
+++ b/util-linux/unshare.c
@@ -137,7 +137,7 @@ static const struct namespace_descr ns_list[] = {
137 * we are forced to use "fake" letters for them. 137 * we are forced to use "fake" letters for them.
138 * '+': stop at first non-option. 138 * '+': stop at first non-option.
139 */ 139 */
140static const char opt_str[] ALIGN1 = "+muinpU""fr""\xfd::""\xfe:""\xff:"; 140#define OPT_STR "+muinpU""fr""\xfd::""\xfe:""\xff:"
141static const char unshare_longopts[] ALIGN1 = 141static const char unshare_longopts[] ALIGN1 =
142 "mount\0" Optional_argument "\xf0" 142 "mount\0" Optional_argument "\xf0"
143 "uts\0" Optional_argument "\xf1" 143 "uts\0" Optional_argument "\xf1"
@@ -210,7 +210,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv)
210 prop_str = PRIVATE_STR; 210 prop_str = PRIVATE_STR;
211 setgrp_str = NULL; 211 setgrp_str = NULL;
212 212
213 opt_complementary = 213 opts = getopt32long(argv, "^" OPT_STR "\0"
214 "\xf0""m" /* long opts (via their "fake chars") imply short opts */ 214 "\xf0""m" /* long opts (via their "fake chars") imply short opts */
215 ":\xf1""u" 215 ":\xf1""u"
216 ":\xf2""i" 216 ":\xf2""i"
@@ -219,15 +219,14 @@ int unshare_main(int argc UNUSED_PARAM, char **argv)
219 ":\xf5""U" 219 ":\xf5""U"
220 ":ru" /* --map-root-user or -r implies -u */ 220 ":ru" /* --map-root-user or -r implies -u */
221 ":\xfd""m" /* --mount-proc implies -m */ 221 ":\xfd""m" /* --mount-proc implies -m */
222 ; 222 , unshare_longopts,
223 opts = getopt32long(argv, opt_str, unshare_longopts, 223 &proc_mnt_target, &prop_str, &setgrp_str,
224 &proc_mnt_target, &prop_str, &setgrp_str, 224 &ns_ctx_list[NS_MNT_POS].path,
225 &ns_ctx_list[NS_MNT_POS].path, 225 &ns_ctx_list[NS_UTS_POS].path,
226 &ns_ctx_list[NS_UTS_POS].path, 226 &ns_ctx_list[NS_IPC_POS].path,
227 &ns_ctx_list[NS_IPC_POS].path, 227 &ns_ctx_list[NS_NET_POS].path,
228 &ns_ctx_list[NS_NET_POS].path, 228 &ns_ctx_list[NS_PID_POS].path,
229 &ns_ctx_list[NS_PID_POS].path, 229 &ns_ctx_list[NS_USR_POS].path
230 &ns_ctx_list[NS_USR_POS].path
231 ); 230 );
232 argv += optind; 231 argv += optind;
233 //bb_error_msg("opts:0x%x", opts); 232 //bb_error_msg("opts:0x%x", opts);