getopt32: remove opt_complementary
No binary (build failed)
—
(log yok)
| @@ -243,10 +243,13 @@ int ar_main(int argc UNUSED_PARAM, char **argv) | |
| /* prepend '-' to the first argument if required */ | |
| if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') | |
| argv[1] = xasprintf("-%s", argv[1]); | |
| - | /* -1: at least one param is reqd */ |
| - | /* one of p,t,x[,r] is required */ |
| - | opt_complementary = "-1:p:t:x"IF_FEATURE_AR_CREATE(":r"); |
| - | opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r")); |
| + | opt = getopt32(argv, "^" |
| + | "voc""ptx"IF_FEATURE_AR_CREATE("r") |
| + | "\0" |
| + | /* -1: at least one arg is reqd */ |
| + | /* one of p,t,x[,r] is required */ |
| + | "-1:p:t:x"IF_FEATURE_AR_CREATE(":r") |
| + | ); |
| argv += optind; | |
| t = opt / FIRST_CMD; | |
| @@ -195,9 +195,11 @@ int bzip2_main(int argc UNUSED_PARAM, char **argv) | |
| * --best alias for -9 | |
| */ | |
| - | opt_complementary = "s2"; /* -s means -2 (compatibility) */ |
| - | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ |
| - | opt = getopt32(argv, "cfkv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs"); |
| + | opt = getopt32(argv, "^" |
| + | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ |
| + | "cfkv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs" |
| + | "\0" "s2" /* -s means -2 (compatibility) */ |
| + | ); |
| #if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */ | |
| if (opt & 0x30) // -d and/or -t | |
| return bunzip2_main(argc, argv); | |
| @@ -80,8 +80,9 @@ int dpkg_deb_main(int argc UNUSED_PARAM, char **argv) | |
| #endif | |
| /* Must have 1 or 2 args */ | |
| - | opt_complementary = "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; |
| - | opt = getopt32(argv, "cefXx"); |
| + | opt = getopt32(argv, "^" "cefXx" |
| + | "\0" "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX" |
| + | ); |
| argv += optind; | |
| //argc -= optind; | |
| @@ -1138,7 +1138,7 @@ int lzop_main(int argc UNUSED_PARAM, char **argv) | |
| /* -U is "anti -k", invert bit for bbunpack(): */ | |
| option_mask32 ^= OPT_KEEP; | |
| /* -k disables -U (if any): */ | |
| - | /* opt_complementary = "k-U"; - nope, only handles -Uk, not -kU */ |
| + | /* opt_complementary "k-U"? - nope, only handles -Uk, not -kU */ |
| if (option_mask32 & OPT_k) | |
| option_mask32 |= OPT_KEEP; | |
| @@ -973,18 +973,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |
| /* Prepend '-' to the first argument if required */ | |
| if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') | |
| argv[1] = xasprintf("-%s", argv[1]); | |
| - | opt_complementary = |
| - | "tt:vv:" // count -t,-v |
| - | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
| - | "\xff::" // --exclude=PATTERN is a list |
| - | #endif |
| - | IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd |
| - | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive |
| - | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive |
| - | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
| - | ":\xf9+" // --strip-components=NUM |
| - | #endif |
| - | ; |
| #if ENABLE_DESKTOP | |
| /* Lie to buildroot when it starts asking stupid questions. */ | |
| if (argv[1] && strcmp(argv[1], "--version") == 0) { | |
| @@ -1021,7 +1009,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| } | |
| #endif | |
| - | opt = GETOPT32(argv, |
| + | opt = GETOPT32(argv, "^" |
| "txC:f:Oopvk" | |
| IF_FEATURE_TAR_CREATE( "ch" ) | |
| IF_FEATURE_SEAMLESS_BZ2( "j" ) | |
| @@ -1032,6 +1020,17 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |
| IF_FEATURE_SEAMLESS_Z( "Z" ) | |
| IF_FEATURE_TAR_NOPRESERVE_TIME("m") | |
| IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components | |
| + | "\0" |
| + | "tt:vv:" // count -t,-v |
| + | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
| + | "\xff::" // --exclude=PATTERN is a list |
| + | #endif |
| + | IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd |
| + | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive |
| + | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive |
| + | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
| + | ":\xf9+" // --strip-components=NUM |
| + | #endif |
| LONGOPTS | |
| , &base_dir // -C dir | |
| , &tar_filename // -f filename | |
| @@ -348,8 +348,7 @@ int loadfont_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned char *buffer; | |
| // no arguments allowed! | |
| - | opt_complementary = "=0"; |
| - | getopt32(argv, ""); |
| + | getopt32(argv, "^" "" "\0" "=0"); |
| /* | |
| * We used to look at the length of the input file | |
| @@ -437,8 +436,7 @@ int setfont_main(int argc UNUSED_PARAM, char **argv) | |
| char *mapfilename; | |
| const char *tty_name = CURRENT_TTY; | |
| - | opt_complementary = "=1"; |
| - | opts = getopt32(argv, "m:C:", &mapfilename, &tty_name); |
| + | opts = getopt32(argv, "^" "m:C:" "\0" "=1", &mapfilename, &tty_name); |
| argv += optind; | |
| fd = xopen_nonblocking(tty_name); | |
| @@ -47,8 +47,7 @@ int setconsole_main(int argc UNUSED_PARAM, char **argv) | |
| int reset; | |
| /* at most one non-option argument */ | |
| - | opt_complementary = "?1"; |
| - | reset = getopt32(argv, "r"); |
| + | reset = getopt32(argv, "^" "r" "\0" "?1"); |
| argv += 1 + reset; | |
| if (*argv) { | |
| @@ -170,9 +170,11 @@ int cat_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| unsigned opts; | |
| - | IF_FEATURE_CATV(opt_complementary = "Aetv"; /* -A == -vet */) |
| - | /* -u is ignored ("unbuffered") */ |
| - | opts = getopt32(argv, IF_FEATURE_CATV("etvA") IF_FEATURE_CATN("nb") "u"); |
| + | opts = getopt32(argv, IF_FEATURE_CATV("^") |
| + | /* -u is ignored ("unbuffered") */ |
| + | IF_FEATURE_CATV("etvA")IF_FEATURE_CATN("nb")"u" |
| + | IF_FEATURE_CATV("\0" "Aetv" /* -A == -vet */) |
| + | ); |
| argv += optind; | |
| /* Read from stdin if there's nothing else to do. */ | |
| @@ -123,8 +123,7 @@ int chmod_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| /* Parse options */ | |
| - | opt_complementary = "-2"; |
| - | getopt32(argv, ("-"OPT_STR) + 1); /* Reuse string */ |
| + | getopt32(argv, "^" OPT_STR "\0" "-2"); |
| argv += optind; | |
| /* Restore option-like mode if needed */ | |
| @@ -55,7 +55,7 @@ | |
| /* This is a NOEXEC applet. Be very careful! */ | |
| - | #define OPT_STR ("Rh" IF_DESKTOP("vcfLHP")) |
| + | #define OPT_STR "Rh" IF_DESKTOP("vcfLHP") |
| #define BIT_RECURSE 1 | |
| #define OPT_RECURSE (opt & 1) | |
| #define OPT_NODEREF (opt & 2) | |
| @@ -127,11 +127,10 @@ int chown_main(int argc UNUSED_PARAM, char **argv) | |
| int opt, flags; | |
| struct param_t param; | |
| - | opt_complementary = "-2"; |
| #if ENABLE_FEATURE_CHOWN_LONG_OPTIONS | |
| - | opt = getopt32long(argv, OPT_STR, chown_longopts); |
| + | opt = getopt32long(argv, "^" OPT_STR "\0" "=2", chown_longopts); |
| #else | |
| - | opt = getopt32(argv, OPT_STR); |
| + | opt = getopt32(argv, "^" OPT_STR "\0" "=2"); |
| #endif | |
| argv += optind; | |
| @@ -62,8 +62,7 @@ int comm_main(int argc UNUSED_PARAM, char **argv) | |
| int i; | |
| int order; | |
| - | opt_complementary = "=2"; |
| - | getopt32(argv, "123"); |
| + | getopt32(argv, "^" "123" "\0" "=2"); |
| argv += optind; | |
| for (i = 0; i < 2; ++i) { | |
| @@ -73,15 +73,17 @@ int cp_main(int argc, char **argv) | |
| #endif | |
| }; | |
| - | // Need at least two arguments |
| - | // Soft- and hardlinking doesn't mix |
| - | // -P and -d are the same (-P is POSIX, -d is GNU) |
| - | // -r and -R are the same |
| - | // -R (and therefore -r) turns on -d (coreutils does this) |
| - | // -a = -pdR |
| - | opt_complementary = "-2:l--s:s--l:Pd:rRd:Rd:apdR"; |
| #if ENABLE_FEATURE_CP_LONG_OPTIONS | |
| - | flags = getopt32long(argv, FILEUTILS_CP_OPTSTR, |
| + | flags = getopt32long(argv, "^" |
| + | FILEUTILS_CP_OPTSTR |
| + | "\0" |
| + | // Need at least two arguments |
| + | // Soft- and hardlinking doesn't mix |
| + | // -P and -d are the same (-P is POSIX, -d is GNU) |
| + | // -r and -R are the same |
| + | // -R (and therefore -r) turns on -d (coreutils does this) |
| + | // -a = -pdR |
| + | "-2:l--s:s--l:Pd:rRd:Rd:apdR", |
| "archive\0" No_argument "a" | |
| "force\0" No_argument "f" | |
| "interactive\0" No_argument "i" | |
| @@ -42,7 +42,7 @@ | |
| /* option vars */ | |
| - | static const char optstring[] ALIGN1 = "b:c:f:d:sn"; |
| + | #define OPT_STR "b:c:f:d:sn" |
| #define CUT_OPT_BYTE_FLGS (1 << 0) | |
| #define CUT_OPT_CHAR_FLGS (1 << 1) | |
| #define CUT_OPT_FIELDS_FLGS (1 << 2) | |
| @@ -201,8 +201,11 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |
| char *sopt, *ltok; | |
| unsigned opt; | |
| - | opt_complementary = "b--bcf:c--bcf:f--bcf"; |
| - | opt = getopt32(argv, optstring, &sopt, &sopt, &sopt, <ok); |
| + | opt = getopt32(argv, "^" |
| + | OPT_STR |
| + | "\0" "b--bcf:c--bcf:f--bcf", |
| + | &sopt, &sopt, &sopt, <ok |
| + | ); |
| // argc -= optind; | |
| argv += optind; | |
| if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) | |
| @@ -192,12 +192,16 @@ int date_main(int argc UNUSED_PARAM, char **argv) | |
| char *filename; | |
| char *isofmt_arg = NULL; | |
| - | opt_complementary = "d--s:s--d" |
| - | IF_FEATURE_DATE_ISOFMT(":R--I:I--R"); |
| - | opt = getopt32long(argv, "Rs:ud:r:" |
| - | IF_FEATURE_DATE_ISOFMT("I::D:"), date_longopts, |
| + | opt = getopt32long(argv, "^" |
| + | "Rs:ud:r:" |
| + | IF_FEATURE_DATE_ISOFMT("I::D:") |
| + | "\0" |
| + | "d--s:s--d" |
| + | IF_FEATURE_DATE_ISOFMT(":R--I:I--R"), |
| + | date_longopts, |
| &date_str, &date_str, &filename | |
| - | IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)); |
| + | IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt) |
| + | ); |
| argv += optind; | |
| maybe_set_utc(opt); | |
| @@ -115,15 +115,18 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |
| init_unicode(); | |
| + | opt = getopt32(argv, "^" |
| + | "kPT" |
| + | IF_FEATURE_DF_FANCY("aiB:") |
| + | IF_FEATURE_HUMAN_READABLE("hm") |
| + | "\0" |
| #if ENABLE_FEATURE_HUMAN_READABLE && ENABLE_FEATURE_DF_FANCY | |
| - | opt_complementary = "k-mB:m-Bk:B-km"; |
| + | "k-mB:m-Bk:B-km" |
| #elif ENABLE_FEATURE_HUMAN_READABLE | |
| - | opt_complementary = "k-m:m-k"; |
| + | "k-m:m-k" |
| #endif | |
| - | opt = getopt32(argv, "kPT" |
| - | IF_FEATURE_DF_FANCY("aiB:") |
| - | IF_FEATURE_HUMAN_READABLE("hm") |
| - | IF_FEATURE_DF_FANCY(, &chp)); |
| + | IF_FEATURE_DF_FANCY(, &chp) |
| + | ); |
| if (opt & OPT_MEGA) | |
| df_disp_hr = 1024*1024; | |
| @@ -120,8 +120,7 @@ int dos2unix_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| /* -u convert to unix, -d convert to dos */ | |
| - | opt_complementary = "u--d:d--u"; /* mutually exclusive */ |
| - | o = getopt32(argv, "du"); |
| + | o = getopt32(argv, "^" "du" "\0" "u--d:d--u"); /* mutually exclusive */ |
| /* Do the conversion requested by an argument else do the default | |
| * conversion depending on our name. */ | |
| @@ -242,8 +242,11 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |
| * ignore -a. This is consistent with -s being equivalent to -d 0. | |
| */ | |
| #if ENABLE_FEATURE_HUMAN_READABLE | |
| - | opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s"; |
| - | opt = getopt32(argv, "aHkLsx" "d:+" "lc" "hm", &G.max_print_depth); |
| + | opt = getopt32(argv, "^" |
| + | "aHkLsxd:+lchm" |
| + | "\0" "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s", |
| + | &G.max_print_depth |
| + | ); |
| argv += optind; | |
| if (opt & OPT_h_for_humans) { | |
| G.disp_unit = 0; | |
| @@ -255,8 +258,11 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |
| G.disp_unit = 1024; | |
| } | |
| #else | |
| - | opt_complementary = "H-L:L-H:s-d:d-s"; |
| - | opt = getopt32(argv, "aHkLsx" "d:+" "lc", &G.max_print_depth); |
| + | opt = getopt32(argv, "^" |
| + | "aHkLsxd:+lc" |
| + | "\0" "H-L:L-H:s-d:d-s", |
| + | &G.max_print_depth |
| + | ); |
| argv += optind; | |
| #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K | |
| if (opt & OPT_k_kbytes) { | |
| @@ -174,9 +174,10 @@ int expand_main(int argc UNUSED_PARAM, char **argv) | |
| , &opt_t | |
| ); | |
| } else { | |
| - | /* -t NUM sets also -a */ |
| - | opt_complementary = "ta"; |
| - | opt = getopt32long(argv, "ft:a", |
| + | opt = getopt32long(argv, "^" |
| + | "ft:a" |
| + | "\0" |
| + | "ta" /* -t NUM sets -a */, |
| "first-only\0" No_argument "i" | |
| "tabs\0" Required_argument "t" | |
| "all\0" No_argument "a" | |
| @@ -170,9 +170,12 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |
| } else { | |
| /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/ | |
| /* Don't allow more than one username */ | |
| - | opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" |
| - | IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); |
| - | opt = getopt32(argv, "rnugG" IF_SELINUX("Z")); |
| + | opt = getopt32(argv, "^" |
| + | "rnugG" IF_SELINUX("Z") |
| + | "\0" |
| + | "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" |
| + | IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G") |
| + | ); |
| } | |
| username = argv[optind]; | |
| @@ -140,13 +140,16 @@ int install_main(int argc, char **argv) | |
| #endif | |
| }; | |
| - | opt_complementary = "t--d:d--t:s--d:d--s" IF_FEATURE_INSTALL_LONG_OPTIONS(IF_SELINUX(":Z--\xff:\xff--Z")); |
| /* -c exists for backwards compatibility, it's needed */ | |
| /* -b is ignored ("make a backup of each existing destination file") */ | |
| - | opts = GETOPT32(argv, "cvb" "Ddpsg:m:o:t:" IF_SELINUX("Z:"), |
| - | LONGOPTS |
| - | &gid_str, &mode_str, &uid_str, &last |
| - | IF_SELINUX(, &scontext) |
| + | opts = GETOPT32(argv, "^" |
| + | "cvb" "Ddpsg:m:o:t:" IF_SELINUX("Z:") |
| + | "\0" |
| + | "t--d:d--t:s--d:d--s" |
| + | IF_FEATURE_INSTALL_LONG_OPTIONS(IF_SELINUX(":Z--\xff:\xff--Z")), |
| + | LONGOPTS |
| + | &gid_str, &mode_str, &uid_str, &last |
| + | IF_SELINUX(, &scontext) |
| ); | |
| argc -= optind; | |
| argv += optind; | |
| @@ -27,8 +27,7 @@ | |
| int link_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int link_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| - | opt_complementary = "=2"; /* exactly 2 params */ |
| - | getopt32(argv, ""); |
| + | getopt32(argv, "^" "" "\0" "=2"); |
| argv += optind; | |
| if (link(argv[0], argv[1]) != 0) { | |
| /* shared message */ | |
| @@ -62,8 +62,7 @@ int ln_main(int argc, char **argv) | |
| struct stat statbuf; | |
| int (*link_func)(const char *, const char *); | |
| - | opt_complementary = "-1"; /* min one arg */ |
| - | opts = getopt32(argv, "sfnbS:vT", &suffix); |
| + | opts = getopt32(argv, "^" "sfnbS:vT" "\0" "-1", &suffix); |
| last = argv[argc - 1]; | |
| argv += optind; | |
| @@ -206,18 +206,18 @@ SPLIT_SUBDIR = 2, | |
| /* -SXvhTw GNU options, busybox optionally supports */ | |
| /* -T WIDTH Ignored (we don't use tabs on output) */ | |
| /* -Z SELinux mandated option, busybox optionally supports */ | |
| - | static const char ls_options[] ALIGN1 = |
| - | "Cadi1lgnsxAk" /* 12 opts, total 12 */ |
| - | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 14 */ |
| - | IF_FEATURE_LS_RECURSIVE("R") /* 1, 15 */ |
| - | IF_SELINUX("Z") /* 1, 16 */ |
| - | "Q" /* 1, 17 */ |
| - | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 20 */ |
| - | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 24 */ |
| - | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ |
| - | IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ |
| + | #define ls_options \ |
| + | "Cadi1lgnsxAk" /* 12 opts, total 12 */ \ |
| + | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 14 */ \ |
| + | IF_FEATURE_LS_RECURSIVE("R") /* 1, 15 */ \ |
| + | IF_SELINUX("Z") /* 1, 16 */ \ |
| + | "Q" /* 1, 17 */ \ |
| + | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 20 */ \ |
| + | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 24 */ \ |
| + | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ \ |
| + | IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ \ |
| IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */ | |
| - | ; |
| + | |
| enum { | |
| OPT_C = (1 << 0), | |
| OPT_a = (1 << 1), | |
| @@ -1093,24 +1093,26 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |
| #endif | |
| /* process options */ | |
| - | opt_complementary = |
| - | /* -n and -g imply -l */ |
| - | "nl:gl" |
| - | /* --full-time implies -l */ |
| - | IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS(":\xff""l")) |
| - | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: |
| - | * in some pairs of opts, only last one takes effect: |
| - | */ |
| - | IF_FEATURE_LS_TIMESTAMPS(IF_FEATURE_LS_SORTFILES(":t-S:S-t")) /* time/size */ |
| - | // ":m-l:l-m" - we don't have -m |
| - | IF_FEATURE_LS_FOLLOWLINKS(":H-L:L-H") |
| - | ":C-xl:x-Cl:l-xC" /* bycols/bylines/long */ |
| - | ":C-1:1-C" /* bycols/oneline */ |
| - | ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */ |
| - | IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ |
| - | /* -w NUM: */ |
| - | IF_FEATURE_LS_WIDTH(":w+"); |
| - | opt = getopt32long(argv, ls_options, ls_longopts |
| + | opt = getopt32long(argv, "^" |
| + | ls_options |
| + | "\0" |
| + | /* -n and -g imply -l */ |
| + | "nl:gl" |
| + | /* --full-time implies -l */ |
| + | IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS(":\xff""l")) |
| + | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: |
| + | * in some pairs of opts, only last one takes effect: |
| + | */ |
| + | IF_FEATURE_LS_TIMESTAMPS(IF_FEATURE_LS_SORTFILES(":t-S:S-t")) /* time/size */ |
| + | // ":m-l:l-m" - we don't have -m |
| + | IF_FEATURE_LS_FOLLOWLINKS(":H-L:L-H") |
| + | ":C-xl:x-Cl:l-xC" /* bycols/bylines/long */ |
| + | ":C-1:1-C" /* bycols/oneline */ |
| + | ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */ |
| + | IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ |
| + | /* -w NUM: */ |
| + | IF_FEATURE_LS_WIDTH(":w+") |
| + | , ls_longopts |
| IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width) | |
| IF_FEATURE_LS_COLOR(, &color_opt) | |
| ); | |
| @@ -258,15 +258,14 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) | |
| #endif | |
| if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) { | |
| - | /* -s and -w require -c */ |
| - | opt_complementary = "s?c:w?c"; |
| /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ | |
| + | /* -s and -w require -c */ |
| #if ENABLE_SHA3SUM | |
| if (applet_name[3] == HASH_SHA3) | |
| - | flags = getopt32(argv, "scwbta:+", &sha3_width); |
| + | flags = getopt32(argv, "^" "scwbta:+" "\0" "s?c:w?c", &sha3_width); |
| else | |
| #endif | |
| - | flags = getopt32(argv, "scwbt"); |
| + | flags = getopt32(argv, "^" "scwbt" "\0" "s?c:w?c"); |
| } else { | |
| #if ENABLE_SHA3SUM | |
| if (applet_name[3] == HASH_SHA3) | |
| @@ -80,8 +80,7 @@ int mktemp_main(int argc UNUSED_PARAM, char **argv) | |
| if (!path || path[0] == '\0') | |
| path = "/tmp"; | |
| - | opt_complementary = "?1"; /* 1 argument max */ |
| - | opts = getopt32(argv, "dqtp:u", &path); |
| + | opts = getopt32(argv, "^" "dqtp:u" "\0" "?1"/*1 arg max*/, &path); |
| chp = argv[optind]; | |
| if (!chp) { | |
| @@ -55,8 +55,10 @@ int mv_main(int argc, char **argv) | |
| * If more than one of -f, -i, -n is specified , only the final one | |
| * takes effect (it unsets previous options). | |
| */ | |
| - | opt_complementary = "-2:f-in:i-fn:n-fi"; |
| - | flags = getopt32long(argv, "finv", |
| + | flags = getopt32long(argv, "^" |
| + | "finv" |
| + | "\0" |
| + | "-2:f-in:i-fn:n-fi", |
| "interactive\0" No_argument "i" | |
| "force\0" No_argument "f" | |
| "no-clobber\0" No_argument "n" | |
| @@ -71,8 +71,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv) | |
| IF_FEATURE_READLINK_FOLLOW( | |
| unsigned opt; | |
| /* We need exactly one non-option argument. */ | |
| - | opt_complementary = "=1"; |
| - | opt = getopt32(argv, "fnvsq"); |
| + | opt = getopt32(argv, "^" "fnvsq" "\0" "=1"); |
| fname = argv[optind]; | |
| ) | |
| IF_NOT_FEATURE_READLINK_FOLLOW( | |
| @@ -46,8 +46,7 @@ int rm_main(int argc UNUSED_PARAM, char **argv) | |
| int flags = 0; | |
| unsigned opt; | |
| - | opt_complementary = "f-i:i-f"; |
| - | opt = getopt32(argv, "fiRrv"); |
| + | opt = getopt32(argv, "^" "fiRrv" "\0" "f-i:i-f"); |
| argv += optind; | |
| if (opt & 1) | |
| flags |= FILEUTILS_FORCE; | |
| @@ -70,8 +70,11 @@ int shuf_main(int argc, char **argv) | |
| unsigned numlines; | |
| char eol; | |
| - | opt_complementary = "e--i:i--e"; /* mutually exclusive */ |
| - | opts = getopt32(argv, OPT_STR, &opt_i_str, &opt_n_str, &opt_o_str); |
| + | opts = getopt32(argv, "^" |
| + | OPT_STR |
| + | "\0" "e--i:i--e"/* mutually exclusive */, |
| + | &opt_i_str, &opt_n_str, &opt_o_str |
| + | ); |
| argc -= optind; | |
| argv += optind; | |
| @@ -94,7 +94,7 @@ | |
| */ | |
| /* These are sort types */ | |
| - | static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:*t:"; |
| + | #define OPT_STR "ngMucszbrdfimS:T:o:k:*t:" |
| enum { | |
| FLAG_n = 1, /* Numeric sort */ | |
| FLAG_g = 2, /* Sort using strtod() */ | |
| @@ -378,9 +378,11 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |
| xfunc_error_retval = 2; | |
| /* Parse command line options */ | |
| - | /* -o and -t can be given at most once */ |
| - | opt_complementary = "o--o:t--t"; /* -t, -o: at most one of each */ |
| - | opts = getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); |
| + | opts = getopt32(argv, "^" |
| + | OPT_STR |
| + | "\0" "o--o:t--t"/*-t, -o: at most one of each*/, |
| + | &str_ignored, &str_ignored, &str_o, &lst_k, &str_t |
| + | ); |
| /* global b strips leading and trailing spaces */ | |
| if (opts & FLAG_b) | |
| option_mask32 |= FLAG_bb; | |
| @@ -100,8 +100,11 @@ int split_main(int argc UNUSED_PARAM, char **argv) | |
| setup_common_bufsiz(); | |
| - | opt_complementary = "?2"; /* max 2 args; -a N */ |
| - | opt = getopt32(argv, "l:b:a:+", &count_p, &count_p, &suffix_len); |
| + | opt = getopt32(argv, "^" |
| + | "l:b:a:+" /* -a N */ |
| + | "\0" "?2"/*max 2 args*/, |
| + | &count_p, &count_p, &suffix_len |
| + | ); |
| if (opt & SPLIT_OPT_l) | |
| cnt = XATOOFF(count_p); | |
| @@ -762,11 +762,13 @@ int stat_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned opts; | |
| statfunc_ptr statfunc = do_stat; | |
| - | opt_complementary = "-1"; /* min one arg */ |
| - | opts = getopt32(argv, "tL" |
| + | opts = getopt32(argv, "^" |
| + | "tL" |
| IF_FEATURE_STAT_FILESYSTEM("f") | |
| IF_SELINUX("Z") | |
| - | IF_FEATURE_STAT_FORMAT("c:", &format) |
| + | IF_FEATURE_STAT_FORMAT("c:") |
| + | "\0" "-1" /* min one arg */ |
| + | IF_FEATURE_STAT_FORMAT(,&format) |
| ); | |
| #if ENABLE_FEATURE_STAT_FILESYSTEM | |
| if (opts & OPT_FILESYS) /* -f */ | |
| @@ -59,8 +59,7 @@ int sync_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM)) | |
| OPT_SYNCFS = (1 << 1), | |
| }; | |
| - | opt_complementary = "d--f:f--d"; |
| - | opts = getopt32(argv, "df"); |
| + | opts = getopt32(argv, "^" "df" "\0" "d--f:f--d"); |
| argv += optind; | |
| /* Handle the no-argument case. */ | |
| @@ -140,9 +140,11 @@ int tail_main(int argc, char **argv) | |
| #endif | |
| /* -s NUM, -F imlies -f */ | |
| - | IF_FEATURE_FANCY_TAIL(opt_complementary = "Ff";) |
| - | opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:+vF"), |
| - | &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period)); |
| + | opt = getopt32(argv, IF_FEATURE_FANCY_TAIL("^") |
| + | "fc:n:"IF_FEATURE_FANCY_TAIL("qs:+vF") |
| + | IF_FEATURE_FANCY_TAIL("\0" "Ff"), |
| + | &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period) |
| + | ); |
| #define FOLLOW (opt & 0x1) | |
| #define COUNT_BYTES (opt & 0x2) | |
| //if (opt & 0x1) // -f | |
| @@ -298,8 +298,8 @@ int tr_main(int argc UNUSED_PARAM, char **argv) | |
| * In POSIX locale, these are the same. | |
| */ | |
| - | opt_complementary = "-1"; |
| - | opts = getopt32(argv, "+Ccds"); /* '+': stop at first non-option */ |
| + | /* '+': stop at first non-option */ |
| + | opts = getopt32(argv, "^+" "Ccds" "\0" "-1"); |
| argv += optind; | |
| str1_length = expand(*argv++, &str1); | |
| @@ -50,8 +50,7 @@ int truncate_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_SIZE = (1 << 1), | |
| }; | |
| - | opt_complementary = "s:-1"; |
| - | opts = getopt32(argv, "cs:", &size_str); |
| + | opts = getopt32(argv, "^" "cs:" "\0" "s:-1", &size_str); |
| if (!(opts & OPT_NOCREATE)) | |
| flags |= O_CREAT; | |
| @@ -25,8 +25,7 @@ | |
| int unlink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int unlink_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| - | opt_complementary = "=1"; /* must have exactly 1 param */ |
| - | getopt32(argv, ""); |
| + | getopt32(argv, "^" "" "\0" "=1"); |
| argv += optind; | |
| xunlink(argv[0]); | |
| return 0; | |
| @@ -120,8 +120,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) | |
| char *outname = NULL; | |
| char *line; | |
| - | opt_complementary = "?1"; /* 1 argument max */ |
| - | getopt32(argv, "o:", &outname); |
| + | getopt32(argv, "^" "o:" "\0" "?1"/* 1 arg max*/, &outname); |
| argv += optind; | |
| if (!argv[0]) | |
| @@ -196,8 +195,7 @@ int base64_main(int argc UNUSED_PARAM, char **argv) | |
| FILE *src_stream; | |
| unsigned opts; | |
| - | opt_complementary = "?1"; /* 1 argument max */ |
| - | opts = getopt32(argv, "d"); |
| + | opts = getopt32(argv, "^" "d" "\0" "?1"/* 1 arg max*/); |
| argv += optind; | |
| if (!argv[0]) | |
| @@ -49,8 +49,7 @@ int uuencode_main(int argc UNUSED_PARAM, char **argv) | |
| tbl = bb_uuenc_tbl_std; | |
| mode = 0666 & ~umask(0666); | |
| - | opt_complementary = "-1:?2"; /* must have 1 or 2 args */ |
| - | if (getopt32(argv, "m")) { |
| + | if (getopt32(argv, "^" "m" "\0" "-1:?2"/*must have 1 or 2 args*/)) { |
| tbl = bb_uuenc_tbl_base64; | |
| } | |
| argv += optind; | |
| @@ -117,8 +117,7 @@ int who_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned opt; | |
| const char *fmt = "%s"; | |
| - | opt_complementary = "=0"; |
| - | opt = getopt32(argv, do_who ? "aH" : ""); |
| + | opt = getopt32(argv, do_who ? "^" "aH" "\0" "=0": "^" "" "\0" "=0"); |
| if ((opt & 2) || do_w) /* -H or we are w */ | |
| puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); | |
| @@ -181,8 +181,9 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| /* We require exactly one argument: the directory name */ | |
| - | opt_complementary = "=1"; |
| - | GETOPT32(argv, "a:*u:" LONGOPTS, &arg_list, &umask_p); |
| + | GETOPT32(argv, "^" "a:*u:" "\0" "=1" LONGOPTS, |
| + | &arg_list, &umask_p |
| + | ); |
| umask(xstrtou_range(umask_p, 8, 0, 07777)); | |
| @@ -451,15 +451,17 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | /* -K or -S is required; they are mutually exclusive */ |
| - | /* -p is required if -m is given */ |
| - | /* -xpun (at least one) is required if -K is given */ |
| - | /* -xa (at least one) is required if -S is given */ |
| - | /* -q turns off -v */ |
| - | opt_complementary = "K:S:K--S:S--K:m?p:K?xpun:S?xa" |
| - | IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"); |
| - | opt = GETOPT32(argv, "KSbqtma:n:s:u:c:x:p:" |
| - | IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"), |
| + | opt = GETOPT32(argv, "^" |
| + | "KSbqtma:n:s:u:c:x:p:" |
| + | IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:") |
| + | /* -K or -S is required; they are mutually exclusive */ |
| + | /* -p is required if -m is given */ |
| + | /* -xpun (at least one) is required if -K is given */ |
| + | /* -xa (at least one) is required if -S is given */ |
| + | /* -q turns off -v */ |
| + | "\0" |
| + | "K:S:K--S:S--K:m?p:K?xpun:S?xa" |
| + | IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"), |
| LONGOPTS | |
| &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile | |
| IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) | |
| @@ -37,8 +37,7 @@ int which_main(int argc UNUSED_PARAM, char **argv) | |
| if (!env_path) | |
| env_path = bb_default_root_path; | |
| - | opt_complementary = "-1"; /* at least one argument */ |
| - | getopt32(argv, "a"); |
| + | getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/); |
| argv += optind; | |
| do { | |
| @@ -71,8 +71,7 @@ int tune2fs_main(int argc UNUSED_PARAM, char **argv) | |
| struct ext2_super_block *sb; | |
| int fd; | |
| - | opt_complementary = "=1"; |
| - | opts = getopt32(argv, "L:c:i:C:", &label, &str_c, &str_i, &str_C); |
| + | opts = getopt32(argv, "^" "L:c:i:C:" "\0" "=1", &label, &str_c, &str_i, &str_C); |
| if (!opts) | |
| bb_show_usage(); | |
| argv += optind; // argv[0] -- device | |
| @@ -36,7 +36,7 @@ static const char fmt_differ[] ALIGN1 = "%s %s differ: char %"OFF_FMT"u, line %u | |
| // This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"u %o %o\n" | |
| static const char fmt_l_opt[] ALIGN1 = "%.0s%.0s%"OFF_FMT"u %3o %3o\n"; | |
| - | static const char opt_chars[] ALIGN1 = "sl"; |
| + | #define OPT_STR "sl" |
| #define CMP_OPT_s (1<<0) | |
| #define CMP_OPT_l (1<<1) | |
| @@ -52,11 +52,13 @@ int cmp_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned opt; | |
| int retval = 0; | |
| - | opt_complementary = "-1" |
| + | opt = getopt32(argv, "^" |
| + | OPT_STR |
| + | "\0" "-1" |
| IF_DESKTOP(":?4") | |
| IF_NOT_DESKTOP(":?2") | |
| - | ":l--s:s--l"; |
| - | opt = getopt32(argv, opt_chars); |
| + | ":l--s:s--l" |
| + | ); |
| argv += optind; | |
| filename1 = *argv; | |
| @@ -984,8 +984,8 @@ int diff_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| /* exactly 2 params; collect multiple -L <label>; -U N */ | |
| - | opt_complementary = "=2"; |
| - | GETOPT32(argv, "abdiL:*NqrsS:tTU:+wupBE" LONGOPTS, |
| + | GETOPT32(argv, "^" "abdiL:*NqrsS:tTU:+wupBE" "\0" "=2" |
| + | LONGOPTS, |
| &L_arg, &s_start, &opt_U_context); | |
| argv += optind; | |
| while (L_arg) | |
| @@ -1507,13 +1507,15 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |
| /* do normal option parsing */ | |
| opt_e = opt_f = NULL; | |
| opt_i = NULL; | |
| - | opt_complementary = "nn"; /* count -n */ |
| /* -i must be first, to match OPT_in_place definition */ | |
| /* -E is a synonym of -r: | |
| * GNU sed 4.2.1 mentions it in neither --help | |
| * nor manpage, but does recognize it. | |
| */ | |
| - | opt = getopt32long(argv, "i::rEne:*f:*", sed_longopts, |
| + | opt = getopt32long(argv, "^" |
| + | "i::rEne:*f:*" |
| + | "\0" "nn"/*count -n*/, |
| + | sed_longopts, |
| &opt_i, &opt_e, &opt_f, | |
| &G.be_quiet); /* counter for -n */ | |
| //argc -= optind; | |
| @@ -107,6 +107,7 @@ | |
| //usage:#define fgrep_trivial_usage NOUSAGE_STR | |
| //usage:#define fgrep_full_usage "" | |
| + | /* -e,-f are lists; -m,-A,-B,-C have numeric param */ |
| #define OPTSTR_GREP \ | |
| "lnqvscFiHhe:*f:*Lorm:+wx" \ | |
| IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \ | |
| @@ -686,11 +687,9 @@ int grep_main(int argc UNUSED_PARAM, char **argv) | |
| /* do normal option parsing */ | |
| #if ENABLE_FEATURE_GREP_CONTEXT | |
| - | /* -H unsets -h; -C unsets -A,-B; -e,-f are lists; |
| - | * -m,-A,-B,-C have numeric param */ |
| - | opt_complementary = "H-h:C-AB"; |
| + | /* -H unsets -h; -C unsets -A,-B */ |
| opts = getopt32(argv, | |
| - | OPTSTR_GREP, |
| + | "^" OPTSTR_GREP "\0" "H-h:C-AB", |
| &pattern_head, &fopt, &max_matches, | |
| &lines_after, &lines_before, &Copt); | |
| @@ -716,9 +715,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| #else | |
| /* with auto sanity checks */ | |
| - | /* -H unsets -h; -c,-q or -l unset -n; -e,-f are lists; -m N */ |
| - | opt_complementary = "H-h:c-n:q-n:l-n:"; |
| - | getopt32(argv, OPTSTR_GREP, |
| + | getopt32(argv, "^" OPTSTR_GREP "\0" "H-h:c-n:q-n:l-n:", // why trailing ":"? |
| &pattern_head, &fopt, &max_matches); | |
| #endif | |
| invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ | |
| @@ -1185,9 +1185,6 @@ void make_all_argv_opts(char **argv) FAST_FUNC; | |
| char* single_argv(char **argv) FAST_FUNC; | |
| extern const char *const bb_argv_dash[]; /* { "-", NULL } */ | |
| extern uint32_t option_mask32; | |
| - | //TODO: get rid of this global variable. How about a trick where optstring can be |
| - | // "^optchars""\0""complementary" (the leading "^" is an indicator)? |
| - | extern const char *opt_complementary; |
| uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; | |
| # define No_argument "\0" | |
| # define Required_argument "\001" | |
| @@ -96,9 +96,11 @@ getopt32(char **argv, const char *applet_opts, ...) | |
| env -i ls -d / | |
| Here we want env to process just the '-i', not the '-d'. | |
| - | "!" Report bad option, missing required options, |
| + | "!" Report bad options, missing required options, |
| inconsistent options with all-ones return value (instead of abort). | |
| + | "^" options string is "^optchars""\0""opt_complementary". |
| + | |
| uint32_t | |
| getopt32long(char **argv, const char *applet_opts, const char *logopts...) | |
| @@ -121,7 +123,7 @@ getopt32long(char **argv, const char *applet_opts, const char *logopts...) | |
| config process and not a required feature. The current standard | |
| is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS. | |
| - | const char *opt_complementary |
| + | opt_complementary - option modifiers. |
| ":" The colon (":") is used to separate groups of two or more chars | |
| and/or groups of chars and special characters (stating some | |
| @@ -132,8 +134,7 @@ const char *opt_complementary | |
| Their flags will be turned on if the main option is found even | |
| if they are not specified on the command line. For example: | |
| - | opt_complementary = "abc"; |
| - | flags = getopt32(argv, "abcd") |
| + | flags = getopt32(argv, "^abcd""\0""abc") |
| If getopt() finds "-a" on the command line, then | |
| getopt32's return value will be as if "-a -b -c" were | |
| @@ -146,8 +147,7 @@ const char *opt_complementary | |
| if w is given more than once, it is "unlimited" | |
| int w_counter = 0; // must be initialized! | |
| - | opt_complementary = "ww"; |
| - | getopt32(argv, "w", &w_counter); |
| + | getopt32(argv, "^w""\0""ww", &w_counter); |
| if (w_counter) | |
| width = (w_counter == 1) ? 132 : INT_MAX; | |
| else | |
| @@ -162,8 +162,9 @@ const char *opt_complementary | |
| llist_t *my_b = NULL; | |
| int verbose_level = 0; | |
| - | opt_complementary = "vv:b-c:c-b"; |
| - | f = getopt32(argv, "vb:*c", &my_b, &verbose_level); |
| + | f = getopt32(argv, "^vb:*c" |
| + | "\0""vv:b-c:c-b" |
| + | , &my_b, &verbose_level); |
| if (f & 2) // -c after -b unsets -b flag | |
| while (my_b) dosomething_with(llist_pop(&my_b)); | |
| if (my_b) // but llist is stored if -b is specified | |
| @@ -199,7 +200,7 @@ Special characters: | |
| getopt32 finds -s, then -d is unset or if it finds -d | |
| then -s is unset. (Note: busybox implements the GNU | |
| "--max-depth" option as "-d".) To obtain this behavior, you | |
| - | set opt_complementary = "s-d:d-s". Only one flag value is |
| + | set opt_complementary to "s-d:d-s". Only one flag value is |
| added to getopt32's return value depending on the | |
| position of the options on the command line. If one of the | |
| two options requires an argument pointer (":" in applet_opts | |
| @@ -207,8 +208,7 @@ Special characters: | |
| char *smax_print_depth; | |
| - | opt_complementary = "s-d:d-s:x-x"; |
| - | opt = getopt32(argv, "sd:x", &smax_print_depth); |
| + | opt = getopt32(argv, "^sd:x""\0""s-d:d-s:x-x", &smax_print_depth); |
| if (opt & 2) | |
| max_print_depth = atoi(smax_print_depth); | |
| @@ -224,7 +224,7 @@ Special characters: | |
| The cut applet must have only one type of list specified, so | |
| -b, -c and -f are mutually exclusive and should raise an error | |
| if specified together. In this case you must set | |
| - | opt_complementary = "b--cf:c--bf:f--bc". If two of the |
| + | opt_complementary to "b--cf:c--bf:f--bc". If two of the |
| mutually exclusive options are found, getopt32 will call | |
| bb_show_usage() and die. | |
| @@ -236,8 +236,7 @@ Special characters: | |
| with xatoi_positive() - allowed range is 0..INT_MAX. | |
| int param; // "unsigned param;" will also work | |
| - | opt_complementary = "p+"; |
| - | getopt32(argv, "p:", ¶m); |
| + | getopt32(argv, "^p:""\0""p+", ¶m); |
| "o::" A double colon after a char in opt_complementary means that the | |
| option can occur multiple times. Each occurrence will be saved as | |
| @@ -252,8 +251,7 @@ Special characters: | |
| (this pointer must be initializated to NULL if the list is empty | |
| as required by llist_add_to_end(llist_t **old_head, char *new_item).) | |
| - | opt_complementary = "e::"; |
| - | getopt32(argv, "e:", &patterns); |
| + | getopt32(argv, "^e:""\0""e::", &patterns); |
| $ grep -e user -e root /etc/passwd | |
| root:x:0:0:root:/root:/bin/bash | |
| @@ -271,8 +269,7 @@ Special characters: | |
| For example from "id" applet: | |
| // Don't allow -n -r -rn -ug -rug -nug -rnug | |
| - | opt_complementary = "r?ug:n?ug:u--g:g--u"; |
| - | flags = getopt32(argv, "rnug"); |
| + | flags = getopt32(argv, "^rnug""\0""r?ug:n?ug:u--g:g--u"); |
| This example allowed only: | |
| $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng | |
| @@ -283,8 +280,7 @@ Special characters: | |
| For example from "start-stop-daemon" applet: | |
| // Don't allow -KS -SK, but -S or -K is required | |
| - | opt_complementary = "K:S:K--S:S--K"; |
| - | flags = getopt32(argv, "KS...); |
| + | flags = getopt32(argv, "^KS...""\0""K:S:K--S:S--K"); |
| Don't forget to use ':'. For example, "?322-22-23X-x-a" | |
| @@ -299,8 +295,6 @@ Special characters: | |
| const char *const bb_argv_dash[] = { "-", NULL }; | |
| - | const char *opt_complementary; |
| - | |
| enum { | |
| PARAM_STRING, | |
| PARAM_LIST, | |
| @@ -337,10 +331,12 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |
| int argc; | |
| unsigned flags = 0; | |
| unsigned requires = 0; | |
| + | unsigned len; |
| t_complementary complementary[33]; /* last stays zero-filled */ | |
| - | char first_char; |
| + | char dont_die_flag; |
| int c; | |
| const unsigned char *s; | |
| + | const char *opt_complementary; |
| t_complementary *on_off; | |
| #if ENABLE_LONG_OPTS | |
| const struct option *l_o; | |
| @@ -349,23 +345,29 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |
| unsigned trigger; | |
| int min_arg = 0; | |
| int max_arg = -1; | |
| - | |
| - | #define SHOW_USAGE_IF_ERROR 1 |
| - | |
| int spec_flgs = 0; | |
| - | /* skip 0: some applets cheat: they do not actually HAVE argv[0] */ |
| - | argc = 1 + string_array_len(argv + 1); |
| + | #define SHOW_USAGE_IF_ERROR 1 |
| on_off = complementary; | |
| memset(on_off, 0, sizeof(complementary)); | |
| - | applet_opts = strcpy(alloca(strlen(applet_opts) + 1), applet_opts); |
| + | len = strlen(applet_opts); |
| /* skip bbox extension */ | |
| - | first_char = applet_opts[0]; |
| - | if (first_char == '!') |
| + | opt_complementary = NULL; |
| + | if (applet_opts[0] == '^') { |
| applet_opts++; | |
| + | /* point it past terminating NUL */ |
| + | opt_complementary = applet_opts + len; |
| + | } |
| + | |
| + | /* skip another bbox extension */ |
| + | dont_die_flag = applet_opts[0]; |
| + | if (dont_die_flag == '!') |
| + | applet_opts++; |
| + | |
| + | applet_opts = strcpy(alloca(len + 1), applet_opts); |
| /* skip GNU extension */ | |
| s = (const unsigned char *)applet_opts; | |
| @@ -435,7 +437,8 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |
| } | |
| #endif /* ENABLE_LONG_OPTS */ | |
| - | for (s = (const unsigned char *)opt_complementary; s && *s; s++) { |
| + | s = (const unsigned char *)opt_complementary; |
| + | if (s) for (; *s; s++) { |
| t_complementary *pair; | |
| unsigned *pair_switch; | |
| @@ -513,8 +516,6 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |
| s--; | |
| } | |
| - | /* Make it unnecessary to clear it by hand after each getopt32 call */ |
| - | opt_complementary = NULL; |
| /* In case getopt32 was already called: | |
| * reset the libc getopt() function, which keeps internal state. | |
| * 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, | |
| */ | |
| GETOPT_RESET(); | |
| + | /* skip 0: some applets cheat: they do not actually HAVE argv[0] */ |
| + | argc = 1 + string_array_len(argv + 1); |
| + | |
| /* Note: just "getopt() <= 0" will not work well for | |
| * "fake" short options, like this one: | |
| * wget $'-\203' "Test: test" http://kernel.org/ | |
| @@ -583,7 +587,7 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |
| return flags; | |
| error: | |
| - | if (first_char != '!') |
| + | if (dont_die_flag != '!') |
| bb_show_usage(); | |
| return (int32_t)-1; | |
| } | |
| @@ -42,8 +42,9 @@ int parse_main(int argc UNUSED_PARAM, char **argv) | |
| int mintokens = 0, ntokens = 128; | |
| unsigned noout; | |
| - | opt_complementary = "-1"; |
| - | noout = 1 & getopt32(argv, "xn:+m:+d:f:+", &ntokens, &mintokens, &delims, &flags); |
| + | noout = 1 & getopt32(argv, "^" "xn:+m:+d:f:+" "\0" "-1", |
| + | &ntokens, &mintokens, &delims, &flags |
| + | ); |
| //argc -= optind; | |
| argv += optind; | |
| @@ -98,7 +98,6 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |
| * (getopt32() does it itself, but getopt() doesn't (and can't)) | |
| */ | |
| GETOPT_RESET(); | |
| - | /* opt_complementary = NULL; - cleared by each getopt32() call anyway */ |
| argc = string_array_len(argv); | |
| @@ -123,7 +122,6 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |
| restore_nofork_data(&old); | |
| /* Other globals can be simply reset to defaults */ | |
| GETOPT_RESET(); | |
| - | /* opt_complementary = NULL; - cleared by each getopt32() call anyway */ |
| return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ | |
| } | |
| @@ -138,7 +136,6 @@ void FAST_FUNC run_noexec_applet_and_exit(int a, const char *name, char **argv) | |
| xfunc_error_retval = EXIT_FAILURE; | |
| die_func = NULL; | |
| GETOPT_RESET(); | |
| - | /* opt_complementary = NULL; - cleared by each getopt32() call anyway */ |
| //TODO: think pidof, pgrep, pkill! | |
| //set_task_comm() makes our pidof find NOEXECs (e.g. "yes >/dev/null"), | |
| @@ -152,11 +152,12 @@ int addgroup_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| /* Syntax: | |
| * addgroup group | |
| - | * addgroup -g num group |
| + | * addgroup --gid num group |
| * addgroup user group | |
| * Check for min, max and missing args */ | |
| - | opt_complementary = "-1:?2"; |
| - | opts = getopt32long(argv, "g:S", addgroup_longopts, &gid); |
| + | opts = getopt32long(argv, "^" "g:S" "\0" "-1:?2", addgroup_longopts, |
| + | &gid |
| + | ); |
| /* move past the commandline options */ | |
| argv += optind; | |
| //argc -= optind; | |
| @@ -201,12 +201,15 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) | |
| pw.pw_shell = (char *)get_shell_name(); | |
| pw.pw_dir = NULL; | |
| - | /* at least one and at most two non-option args */ |
| - | /* disable interactive passwd for system accounts */ |
| - | opt_complementary = "-1:?2:SD"; |
| - | opts = getopt32long(argv, "h:g:s:G:DSHu:k:", adduser_longopts, |
| + | opts = getopt32long(argv, "^" |
| + | "h:g:s:G:DSHu:k:" |
| + | /* at least one and at most two non-option args */ |
| + | /* disable interactive passwd for system accounts */ |
| + | "\0" "-1:?2:SD", |
| + | adduser_longopts, |
| &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, | |
| - | &usegroup, &uid, &skel); |
| + | &usegroup, &uid, &skel |
| + | ); |
| if (opts & OPT_UID) | |
| pw.pw_uid = xatou_range(uid, 0, CONFIG_LAST_ID); | |
| @@ -61,8 +61,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) | |
| if (getuid() != 0) | |
| bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | |
| - | opt_complementary = "m--ec:e--mc:c--em"; |
| - | opt = getopt32long(argv, "emc:", chpasswd_longopts, &algo); |
| + | opt = getopt32long(argv, "^" "emc:" "\0" "m--ec:e--mc:c--em", |
| + | chpasswd_longopts, |
| + | &algo |
| + | ); |
| while ((name = xmalloc_fgetline(stdin)) != NULL) { | |
| char *free_me; | |
| @@ -111,9 +111,10 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv) | |
| opt_m = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO; | |
| opt_S = NULL; | |
| /* at most two non-option arguments; -P NUM */ | |
| - | opt_complementary = "?2"; |
| - | getopt32long(argv, "sP:+S:m:a:", mkpasswd_longopts, |
| - | &fd, &opt_S, &opt_m, &opt_m); |
| + | getopt32long(argv, "^" "sP:+S:m:a:" "\0" "?2", |
| + | mkpasswd_longopts, |
| + | &fd, &opt_S, &opt_m, &opt_m |
| + | ); |
| argv += optind; | |
| /* have no idea how to handle -s... */ | |
| @@ -131,7 +131,7 @@ struct globals { | |
| //usage: "\n" | |
| //usage: "\nBAUD_RATE of 0 leaves it unchanged" | |
| - | static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:+wn"; |
| + | #define OPT_STR "I:LH:f:hil:mt:+wn" |
| #define F_INITSTRING (1 << 0) /* -I */ | |
| #define F_LOCAL (1 << 1) /* -L */ | |
| #define F_FAKEHOST (1 << 2) /* -H */ | |
| @@ -179,8 +179,7 @@ static void parse_args(char **argv) | |
| char *ts; | |
| int flags; | |
| - | opt_complementary = "-2"; /* at least 2 args; -t N */ |
| - | flags = getopt32(argv, opt_string, |
| + | flags = getopt32(argv, "^" OPT_STR "\0" "-2"/* at least 2 args*/, |
| &G.initstring, &G.fakehost, &G.issue, | |
| &G.login, &G.timeout | |
| ); | |
| @@ -66,8 +66,7 @@ int vlock_main(int argc UNUSED_PARAM, char **argv) | |
| struct passwd *pw; | |
| pw = xgetpwuid(getuid()); | |
| - | opt_complementary = "=0"; /* no params! */ |
| - | getopt32(argv, "a"); |
| + | getopt32(argv, "^" "a" "\0" "=0"/* no args!*/); |
| /* Ignore some signals so that we don't get killed by them */ | |
| bb_signals(0 | |
| @@ -125,9 +125,9 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| // parse options | |
| - | opt_complementary = "-1:dd"; |
| - | opts = getopt32(argv, |
| - | "bdmVcasTkt:+" "R:+Z:L:+H:+" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:"), |
| + | opts = getopt32(argv, "^" |
| + | "bdmVcasTkt:+" "R:+Z:L:+H:+" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:") |
| + | "\0" "-1:dd", |
| &timeout, NULL, NULL, NULL, &opt_nlines | |
| IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same | |
| ); | |
| @@ -280,9 +280,9 @@ int reformime_main(int argc UNUSED_PARAM, char **argv) | |
| // parse options | |
| // N.B. only -x and -X are supported so far | |
| - | opt_complementary = "x--X:X--x"; |
| - | opts = getopt32(argv, |
| - | "x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:*h:o:O:"), |
| + | opts = getopt32(argv, "^" |
| + | "x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:*h:o:O:") |
| + | "\0" "x--X:X--x", |
| &opt_prefix | |
| IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL) | |
| ); | |
| @@ -256,13 +256,17 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |
| G.fp0 = xfdopen_for_read(3); | |
| // parse options | |
| - | // -v is a counter, -H and -S are mutually exclusive, -a is a list |
| - | opt_complementary = "vv:H--S:S--H"; |
| // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect | |
| // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility, | |
| // it is still under development. | |
| - | opts = getopt32(argv, "tf:o:iw:+H:S:a:*:v", &opt_from, NULL, |
| - | &timeout, &opt_connect, &opt_connect, &list, &verbose); |
| + | opts = getopt32(argv, "^" |
| + | "tf:o:iw:+H:S:a:*:v" |
| + | "\0" |
| + | // -v is a counter, -H and -S are mutually exclusive, -a is a list |
| + | "vv:H--S:S--H", |
| + | &opt_from, NULL, |
| + | &timeout, &opt_connect, &opt_connect, &list, &verbose |
| + | ); |
| //argc -= optind; | |
| argv += optind; | |
| @@ -95,9 +95,10 @@ int adjtimex_main(int argc UNUSED_PARAM, char **argv) | |
| memset(&txc, 0, sizeof(txc)); | |
| - | opt_complementary = "=0"; /* no valid non-option parameters */ |
| - | opt = getopt32(argv, "qo:f:p:t:", |
| - | &opt_o, &opt_f, &opt_p, &opt_t); |
| + | opt = getopt32(argv, "^" "qo:f:p:t:" |
| + | "\0" "=0"/*no valid non-option args*/, |
| + | &opt_o, &opt_f, &opt_p, &opt_t |
| + | ); |
| //if (opt & 0x1) // -q | |
| if (opt & 0x2) { // -o | |
| txc.offset = xatol(opt_o); | |
| @@ -1021,13 +1021,17 @@ int crond_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | /* "-b after -f is ignored", and so on for every pair a-b */ |
| - | opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") |
| + | opts = getopt32(argv, "^" |
| + | "l:L:fbSc:" IF_FEATURE_CROND_D("d:") |
| + | "\0" |
| + | /* "-b after -f is ignored", and so on for every pair a-b */ |
| + | "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") |
| /* -l and -d have numeric param */ | |
| - | ":l+" IF_FEATURE_CROND_D(":d+"); |
| - | opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), |
| + | ":l+" IF_FEATURE_CROND_D(":d+") |
| + | , |
| &G.log_level, &G.log_filename, &G.crontab_dir_name | |
| - | IF_FEATURE_CROND_D(,&G.log_level)); |
| + | IF_FEATURE_CROND_D(,&G.log_level) |
| + | ); |
| /* both -d N and -l N set the same variable: G.log_level */ | |
| if (!(opts & OPT_f)) { | |
| @@ -99,8 +99,9 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_ler = OPT_l + OPT_e + OPT_r, | |
| }; | |
| - | opt_complementary = "?1:dr"; /* max one argument; -d implies -r */ |
| - | opt_ler = getopt32(argv, "u:c:lerd", &user_name, &crontab_dir); |
| + | opt_ler = getopt32(argv, "^" "u:c:lerd" "\0" "?1:dr"/*max one arg; -d implies -r*/, |
| + | &user_name, &crontab_dir |
| + | ); |
| argv += optind; | |
| if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */ | |
| @@ -82,8 +82,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned int flags; | |
| char *mtd_name; | |
| - | opt_complementary = "=1"; |
| - | flags = getopt32(argv, "jNq"); |
| + | flags = getopt32(argv, "^" "jNq" "\0" "=1"); |
| mtd_name = argv[optind]; | |
| fd = xopen(mtd_name, O_RDWR); | |
| @@ -69,8 +69,7 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv) | |
| RESERVE_CONFIG_UBUFFER(buf, BUFSIZE); | |
| RESERVE_CONFIG_UBUFFER(buf2, BUFSIZE); | |
| - | opt_complementary = "=2"; /* exactly 2 non-option args: file, dev */ |
| - | /*opts =*/ getopt32(argv, "v"); |
| + | /*opts =*/ getopt32(argv, "^" "v" "\0" "=2"/*exactly 2 non-option args: file,dev*/); |
| argv += optind; | |
| // filename = *argv++; | |
| // devicename = *argv; | |
| @@ -455,14 +455,12 @@ int i2cget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int i2cget_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| const unsigned opt_f = (1 << 0), opt_y = (1 << 1); | |
| - | const char *const optstr = "fy"; |
| int bus_num, bus_addr, data_addr = -1, status; | |
| int mode = I2C_SMBUS_BYTE, pec = 0, fd; | |
| unsigned opts; | |
| - | opt_complementary = "-2:?4"; /* from 2 to 4 args */ |
| - | opts = getopt32(argv, optstr); |
| + | opts = getopt32(argv, "^" "fy" "\0" "-2:?4"/*from 2 to 4 args*/); |
| argv += optind; | |
| bus_num = i2c_bus_lookup(argv[0]); | |
| @@ -544,7 +542,6 @@ int i2cset_main(int argc, char **argv) | |
| { | |
| const unsigned opt_f = (1 << 0), opt_y = (1 << 1), | |
| opt_m = (1 << 2), opt_r = (1 << 3); | |
| - | const char *const optstr = "fym:r"; |
| int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0; | |
| int val, blen = 0, mask = 0, fd, status; | |
| @@ -552,8 +549,7 @@ int i2cset_main(int argc, char **argv) | |
| char *opt_m_arg = NULL; | |
| unsigned opts; | |
| - | opt_complementary = "-3"; /* from 3 to ? args */ |
| - | opts = getopt32(argv, optstr, &opt_m_arg); |
| + | opts = getopt32(argv, "^" "fym:r" "\0" "-3"/*from 3 to ? args*/, &opt_m_arg); |
| argv += optind; | |
| argc -= optind; | |
| @@ -905,7 +901,6 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| const unsigned opt_f = (1 << 0), opt_y = (1 << 1), | |
| opt_r = (1 << 2); | |
| - | const char *const optstr = "fyr:"; |
| int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0; | |
| unsigned first = 0x00, last = 0xff, opts; | |
| @@ -913,8 +908,11 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv) | |
| char *opt_r_str, *dash; | |
| int fd, res; | |
| - | opt_complementary = "-2:?3"; /* from 2 to 3 args */ |
| - | opts = getopt32(argv, optstr, &opt_r_str); |
| + | opts = getopt32(argv, "^" |
| + | "fyr:" |
| + | "\0" "-2:?3" /* from 2 to 3 args */, |
| + | &opt_r_str |
| + | ); |
| argv += optind; | |
| bus_num = i2c_bus_lookup(argv[0]); | |
| @@ -1208,15 +1206,16 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) | |
| const unsigned opt_y = (1 << 0), opt_a = (1 << 1), | |
| opt_q = (1 << 2), opt_r = (1 << 3), | |
| opt_F = (1 << 4), opt_l = (1 << 5); | |
| - | const char *const optstr = "yaqrFl"; |
| int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status, cmd; | |
| unsigned first = 0x03, last = 0x77, opts; | |
| unsigned long funcs; | |
| - | opt_complementary = "q--r:r--q:" /* mutually exclusive */ |
| - | "?3"; /* up to 3 args */ |
| - | opts = getopt32(argv, optstr); |
| + | opts = getopt32(argv, "^" |
| + | "yaqrFl" |
| + | "\0" |
| + | "q--r:r--q:"/*mutually exclusive*/ "?3"/*up to 3 args*/ |
| + | ); |
| argv += optind; | |
| if (opts & opt_l) | |
| @@ -183,8 +183,7 @@ int makedevs_main(int argc UNUSED_PARAM, char **argv) | |
| char *line = (char *)"-"; | |
| int ret = EXIT_SUCCESS; | |
| - | opt_complementary = "=1"; /* exactly one param */ |
| - | getopt32(argv, "d:", &line); |
| + | getopt32(argv, "^" "d:" "\0" "=1", &line); |
| argv += optind; | |
| xchdir(*argv); /* ensure root dir exists */ | |
| @@ -253,8 +253,7 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | opt_complementary = "-1"; /* at least one argument */ |
| - | opt = getopt32(argv, "+aw"); |
| + | opt = getopt32(argv, "^+" "aw" "\0" "-1"/*at least one arg*/); |
| argv += optind; | |
| sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9"); | |
| @@ -74,8 +74,9 @@ int microcom_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned opts; | |
| // fetch options | |
| - | opt_complementary = "=1"; |
| - | opts = getopt32(argv, "Xs:+d:+t:+", &speed, &delay, &timeout); |
| + | opts = getopt32(argv, "^" "Xs:+d:+t:+" "\0" "=1", |
| + | &speed, &delay, &timeout |
| + | ); |
| // argc -= optind; | |
| argv += optind; | |
| @@ -123,13 +123,12 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) | |
| const char *opt_s = "0", *opt_f = "-", *opt_l, *opt_bb; | |
| if (IS_NANDDUMP) { | |
| - | opt_complementary = "=1"; |
| - | opts = getopt32long(argv, "ons:f:l:", |
| + | opts = getopt32long(argv, "^" "ons:f:l:" "\0" "=1", |
| "bb\0" Required_argument "\xff", /* no short equivalent */ | |
| - | &opt_s, &opt_f, &opt_l, &opt_bb); |
| + | &opt_s, &opt_f, &opt_l, &opt_bb |
| + | ); |
| } else { /* nandwrite */ | |
| - | opt_complementary = "-1:?2"; |
| - | opts = getopt32(argv, "pns:", &opt_s); |
| + | opts = getopt32(argv, "^" "pns:" "\0" "-1:?2", &opt_s); |
| } | |
| argv += optind; | |
| @@ -742,8 +742,7 @@ int setserial_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| int opts; | |
| - | opt_complementary = "-1:b-aG:G-ab:a-bG"; |
| - | opts = getopt32(argv, "bGavzgq"); |
| + | opts = getopt32(argv, "^" "bGavzgq" "\0" "-1:b-aG:G-ab:a-bG"); |
| argv += optind; | |
| if (!argv[1]) /* one arg only? (nothing to change?) */ | |
| @@ -430,9 +430,10 @@ int time_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_f = (1 << 4), | |
| }; | |
| - | opt_complementary = "-1"; /* at least one arg */ |
| /* "+": stop on first non-option */ | |
| - | opt = getopt32(argv, "+vpao:f:", &output_filename, &output_format); |
| + | opt = getopt32(argv, "^+" "vpao:f:" "\0" "-1"/*at least one arg*/, |
| + | &output_filename, &output_format |
| + | ); |
| argv += optind; | |
| if (opt & OPT_v) | |
| output_format = long_format; | |
| @@ -145,20 +145,17 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |
| #define OPTION_a (1 << 5) | |
| #define OPTION_t (1 << 6) | |
| if (do_mkvol) { | |
| - | opt_complementary = "-1"; |
| - | opts = getopt32(argv, "md:+n:+N:s:a:+t:O:+", |
| + | opts = getopt32(argv, "^" "md:+n:+N:s:a:+t:O:+" "\0" "-1", |
| &dev_num, &vol_id, | |
| &vol_name, &size_bytes_str, &alignment, &type, | |
| &vid_hdr_offset | |
| ); | |
| } else | |
| if (do_update) { | |
| - | opt_complementary = "-1"; |
| - | opts = getopt32(argv, "s:at", &size_bytes_str); |
| + | opts = getopt32(argv, "^" "s:at" "\0" "-1", &size_bytes_str); |
| opts *= OPTION_s; | |
| } else { | |
| - | opt_complementary = "-1"; |
| - | opts = getopt32(argv, "m:+d:+n:+N:s:a:+t:", |
| + | opts = getopt32(argv, "^" "m:+d:+n:+N:s:a:+t:" "\0" "-1", |
| &mtd_num, &dev_num, &vol_id, | |
| &vol_name, &size_bytes_str, &alignment, &type | |
| ); | |
| @@ -101,8 +101,9 @@ int watchdog_main(int argc UNUSED_PARAM, char **argv) | |
| char *st_arg; | |
| char *ht_arg; | |
| - | opt_complementary = "=1"; /* must have exactly 1 argument */ |
| - | opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg); |
| + | opts = getopt32(argv, "^" "Ft:T:" "\0" "=1"/*must have exactly 1 arg*/, |
| + | &st_arg, &ht_arg |
| + | ); |
| /* We need to daemonize *before* opening the watchdog as many drivers | |
| * will only allow one process at a time to do so. Since daemonizing | |
| @@ -148,8 +148,7 @@ int modinfo_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned i; | |
| field = NULL; | |
| - | opt_complementary = "-1"; /* minimum one param */ |
| - | opts = getopt32(argv, "0F:nadlp", &field); |
| + | opts = getopt32(argv, "^" "0F:nadlp" "\0" "-1"/*minimum one arg*/, &field); |
| /* If no field selected, show all */ | |
| if (!(opts & (OPT_TAGS|OPT_F))) | |
| option_mask32 |= OPT_TAGS; | |
| @@ -988,10 +988,9 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |
| #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD | |
| /* modprobe, insmod, rmmod require at least one argument */ | |
| - | opt_complementary = "-1"; |
| /* only -q (quiet) and -r (rmmod), | |
| * the rest are accepted and ignored (compat) */ | |
| - | getopt32(argv, "qrfsvwb"); |
| + | getopt32(argv, "^" "qrfsvwb" "\0" "-1"); |
| argv += optind; | |
| if (is_modprobe) { | |
| @@ -133,7 +133,7 @@ | |
| */ | |
| #define MODPROBE_OPTS "alrDb" | |
| /* -a and -D _are_ in fact compatible */ | |
| - | #define MODPROBE_COMPLEMENTARY ("q-v:v-q:l--arD:r--alD:a--lr:D--rl") |
| + | #define MODPROBE_COMPLEMENTARY "q-v:v-q:l--arD:r--alD:a--lr:D--rl" |
| //#define MODPROBE_OPTS "acd:lnrt:C:b" | |
| //#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--acr:a--lr:r--al" | |
| enum { | |
| @@ -566,8 +566,10 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | opt_complementary = MODPROBE_COMPLEMENTARY; |
| - | opt = getopt32long(argv, INSMOD_OPTS MODPROBE_OPTS, modprobe_longopts INSMOD_ARGS); |
| + | opt = getopt32long(argv, "^" INSMOD_OPTS MODPROBE_OPTS "\0" MODPROBE_COMPLEMENTARY, |
| + | modprobe_longopts |
| + | INSMOD_ARGS |
| + | ); |
| argv += optind; | |
| /* Goto modules location */ | |
| @@ -306,9 +306,9 @@ int arping_main(int argc UNUSED_PARAM, char **argv) | |
| /* Dad also sets quit_on_reply. | |
| * Advert also sets unsolicited. | |
| */ | |
| - | opt_complementary = "=1:Df:AU"; |
| - | opt = getopt32(argv, "DUAqfbc:+w:I:s:", |
| - | &count, &str_timeout, &device, &source); |
| + | opt = getopt32(argv, "^" "DUAqfbc:+w:I:s:" "\0" "=1:Df:AU", |
| + | &count, &str_timeout, &device, &source |
| + | ); |
| if (opt & 0x80) /* -w: timeout */ | |
| timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; | |
| //if (opt & 0x200) /* -s: source */ | |
| @@ -212,8 +212,7 @@ int ether_wake_main(int argc UNUSED_PARAM, char **argv) | |
| struct whereto_t whereto; /* who to wake up */ | |
| /* handle misc user options */ | |
| - | opt_complementary = "=1"; |
| - | flags = getopt32(argv, "bi:p:", &ifname, &pass); |
| + | flags = getopt32(argv, "^" "bi:p:" "\0" "=1", &ifname, &pass); |
| if (flags & 4) /* -p */ | |
| wol_passwd_sz = get_wol_pw(pass, wol_passwd); | |
| flags &= 1; /* we further interested only in -b [bcast] flag */ | |
| @@ -1174,17 +1174,20 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |
| abs_timeout = 1 * 60 * 60; | |
| verbose_S = 0; | |
| G.timeout = 2 * 60; | |
| - | opt_complementary = "vv:SS"; |
| #if BB_MMU | |
| - | opts = getopt32(argv, "vS" |
| - | IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:"), |
| + | opts = getopt32(argv, "^" "vS" |
| + | IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:") |
| + | "\0" "vv:SS", |
| &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,) | |
| - | &G.verbose, &verbose_S); |
| + | &G.verbose, &verbose_S |
| + | ); |
| #else | |
| - | opts = getopt32(argv, "l1AvS" |
| - | IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:"), |
| + | opts = getopt32(argv, "^" "l1AvS" |
| + | IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:") |
| + | "\0" "vv:SS", |
| &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,) | |
| - | &G.verbose, &verbose_S); |
| + | &G.verbose, &verbose_S |
| + | ); |
| if (opts & (OPT_l|OPT_1)) { | |
| /* Our secret backdoor to ls */ | |
| if (fchdir(3) != 0) | |
| @@ -361,11 +361,12 @@ int ftpgetput_main(int argc UNUSED_PARAM, char **argv) | |
| /* | |
| * Decipher the command line | |
| */ | |
| - | opt_complementary = "-2:vv:cc"; /* must have 2 to 3 params; -v and -c count */ |
| + | /* must have 2 to 3 params; -v and -c count */ |
| + | #define OPTSTRING "^cvu:p:P:" "\0" "-2:?3:vv:cc" |
| #if ENABLE_FEATURE_FTPGETPUT_LONG_OPTIONS | |
| - | getopt32long(argv, "cvu:p:P:", ftpgetput_longopts, |
| + | getopt32long(argv, OPTSTRING, ftpgetput_longopts, |
| #else | |
| - | getopt32(argv, "cvu:p:P:", |
| + | getopt32(argv, OPTSTRING, |
| #endif | |
| &user, &password, &port, &verbose_flag, &do_continue | |
| ); | |
| @@ -2636,17 +2636,19 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |
| #endif | |
| home_httpd = xrealloc_getcwd_or_warn(NULL); | |
| - | /* -v counts, -i implies -f */ |
| - | opt_complementary = "vv:if"; |
| /* We do not "absolutize" path given by -h (home) opt. | |
| * If user gives relative path in -h, | |
| * $SCRIPT_FILENAME will not be set. */ | |
| - | opt = getopt32(argv, "c:d:h:" |
| + | opt = getopt32(argv, "^" |
| + | "c:d:h:" |
| IF_FEATURE_HTTPD_ENCODE_URL_STR("e:") | |
| IF_FEATURE_HTTPD_BASIC_AUTH("r:") | |
| IF_FEATURE_HTTPD_AUTH_MD5("m:") | |
| IF_FEATURE_HTTPD_SETUID("u:") | |
| - | "p:ifv", |
| + | "p:ifv" |
| + | "\0" |
| + | /* -v counts, -i implies -f */ |
| + | "vv:if", |
| &opt_c_configFile, &url_for_decode, &home_httpd | |
| IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) | |
| IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) | |
| @@ -130,8 +130,11 @@ int ipcalc_main(int argc UNUSED_PARAM, char **argv) | |
| #define ipaddr (s_ipaddr.s_addr) | |
| char *ipstr; | |
| - | opt_complementary = "-1:?2"; /* minimum 1 arg, maximum 2 args */ |
| - | opt = GETOPT32(argv, "mbn" IF_FEATURE_IPCALC_FANCY("phs") LONGOPTS); |
| + | opt = GETOPT32(argv, "^" |
| + | "mbn" IF_FEATURE_IPCALC_FANCY("phs") |
| + | "\0" "-1:?2"/*min 1, max 2 args*/ |
| + | LONGOPTS |
| + | ); |
| argv += optind; | |
| if (opt & SILENT) | |
| logmode = LOGMODE_NONE; /* suppress error_msg() output */ | |
| @@ -787,11 +787,15 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |
| e_found: | |
| // -g -G -t -r deleted, unimplemented -a deleted too | |
| - | opt_complementary = "?2:vv:ll"; /* max 2 params; -v and -l are counters; -w N */ |
| - | getopt32(argv, "np:s:uvw:+" IF_NC_SERVER("lk") |
| - | IF_NC_EXTRA("i:o:z"), |
| - | &str_p, &str_s, &o_wait |
| - | IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l)); |
| + | getopt32(argv, "^" |
| + | "np:s:uvw:+"/* -w N */ IF_NC_SERVER("lk") |
| + | IF_NC_EXTRA("i:o:z") |
| + | "\0" |
| + | "?2:vv:ll", /* max 2 params; -v and -l are counters */ |
| + | &str_p, &str_s, &o_wait |
| + | IF_NC_EXTRA(, &str_i, &str_o) |
| + | , &o_verbose IF_NC_SERVER(, &cnt_l) |
| + | ); |
| argv += optind; | |
| #if ENABLE_NC_EXTRA | |
| if (option_mask32 & OPT_i) /* line-interval time */ | |
| @@ -2230,15 +2230,16 @@ static NOINLINE void ntp_init(char **argv) | |
| /* Parse options */ | |
| peers = NULL; | |
| - | opt_complementary = "dd:wn" /* -d: counter; -p: list; -w implies -n */ |
| - | IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */ |
| - | opts = getopt32(argv, |
| + | opts = getopt32(argv, "^" |
| "nqNx" /* compat */ | |
| "wp:*S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ | |
| IF_FEATURE_NTPD_SERVER("I:") /* compat */ | |
| "d" /* compat */ | |
| "46aAbgL", /* compat, ignored */ | |
| - | &peers, &G.script_name, |
| + | "\0" |
| + | "dd:wn" /* -d: counter; -p: list; -w implies -n */ |
| + | IF_FEATURE_NTPD_SERVER(":Il") /* -I implies -l */ |
| + | , &peers, &G.script_name, |
| #if ENABLE_FEATURE_NTPD_SERVER | |
| &G.if_name, | |
| #endif | |
| @@ -340,7 +340,8 @@ static int common_ping_main(sa_family_t af, char **argv) | |
| /* Full(er) version */ | |
| - | #define OPT_STRING ("qvc:+s:t:+w:+W:+I:np:4" IF_PING6("6")) |
| + | /* -c NUM, -t NUM, -w NUM, -W NUM */ |
| + | #define OPT_STRING "qvc:+s:t:+w:+W:+I:np:4"IF_PING6("6") |
| enum { | |
| OPT_QUIET = 1 << 0, | |
| OPT_VERBOSE = 1 << 1, | |
| @@ -863,9 +864,12 @@ static int common_ping_main(int opt, char **argv) | |
| INIT_G(); | |
| - | /* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */ |
| - | opt_complementary = "=1:q--v:v--q"; |
| - | opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p); |
| + | opt |= getopt32(argv, "^" |
| + | OPT_STRING |
| + | /* exactly one arg; -v and -q don't mix */ |
| + | "\0" "=1:q--v:v--q", |
| + | &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p |
| + | ); |
| if (opt & OPT_s) | |
| datalen = xatou16(str_s); // -s | |
| if (opt & OPT_I) { // -I | |
| @@ -75,8 +75,11 @@ int pscan_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned rtt_4; | |
| unsigned start, diff; | |
| - | opt_complementary = "=1"; /* exactly one non-option */ |
| - | opt = getopt32(argv, "cbp:P:t:T:", &opt_min_port, &opt_max_port, &opt_timeout, &opt_min_rtt); |
| + | opt = getopt32(argv, "^" |
| + | "cbp:P:t:T:" |
| + | "\0" "=1", /* exactly one non-option */ |
| + | &opt_min_port, &opt_max_port, &opt_timeout, &opt_min_rtt |
| + | ); |
| argv += optind; | |
| max_port = xatou_range(opt_max_port, 1, 65535); | |
| port = xatou_range(opt_min_port, 1, max_port); | |
| @@ -128,8 +128,9 @@ int slattach_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| /* Parse command line options */ | |
| - | opt_complementary = "=1"; |
| - | opt = getopt32(argv, "p:s:c:ehmLF", &proto, &baud_str, &extcmd); |
| + | opt = getopt32(argv, "^" "p:s:c:ehmLF" "\0" "=1", |
| + | &proto, &baud_str, &extcmd |
| + | ); |
| /*argc -= optind;*/ | |
| argv += optind; | |
| @@ -269,10 +269,11 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv) | |
| tcp = (applet_name[0] == 't'); | |
| - | /* 3+ args, -i at most once, -p implies -h, -v is counter, -b N, -c N */ |
| - | opt_complementary = "-3:i--i:ph:vv"; |
| #ifdef SSLSVD | |
| - | opts = getopt32(argv, "+c:+C:i:x:u:l:Eb:+hpt:vU:/:Z:K:", |
| + | opts = getopt32(argv, "^+" |
| + | "c:+C:i:x:u:l:Eb:+hpt:vU:/:Z:K:" /* -c NUM, -b NUM */ |
| + | /* 3+ args, -i at most once, -p implies -h, -v is a counter */ |
| + | "\0" "-3:i--i:ph:vv", |
| &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname, | |
| &backlog, &str_t, &ssluser, &root, &cert, &key, &verbose | |
| ); | |
| @@ -659,13 +659,15 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv) | |
| #endif | |
| INIT_G(); | |
| - | /* -w NUM, and implies -F. -w and -i don't mix */ |
| - | IF_FEATURE_TELNETD_INETD_WAIT(opt_complementary = "wF:i--w:w--i";) |
| /* Even if !STANDALONE, we accept (and ignore) -i, thus people | |
| * don't need to guess whether it's ok to pass -i to us */ | |
| - | opt = getopt32(argv, "f:l:Ki" |
| + | opt = getopt32(argv, "^" |
| + | "f:l:Ki" |
| IF_FEATURE_TELNETD_STANDALONE("p:b:F") | |
| - | IF_FEATURE_TELNETD_INETD_WAIT("Sw:+"), |
| + | IF_FEATURE_TELNETD_INETD_WAIT("Sw:+") /* -w NUM */ |
| + | "\0" |
| + | /* -w implies -F. -w and -i don't mix */ |
| + | IF_FEATURE_TELNETD_INETD_WAIT("wF:i--w:w--i"), |
| &G.issuefile, &G.loginpath | |
| IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr) | |
| IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger) | |
| @@ -761,15 +761,16 @@ int tftp_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | /* -p or -g is mandatory, and they are mutually exclusive */ |
| - | opt_complementary = "" IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:") |
| - | IF_GETPUT("g--p:p--g:"); |
| - | |
| - | IF_GETPUT(opt =) getopt32(argv, |
| + | IF_GETPUT(opt =) getopt32(argv, "^" |
| IF_FEATURE_TFTP_GET("g") IF_FEATURE_TFTP_PUT("p") | |
| - | "l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:"), |
| + | "l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:") |
| + | "\0" |
| + | /* -p or -g is mandatory, and they are mutually exclusive */ |
| + | IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:") |
| + | IF_GETPUT("g--p:p--g:"), |
| &local_file, &remote_file | |
| - | IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)); |
| + | IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str) |
| + | ); |
| argv += optind; | |
| # if ENABLE_FEATURE_TFTP_BLOCKSIZE | |
| @@ -833,9 +833,9 @@ common_traceroute_main(int op, char **argv) | |
| INIT_G(); | |
| - | /* minimum 1 arg */ |
| - | opt_complementary = "-1:x-x"; |
| - | op |= getopt32(argv, OPT_STRING |
| + | op |= getopt32(argv, "^" |
| + | OPT_STRING |
| + | "\0" "-1:x-x" /* minimum 1 arg */ |
| , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str | |
| , &source, &waittime_str, &pausemsecs_str, &first_ttl_str | |
| ); | |
| @@ -83,10 +83,13 @@ int tunctl_main(int argc UNUSED_PARAM, char **argv) | |
| #endif | |
| }; | |
| - | opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d |
| - | opts = getopt32(argv, "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b"), |
| + | opts = getopt32(argv, "^" |
| + | "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b") |
| + | "\0" |
| + | "=0:t--d:d--t", // no arguments; t ^ d |
| &opt_device, &opt_name, &opt_name | |
| - | IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)); |
| + | IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group) |
| + | ); |
| // select device | |
| memset(&ifr, 0, sizeof(ifr)); | |
| @@ -153,9 +156,12 @@ int tunctl_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_d = 1 << 2, // delete named interface | |
| }; | |
| - | opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d |
| - | opts = getopt32(argv, "f:t:d:u:g:b", // u, g, b accepted and ignored |
| - | &opt_device, &opt_name, &opt_name, NULL, NULL); |
| + | opts = getopt32(argv, "^" |
| + | "f:t:d:u:g:b" // u, g, b accepted and ignored |
| + | "\0" |
| + | "=0:t--d:d--t", // no arguments; t ^ d |
| + | &opt_device, &opt_name, &opt_name, NULL, NULL |
| + | ); |
| // set interface name | |
| memset(&ifr, 0, sizeof(ifr)); | |
| @@ -1101,13 +1101,14 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |
| client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; | |
| /* Parse command line */ | |
| - | /* O,x: list; -T,-t,-A take numeric param */ |
| - | IF_UDHCP_VERBOSE(opt_complementary = "vv";) |
| - | opt = getopt32long(argv, "i:np:qRr:s:T:+t:+SA:+O:*ox:*f" |
| + | opt = getopt32long(argv, "^" |
| + | /* O,x: list; -T,-t,-A take numeric param */ |
| + | "i:np:qRr:s:T:+t:+SA:+O:*ox:*f" |
| USE_FOR_MMU("b") | |
| ///IF_FEATURE_UDHCPC_ARPING("a") | |
| IF_FEATURE_UDHCP_PORT("P:") | |
| "v" | |
| + | "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */ |
| , udhcpc6_longopts | |
| , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ | |
| , &client_config.script /* s */ | |
| @@ -1295,16 +1295,18 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |
| str_V = "udhcp "BB_VER; | |
| /* Parse command line */ | |
| - | /* O,x: list; -T,-t,-A take numeric param */ |
| - | IF_UDHCP_VERBOSE(opt_complementary = "vv";) |
| - | opt = getopt32long(argv, "CV:H:h:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB" |
| + | opt = getopt32long(argv, "^" |
| + | /* O,x: list; -T,-t,-A take numeric param */ |
| + | "CV:H:h:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB" |
| USE_FOR_MMU("b") | |
| IF_FEATURE_UDHCPC_ARPING("a::") | |
| IF_FEATURE_UDHCP_PORT("P:") | |
| "v" | |
| + | "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */ |
| , udhcpc_longopts | |
| , &str_V, &str_h, &str_h, &str_F | |
| - | , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ |
| + | , &client_config.interface, &client_config.pidfile /* i,p */ |
| + | , &str_r /* r */ |
| , &client_config.script /* s */ | |
| , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ | |
| , &list_O | |
| @@ -814,11 +814,12 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |
| IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) | |
| IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) | |
| + | opt = getopt32(argv, "^" |
| + | "fSI:va:"IF_FEATURE_UDHCP_PORT("P:") |
| + | "\0" |
| #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | |
| - | opt_complementary = "vv"; |
| + | "vv" |
| #endif | |
| - | opt = getopt32(argv, "fSI:va:" |
| - | IF_FEATURE_UDHCP_PORT("P:") |
| , &str_I | |
| , &str_a | |
| IF_FEATURE_UDHCP_PORT(, &str_P) | |
| @@ -54,8 +54,12 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) | |
| #endif | |
| init_unicode(); | |
| - | opt_complementary = "=0:a--r:r--a"; |
| - | opt = getopt32long(argv, "arf:d", dumpleases_longopts, &file); |
| + | opt = getopt32long(argv, "^" |
| + | "arf:d" |
| + | "\0" "=0:a--r:r--a", |
| + | dumpleases_longopts, |
| + | &file |
| + | ); |
| fd = xopen(file, O_RDONLY); | |
| @@ -1387,9 +1387,8 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") | |
| #if ENABLE_FEATURE_WGET_LONG_OPTIONS | |
| #endif | |
| - | opt_complementary = "-1" /* at least one URL */ |
| - | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ |
| - | GETOPT32(argv, "cqSO:P:Y:U:T:+" |
| + | GETOPT32(argv, "^" |
| + | "cqSO:P:Y:U:T:+" |
| /*ignored:*/ "t:" | |
| /*ignored:*/ "n::" | |
| /* 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") | |
| * "n::" above says that we accept -n[ARG]. | |
| * Specifying "n:" would be a bug: "-n ARG" would eat ARG! | |
| */ | |
| + | "\0" |
| + | "-1" /* at least one URL */ |
| + | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::") /* --header is a list */ |
| LONGOPTS | |
| , &G.fname_out, &G.dir_prefix, | |
| &G.proxy_flag, &G.user_agent, | |
| @@ -167,8 +167,7 @@ int whois_main(int argc UNUSED_PARAM, char **argv) | |
| int port = 43; | |
| const char *host = "whois.iana.org"; | |
| - | opt_complementary = "-1"; |
| - | getopt32(argv, "ih:p:+", &host, &port); |
| + | getopt32(argv, "^" "ih:p:+" "\0" "-1", &host, &port); |
| argv += optind; | |
| do { | |
| @@ -253,8 +253,9 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |
| #define QUIT (opts & 2) | |
| // Parse commandline: prog [options] ifname script | |
| // exactly 2 args; -v accumulates and implies -f | |
| - | opt_complementary = "=2:vv:vf"; |
| - | opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose); |
| + | opts = getopt32(argv, "^" "fqr:l:v" "\0" "=2:vv:vf", |
| + | &r_opt, &l_opt, &verbose |
| + | ); |
| #if !BB_MMU | |
| // on NOMMU reexec early (or else we will rerun things twice) | |
| if (!FOREGROUND) | |
| @@ -299,8 +299,7 @@ int fuser_main(int argc UNUSED_PARAM, char **argv) | |
| break; | |
| } | |
| - | opt_complementary = "-1"; /* at least one param */ |
| - | getopt32(argv, OPTION_STRING); |
| + | getopt32(argv, "^" OPTION_STRING "\0" "-1"/*at least one arg*/); |
| argv += optind; | |
| pp = argv; | |
| @@ -418,8 +418,7 @@ int iostat_main(int argc UNUSED_PARAM, char **argv) | |
| /* Parse and process arguments */ | |
| /* -k and -m are mutually exclusive */ | |
| - | opt_complementary = "k--m:m--k"; |
| - | opt = getopt32(argv, "cdtzkm"); |
| + | opt = getopt32(argv, "^" "cdtzkm" "\0" "k--m:m--k"); |
| if (!(opt & (OPT_c + OPT_d))) | |
| /* Default is -cd */ | |
| opt |= OPT_c + OPT_d; | |
| @@ -96,8 +96,7 @@ int pmap_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned opts; | |
| int ret; | |
| - | opt_complementary = "-1"; /* min one arg */ |
| - | opts = getopt32(argv, "xq"); |
| + | opts = getopt32(argv, "^" "xq" "\0" "-1"); /* min one arg */ |
| argv += optind; | |
| ret = 0; | |
| @@ -718,9 +718,11 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |
| /* -w is a bit complicated */ | |
| int w_count = 0; | |
| make_all_argv_opts(argv); | |
| - | opt_complementary = "ww"; |
| - | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") |
| - | "w", &w_count); |
| + | opts = getopt32(argv, "^" |
| + | IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")"w" |
| + | "\0" "ww", |
| + | &w_count |
| + | ); |
| /* if w is given once, GNU ps sets the width to 132, | |
| * if w is given more than once, it is "unlimited" | |
| */ | |
| @@ -386,8 +386,7 @@ int pstree_main(int argc UNUSED_PARAM, char **argv) | |
| G.output_width = get_terminal_width(0); | |
| - | opt_complementary = "?1"; |
| - | getopt32(argv, "p"); |
| + | getopt32(argv, "^" "p" "\0" "?1"); |
| argv += optind; | |
| if (argv[0]) { | |
| @@ -28,8 +28,7 @@ | |
| int pwdx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int pwdx_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| - | opt_complementary = "-1"; |
| - | getopt32(argv, ""); |
| + | getopt32(argv, "^" "" "\0" "-1"); |
| argv += optind; | |
| do { | |
| @@ -62,9 +62,9 @@ int watch_main(int argc UNUSED_PARAM, char **argv) | |
| xopen("/dev/null", O_RDONLY); | |
| #endif | |
| - | opt_complementary = "-1"; // at least one param; -n NUM |
| - | // "+": stop at first non-option (procps 3.x only) |
| - | opt = getopt32(argv, "+dtn:+", &period); |
| + | // "+": stop at first non-option (procps 3.x only); -n NUM |
| + | // at least one param |
| + | opt = getopt32(argv, "^+" "dtn:+" "\0" "-1", &period); |
| argv += optind; | |
| // watch from both procps 2.x and 3.x does concatenation. Example: | |
| @@ -301,9 +301,10 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) | |
| // FIXME: can we live with int-sized limits? | |
| // can we live with 40000 days? | |
| // if yes -> getopt converts strings to numbers for us | |
| - | opt_complementary = "-1"; |
| - | opt = getopt32(argv, "+a:+c:+d:+f:+l:+m:+o:+p:+r:+s:+t:+u:U:e:" |
| - | IF_CHPST("/:n:vP012"), |
| + | opt = getopt32(argv, "^+" |
| + | "a:+c:+d:+f:+l:+m:+o:+p:+r:+s:+t:+u:U:e:" |
| + | IF_CHPST("/:n:vP012") |
| + | "\0" "-1", |
| &limita, &limitc, &limitd, &limitf, &limitl, | |
| &limitm, &limito, &limitp, &limitr, &limits, &limitt, | |
| &set_user, &set_user, &env_dir | |
| @@ -248,10 +248,9 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | opt_complementary = "-1"; |
| opt_s_argv[0] = NULL; | |
| opt_s_argv[2] = NULL; | |
| - | getopt32(argv, "Ps:", &opt_s_argv[0]); |
| + | getopt32(argv, "^" "Ps:" "\0" "-1", &opt_s_argv[0]); |
| argv += optind; | |
| i_am_init = (getpid() == 1); | |
| @@ -506,8 +506,9 @@ static int sv(char **argv) | |
| x = getenv("SVWAIT"); | |
| if (x) waitsec = xatou(x); | |
| - | opt_complementary = "vv"; /* -w N, -v is a counter */ |
| - | getopt32(argv, "w:+v", &waitsec, &verbose); |
| + | getopt32(argv, "^" "w:+v" "\0" "vv" /* -w N, -v is a counter */, |
| + | &waitsec, &verbose |
| + | ); |
| argv += optind; | |
| action = *argv++; | |
| if (!action || !*argv) bb_show_usage(); | |
| @@ -1037,9 +1037,10 @@ int svlogd_main(int argc, char **argv) | |
| INIT_G(); | |
| - | opt_complementary = "tt:vv"; |
| - | opt = getopt32(argv, "r:R:l:b:tv", |
| - | &r, &replace, &l, &b, ×tamp, &verbose); |
| + | opt = getopt32(argv, "^" |
| + | "r:R:l:b:tv" "\0" "tt:vv", |
| + | &r, &replace, &l, &b, ×tamp, &verbose |
| + | ); |
| if (opt & 1) { // -r | |
| repl = r[0]; | |
| if (!repl || r[1]) | |
| @@ -163,13 +163,16 @@ int chcon_main(int argc UNUSED_PARAM, char **argv) | |
| char *fname; | |
| int i, errors = 0; | |
| - | opt_complementary = "-1" /* at least 1 param */ |
| - | ":?" /* error if exclusivity constraints are violated */ |
| + | getopt32long(argv, "^" |
| + | "Rchfu:r:t:l:v" |
| + | "\0" |
| + | "-1" /* at least 1 arg */ |
| + | ":?" /* error if exclusivity constraints are violated */ |
| #if ENABLE_LONG_OPTS | |
| ":\xff--urtl:u--\xff:r--\xff:t--\xff:l--\xff" | |
| #endif | |
| - | ":f--v:v--f"; /* 'verbose' and 'quiet' are exclusive */ |
| - | getopt32long(argv, "Rchfu:r:t:l:v", chcon_longopts, |
| + | ":f--v:v--f" /* 'verbose' and 'quiet' are exclusive */ |
| + | , chcon_longopts, |
| &user, &role, &type, &range, &reference_file | |
| ); | |
| argv += optind; | |
| @@ -58,9 +58,13 @@ int matchpathcon_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned opts; | |
| char *fcontext, *prefix, *path; | |
| - | opt_complementary = "-1" /* at least one param reqd */ |
| - | ":?:f--p:p--f"; /* mutually exclusive */ |
| - | opts = getopt32(argv, "nNf:p:V", &fcontext, &prefix); |
| + | opts = getopt32(argv, "^" |
| + | "nNf:p:V" |
| + | "\0" |
| + | "-1" /* at least one param reqd */ |
| + | ":?:f--p:p--f" /* mutually exclusive */ |
| + | , &fcontext, &prefix |
| + | ); |
| argv += optind; | |
| if (opts & OPT_NOT_TRANS) { | |
| @@ -126,9 +126,12 @@ int runcon_main(int argc UNUSED_PARAM, char **argv) | |
| selinux_or_die(); | |
| - | opt_complementary = "-1"; |
| - | opts = getopt32long(argv, "r:t:u:l:ch", runcon_longopts, |
| - | &role, &type, &user, &range); |
| + | opts = getopt32long(argv, "^" |
| + | "r:t:u:l:ch" |
| + | "\0" "-1", |
| + | runcon_longopts, |
| + | &role, &type, &user, &range |
| + | ); |
| argv += optind; | |
| if (!(opts & OPTS_CONTEXT_COMPONENT)) { | |
| @@ -167,8 +167,7 @@ int sestatus_main(int argc UNUSED_PARAM, char **argv) | |
| const char *pol_path; | |
| int rc; | |
| - | opt_complementary = "?0"; /* no arguments are required. */ |
| - | opts = getopt32(argv, "vb"); |
| + | opts = getopt32(argv, "^" "vb" "\0" "=0"/*no arguments*/); |
| /* SELinux status: line */ | |
| rc = is_selinux_enabled(); | |
| @@ -610,17 +610,23 @@ int setfiles_main(int argc UNUSED_PARAM, char **argv) | |
| set_matchpathcon_flags(matchpathcon_flags); | |
| - | opt_complementary = "vv:v--p:p--v:v--q:q--v"; |
| /* Option order must match OPT_x definitions! */ | |
| if (applet_name[0] == 'r') { /* restorecon */ | |
| - | flags = getopt32(argv, "de:*f:ilnpqrsvo:FWR", |
| - | &exclude_dir, &input_filename, &out_filename, &verbose); |
| + | flags = getopt32(argv, "^" |
| + | "de:*f:ilnpqrsvo:FWR", |
| + | "\0" "vv:v--p:p--v:v--q:q--v"; |
| + | &exclude_dir, &input_filename, &out_filename, |
| + | &verbose |
| + | ); |
| } else { /* setfiles */ | |
| - | flags = getopt32(argv, "de:*f:ilnpqr:svo:FW" |
| - | IF_FEATURE_SETFILES_CHECK_OPTION("c:"), |
| + | flags = getopt32(argv, "^" |
| + | "de:*f:ilnpqr:svo:FW" |
| + | IF_FEATURE_SETFILES_CHECK_OPTION("c:"), |
| + | "\0" "vv:v--p:p--v:v--q:q--v"; |
| &exclude_dir, &input_filename, &rootpath, &out_filename, | |
| - | IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) |
| - | &verbose); |
| + | IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) |
| + | &verbose |
| + | ); |
| } | |
| argv += optind; | |
| @@ -1109,8 +1109,7 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| /* No non-option params */ | |
| - | opt_complementary = "=0"; |
| - | opts = getopt32(argv, OPTION_STR, OPTION_PARAM); |
| + | opts = getopt32(argv, "^"OPTION_STR"\0""=0", OPTION_PARAM); |
| #if ENABLE_FEATURE_REMOTE_LOG | |
| while (remoteAddrList) { | |
| remoteHost_t *rh = xzalloc(sizeof(*rh)); | |
| @@ -264,8 +264,12 @@ int acpid_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | opt_complementary = "df:e--e"; |
| - | opts = getopt32(argv, "c:de:fl:a:M:" IF_FEATURE_PIDFILE("p:") IF_FEATURE_ACPID_COMPAT("g:m:s:S:v"), |
| + | opts = getopt32(argv, "^" |
| + | "c:de:fl:a:M:" |
| + | IF_FEATURE_PIDFILE("p:") |
| + | IF_FEATURE_ACPID_COMPAT("g:m:s:S:v") |
| + | "\0" |
| + | "df:e--e", |
| &opt_dir, &opt_input, &opt_logfile, &opt_action, &opt_map | |
| IF_FEATURE_PIDFILE(, &opt_pidfile) | |
| IF_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL) | |
| @@ -53,8 +53,7 @@ int blkdiscard_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_SECURE = (1 << 2), | |
| }; | |
| - | opt_complementary = "=1"; |
| - | opts = getopt32(argv, "o:l:s", &offset_str, &length_str); |
| + | opts = getopt32(argv, "^" "o:l:s" "\0" "=1", &offset_str, &length_str); |
| argv += optind; | |
| fd = xopen(argv[0], O_RDWR|O_EXCL); | |
| @@ -77,8 +77,7 @@ int chrt_main(int argc UNUSED_PARAM, char **argv) | |
| int policy = SCHED_RR; | |
| /* only one policy accepted */ | |
| - | opt_complementary = "r--fo:f--ro:o--rf"; |
| - | opt = getopt32(argv, "+mprfo"); |
| + | opt = getopt32(argv, "^+" "mprfo" "\0" "r--fo:f--ro:o--rf"); |
| if (opt & OPT_m) { /* print min/max and exit */ | |
| show_min_max(SCHED_FIFO); | |
| show_min_max(SCHED_RR); | |
| @@ -124,8 +124,9 @@ int eject_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned flags; | |
| const char *device; | |
| - | opt_complementary = "?1:t--T:T--t"; |
| - | flags = getopt32(argv, "tT" IF_FEATURE_EJECT_SCSI("s")); |
| + | flags = getopt32(argv, "^" "tT"IF_FEATURE_EJECT_SCSI("s") |
| + | "\0" "?1:t--T:T--t" |
| + | ); |
| device = argv[optind] ? argv[optind] : "/dev/cdrom"; | |
| /* We used to do "umount <device>" here, but it was buggy | |
| @@ -82,8 +82,7 @@ int fallocate_main(int argc UNUSED_PARAM, char **argv) | |
| int fd; | |
| /* exactly one non-option arg */ | |
| - | opt_complementary = "=1"; |
| - | opts = getopt32(argv, "l:o:", &str_l, &str_o); |
| + | opts = getopt32(argv, "^" "l:o:" "\0" "=1", &str_l, &str_o); |
| if (!(opts & 1)) | |
| bb_show_usage(); | |
| @@ -66,8 +66,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) | |
| struct floppy_struct param; | |
| struct format_descr descr; | |
| - | opt_complementary = "=1"; /* must have 1 param */ |
| - | verify = !getopt32(argv, "n"); |
| + | verify = !getopt32(argv, "^" "n" "\0" "=1"); |
| argv += optind; | |
| xstat(*argv, &st); | |
| @@ -45,9 +45,8 @@ int flock_main(int argc UNUSED_PARAM, char **argv) | |
| "nonblock\0" No_argument "n" | |
| ; | |
| #endif | |
| - | opt_complementary = "-1"; |
| - | opt = getopt32long(argv, "+sxnu", flock_longopts); |
| + | opt = getopt32long(argv, "^+" "sxnu" "\0" "-1", flock_longopts); |
| argv += optind; | |
| if (argv[1]) { | |
| @@ -1232,8 +1232,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | opt_complementary = "=1:ar"; /* one argument; -a assumes -r */ |
| - | getopt32(argv, OPTION_STR); |
| + | getopt32(argv, "^" OPTION_STR "\0" "=1:ar" /* one arg; -a assumes -r */); |
| argv += optind; | |
| device_name = argv[0]; | |
| @@ -39,8 +39,9 @@ int fsfreeze_main(int argc UNUSED_PARAM, char **argv) | |
| /* exactly one non-option arg: the mountpoint */ | |
| /* one of opts is required */ | |
| /* opts are mutually exclusive */ | |
| - | opt_complementary = "=1:""\xff:\xfe:""\xff--\xfe:\xfe--\xff"; |
| - | opts = getopt32long(argv, "", |
| + | opts = getopt32long(argv, "^" |
| + | "" /* no opts */ |
| + | "\0" "=1:""\xff:\xfe:""\xff--\xfe:\xfe--\xff", |
| "freeze\0" No_argument "\xff" | |
| "unfreeze\0" No_argument "\xfe" | |
| ); | |
| @@ -71,8 +71,9 @@ int fstrim_main(int argc UNUSED_PARAM, char **argv) | |
| ; | |
| #endif | |
| - | opt_complementary = "=1"; /* exactly one non-option arg: the mountpoint */ |
| - | opts = getopt32long(argv, "o:l:m:v", fstrim_longopts, &arg_o, &arg_l, &arg_m); |
| + | opts = getopt32long(argv, "^" "o:l:m:v" "\0" "=1", fstrim_longopts, |
| + | &arg_o, &arg_l, &arg_m |
| + | ); |
| memset(&range, 0, sizeof(range)); | |
| range.len = ULLONG_MAX; | |
| @@ -73,8 +73,9 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| #define OPT_s (1 << 1) | |
| #define OPT_a (1 << 2) | |
| #define OPT_p (1 << 3) | |
| - | opt_complementary = "?1"; /* 1 argument max */ |
| - | opt = getopt32(argv, "l:s:apg:+c:+", &opt_l, &opt_s, &bytes, &cols); |
| + | opt = getopt32(argv, "^" "l:s:apg:+c:+" "\0" "?1" /* 1 argument max */, |
| + | &opt_l, &opt_s, &bytes, &cols |
| + | ); |
| argv += optind; | |
| dumper->dump_vflag = ALL; | |
| @@ -343,8 +343,11 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) | |
| /* Initialize "timezone" (libc global variable) */ | |
| tzset(); | |
| - | opt_complementary = "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l"; |
| - | opt = getopt32long(argv, "lurswtf:", hwclock_longopts, &rtcname); |
| + | opt = getopt32long(argv, |
| + | "^lurswtf:" "\0" "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", |
| + | hwclock_longopts, |
| + | &rtcname |
| + | ); |
| /* If -u or -l wasn't given check if we are using utc */ | |
| if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) | |
| @@ -57,8 +57,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_r = (1 << 4), /* must be last */ | |
| }; | |
| - | opt_complementary = "?2:d--ofar:a--ofr"; |
| - | opt = getopt32(argv, "do:far", &opt_o); |
| + | opt = getopt32(argv, "^" "do:far" "\0" "?2:d--ofar:a--ofr", &opt_o); |
| argv += optind; | |
| /* LOOPDEV */ | |
| @@ -180,8 +180,7 @@ int mkfs_reiser_main(int argc UNUSED_PARAM, char **argv) | |
| // using global "option_mask32" instead of local "opts": | |
| // we are register starved here | |
| - | opt_complementary = "-1"; |
| - | /*opts =*/ getopt32(argv, "b:+j:s:o:t:B:h:u:l:fqd", |
| + | /*opts =*/ getopt32(argv, "^" "b:+j:s:o:t:B:h:u:l:fqd" "\0" "-1", |
| NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label); | |
| argv += optind; // argv[0] -- device | |
| @@ -269,8 +269,9 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_v = 1 << 16, // verbose | |
| }; | |
| - | opt_complementary = "-1";//:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c"; |
| - | opts = getopt32(argv, "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v", |
| + | opts = getopt32(argv, "^" |
| + | "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v" |
| + | "\0" "-1", //:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c |
| NULL, NULL, NULL, NULL, NULL, | |
| NULL, NULL, &volume_label, NULL, NULL, NULL, NULL); | |
| argv += optind; | |
| @@ -119,9 +119,8 @@ int mkswap_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| - | opt_complementary = "-1"; /* at least one param */ |
| /* TODO: -p PAGESZ, -U UUID */ | |
| - | getopt32(argv, "L:", &label); |
| + | getopt32(argv, "^" "L:" "\0" "-1"/*at least one arg*/, &label); |
| argv += optind; | |
| fd = xopen(argv[0], O_WRONLY); | |
| @@ -2205,10 +2205,14 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |
| // Parse remaining options | |
| // Max 2 params; -o is a list, -v is a counter | |
| - | opt_complementary = "?2" IF_FEATURE_MOUNT_VERBOSE("vv"); |
| - | opt = getopt32(argv, OPTION_STR, &lst_o, &fstype, &O_optmatch |
| - | IF_FEATURE_MOUNT_OTHERTAB(, &fstabname) |
| - | IF_FEATURE_MOUNT_VERBOSE(, &verbose)); |
| + | opt = getopt32(argv, "^" |
| + | OPTION_STR |
| + | "\0" "?2"IF_FEATURE_MOUNT_VERBOSE("vv"), |
| + | &lst_o, &fstype, &O_optmatch |
| + | IF_FEATURE_MOUNT_OTHERTAB(, &fstabname) |
| + | IF_FEATURE_MOUNT_VERBOSE(, &verbose) |
| + | ); |
| + | |
| while (lst_o) append_mount_options(&cmdopts, llist_pop(&lst_o)); // -o | |
| if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r | |
| if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w | |
| @@ -43,8 +43,7 @@ int mountpoint_main(int argc UNUSED_PARAM, char **argv) | |
| char *arg; | |
| int rc, opt; | |
| - | opt_complementary = "=1"; /* must have one argument */ |
| - | opt = getopt32(argv, "qdxn"); |
| + | opt = getopt32(argv, "^" "qdxn" "\0" "=1"); |
| #define OPT_q (1) | |
| #define OPT_d (2) | |
| #define OPT_x (4) | |
| @@ -81,8 +81,7 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) | |
| time_t remote_time; | |
| unsigned flags; | |
| - | opt_complementary = "-1"; |
| - | flags = getopt32(argv, "sp"); |
| + | flags = getopt32(argv, "^" "sp" "\0" "-1"); |
| remote_time = askremotedate(argv[optind]); | |
| @@ -155,9 +155,9 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv) | |
| "time\0" Required_argument "t" | |
| ; | |
| #endif | |
| - | /* Must have -s or -t, exclusive */ |
| - | opt_complementary = "s:t:s--t:t--s"; |
| - | opt = getopt32long(argv, "alud:m:s:t:", rtcwake_longopts, |
| + | opt = getopt32long(argv, |
| + | /* Must have -s or -t, exclusive */ |
| + | "^alud:m:s:t:" "\0" "s:t:s--t:t--s", rtcwake_longopts, |
| &rtcname, &suspend, &opt_seconds, &opt_time); | |
| /* this is the default | |
| @@ -80,8 +80,10 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |
| ; | |
| #endif | |
| - | opt_complementary = "?1"; /* max one arg */ |
| - | opt = getopt32long(argv, "ac:fqt::", script_longopts, &shell_arg, &str_t); |
| + | opt = getopt32long(argv, "^" "ac:fqt::" "\0" "?1"/* max one arg */, |
| + | script_longopts, |
| + | &shell_arg, &str_t |
| + | ); |
| //argc -= optind; | |
| argv += optind; | |
| if (argv[0]) { | |
| @@ -37,8 +37,8 @@ int setsid_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| unsigned opt; | |
| - | opt_complementary = "-1"; /* at least one arg */ |
| - | opt = getopt32(argv, "+c"); /* +: stop on first non-opt */ |
| + | /* +: stop on first non-opt */ |
| + | opt = getopt32(argv, "^+" "c" "\0" "-1"/* at least one arg */); |
| argv += optind; | |
| /* setsid() is allowed only when we are not a process group leader. | |
| @@ -97,9 +97,8 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) | |
| struct statfs stfs; | |
| dev_t rootdev; | |
| - | // Parse args (-c console) |
| - | opt_complementary = "-2"; // minimum 2 params |
| - | getopt32(argv, "+c:", &console); // '+': stop at first non-option |
| + | // Parse args (-c console). '+': stop at first non-option |
| + | getopt32(argv, "^+" "c:" "\0" "-2" /* minimum 2 args */, &console); |
| argv += optind; | |
| newroot = *argv++; | |
| @@ -123,8 +123,7 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |
| * Indeed, util-linux-2.13-pre7 uses: | |
| * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ | |
| - | opt_complementary = "-1"; /* at least 1 arg */ |
| - | opt_p = getopt32(argv, "+p"); |
| + | opt_p = getopt32(argv, "^+" "p" "\0" "-1" /* at least 1 arg */); |
| argv += optind; | |
| aff = *argv++; | |
| @@ -137,7 +137,7 @@ static const struct namespace_descr ns_list[] = { | |
| * we are forced to use "fake" letters for them. | |
| * '+': stop at first non-option. | |
| */ | |
| - | static const char opt_str[] ALIGN1 = "+muinpU""fr""\xfd::""\xfe:""\xff:"; |
| + | #define OPT_STR "+muinpU""fr""\xfd::""\xfe:""\xff:" |
| static const char unshare_longopts[] ALIGN1 = | |
| "mount\0" Optional_argument "\xf0" | |
| "uts\0" Optional_argument "\xf1" | |
| @@ -210,7 +210,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) | |
| prop_str = PRIVATE_STR; | |
| setgrp_str = NULL; | |
| - | opt_complementary = |
| + | opts = getopt32long(argv, "^" OPT_STR "\0" |
| "\xf0""m" /* long opts (via their "fake chars") imply short opts */ | |
| ":\xf1""u" | |
| ":\xf2""i" | |
| @@ -219,15 +219,14 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) | |
| ":\xf5""U" | |
| ":ru" /* --map-root-user or -r implies -u */ | |
| ":\xfd""m" /* --mount-proc implies -m */ | |
| - | ; |
| - | opts = getopt32long(argv, opt_str, unshare_longopts, |
| - | &proc_mnt_target, &prop_str, &setgrp_str, |
| - | &ns_ctx_list[NS_MNT_POS].path, |
| - | &ns_ctx_list[NS_UTS_POS].path, |
| - | &ns_ctx_list[NS_IPC_POS].path, |
| - | &ns_ctx_list[NS_NET_POS].path, |
| - | &ns_ctx_list[NS_PID_POS].path, |
| - | &ns_ctx_list[NS_USR_POS].path |
| + | , unshare_longopts, |
| + | &proc_mnt_target, &prop_str, &setgrp_str, |
| + | &ns_ctx_list[NS_MNT_POS].path, |
| + | &ns_ctx_list[NS_UTS_POS].path, |
| + | &ns_ctx_list[NS_IPC_POS].path, |
| + | &ns_ctx_list[NS_NET_POS].path, |
| + | &ns_ctx_list[NS_PID_POS].path, |
| + | &ns_ctx_list[NS_USR_POS].path |
| ); | |
| argv += optind; | |
| //bb_error_msg("opts:0x%x", opts); | |