getopt32: add new syntax of 'o:+' and 'o:*' for -o NUM and -o LIST
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 6 Jul 2016 19:58:02 +0000 (21:58 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 6 Jul 2016 19:58:02 +0000 (21:58 +0200)
In many cases, this aqllows to drop use of opt_complementary.
Approximately -400 bytes:

function                                             old     new   delta
getopt32                                            1423    1502     +79
opt_string                                            17      18      +1
OPT_STR                                               24      25      +1
uniq_main                                            416     406     -10
timeout_main                                         279     269     -10
sulogin_main                                         270     260     -10
readprofile_main                                    1825    1815     -10
ps_main                                              543     533     -10
pidof_main                                           245     235     -10
pgrep_main                                           611     601     -10
od_main                                             2600    2590     -10
mkfs_minix_main                                     2684    2674     -10
mkfs_ext2_main                                      2603    2593     -10
microcom_main                                        712     702     -10
makemime_main                                        315     305     -10
ionice_main                                          282     272     -10
inetd_main                                          2074    2064     -10
ifplugd_main                                        1144    1134     -10
halt_main                                            353     343     -10
getopt_main                                          636     626     -10
fdisk_main                                          2854    2844     -10
env_main                                             206     196     -10
dmesg_main                                           319     309     -10
conspy_main                                         1214    1204     -10
awk_main                                             981     971     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/22 up/down: 81/-220)         Total: -139 bytes
   text    data     bss     dec     hex filename
 919373     906   14060  934339   e41c3 busybox_old
 918969     906   14060  933935   e402f busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
58 files changed:
archival/tar.c
coreutils/du.c
coreutils/env.c
coreutils/od_bloaty.c
coreutils/sort.c
coreutils/split.c
coreutils/tail.c
coreutils/uniq.c
debianutils/run_parts.c
editors/awk.c
editors/diff.c
editors/sed.c
findutils/grep.c
init/halt.c
libbb/getopt32.c
libbb/parse_config.c
loginutils/cryptpw.c
loginutils/getty.c
loginutils/sulogin.c
mailutils/makemime.c
mailutils/popmaildir.c
mailutils/reformime.c
mailutils/sendmail.c
miscutils/conspy.c
miscutils/ionice.c
miscutils/microcom.c
miscutils/timeout.c
miscutils/ubi_tools.c
networking/arping.c
networking/ftpd.c
networking/ifplugd.c
networking/inetd.c
networking/nc_bloaty.c
networking/ntpd.c
networking/ping.c
networking/tcpudp.c
networking/telnetd.c
networking/traceroute.c
networking/udhcp/d6_dhcpc.c
networking/udhcp/dhcpc.c
networking/wget.c
networking/whois.c
procps/pgrep.c
procps/pidof.c
procps/ps.c
procps/watch.c
runit/chpst.c
runit/sv.c
selinux/setfiles.c
sysklogd/syslogd.c
util-linux/dmesg.c
util-linux/fdisk.c
util-linux/getopt.c
util-linux/mkfs_ext2.c
util-linux/mkfs_minix.c
util-linux/mkfs_reiser.c
util-linux/mount.c
util-linux/readprofile.c

index 7434e22e4028a7b086eed2f7fc6bc5ff62f79dc8..8e315c610a9d208103252d4f4f837d2c3c8daa59 100644 (file)
@@ -980,7 +980,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
        /* Prepend '-' to the first argument if required */
        opt_complementary = "--:" // first arg is options
                "tt:vv:" // count -t,-v
-               IF_FEATURE_TAR_FROM("X::T::") // cumulative lists
 #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
                "\xff::" // --exclude=PATTERN is a list
 #endif
@@ -1032,13 +1031,13 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
 #endif
        opt = getopt32(argv,
                "txC:f:Oopvk"
-               IF_FEATURE_TAR_CREATE(   "ch"  )
-               IF_FEATURE_SEAMLESS_BZ2( "j"   )
-               IF_FEATURE_SEAMLESS_LZMA("a"   )
-               IF_FEATURE_TAR_FROM(     "T:X:")
-               IF_FEATURE_SEAMLESS_GZ(  "z"   )
-               IF_FEATURE_SEAMLESS_XZ(  "J"   )
-               IF_FEATURE_SEAMLESS_Z(   "Z"   )
+               IF_FEATURE_TAR_CREATE(   "ch"    )
+               IF_FEATURE_SEAMLESS_BZ2( "j"     )
+               IF_FEATURE_SEAMLESS_LZMA("a"     )
+               IF_FEATURE_TAR_FROM(     "T:*X:*")
+               IF_FEATURE_SEAMLESS_GZ(  "z"     )
+               IF_FEATURE_SEAMLESS_XZ(  "J"     )
+               IF_FEATURE_SEAMLESS_Z(   "Z"     )
                IF_FEATURE_TAR_NOPRESERVE_TIME("m")
                IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components
                , &base_dir // -C dir
index 1240bcbbc3316f3dca93a0ad34eb9d0cd7de69b0..5f104736b0cdeed7fd7d7092fa14bb1f80de6dee 100644 (file)
@@ -226,8 +226,8 @@ 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:d+";
-       opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth);
+       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);
        argv += optind;
        if (opt & OPT_h_for_humans) {
                G.disp_unit = 0;
@@ -239,8 +239,8 @@ int du_main(int argc UNUSED_PARAM, char **argv)
                G.disp_unit = 1024;
        }
 #else
-       opt_complementary = "H-L:L-H:s-d:d-s:d+";
-       opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth);
+       opt_complementary = "H-L:L-H:s-d:d-s";
+       opt = getopt32(argv, "aHkLsx" "d:+" "lc", &G.max_print_depth);
        argv += optind;
 #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
        if (opt & OPT_k_kbytes) {
index 807ef13e9be033b488d2df6ce3c9eb9c7f2bd810..cdfc30e1424791d3c6038b910b18ffac12108ac5 100644 (file)
@@ -54,11 +54,10 @@ int env_main(int argc UNUSED_PARAM, char **argv)
        unsigned opts;
        llist_t *unset_env = NULL;
 
-       opt_complementary = "u::";
 #if ENABLE_FEATURE_ENV_LONG_OPTIONS
        applet_long_options = env_longopts;
 #endif
-       opts = getopt32(argv, "+iu:", &unset_env);
+       opts = getopt32(argv, "+iu:+", &unset_env);
        argv += optind;
        if (argv[0] && LONE_DASH(argv[0])) {
                opts |= 1;
index c8a6541654fd399ea58793db21e527ecaa9fb3f3..f13bdfc11cfb111c46f941641c3f516a27237b86 100644 (file)
@@ -62,7 +62,7 @@ enum {
 };
 
 #define OD_GETOPT32() getopt32(argv, \
-       "A:N:abcdfhij:lot:vxsS:w::", \
+       "A:N:abcdfhij:lot:*vxsS:w:+:", \
        /* -w with optional param */ \
        /* -S was -s and also had optional parameter */ \
        /* but in coreutils 6.3 it was renamed and now has */ \
@@ -1212,7 +1212,6 @@ int od_main(int argc UNUSED_PARAM, char **argv)
        address_pad_len_char = '7';
 
        /* Parse command line */
-       opt_complementary = "w+:t::"; /* -w N, -t is a list */
 #if ENABLE_LONG_OPTS
        applet_long_options = od_longopts;
 #endif
index 9139d9f4713a1617d5580a2f78178fe3107fe29f..34a41999bc3d0ed2622230d0a3209afc7d86f282 100644 (file)
@@ -73,7 +73,7 @@
 */
 
 /* These are sort types */
-static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:t:";
+static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:*t:";
 enum {
        FLAG_n  = 1,            /* Numeric sort */
        FLAG_g  = 2,            /* Sort using strtod() */
@@ -358,8 +358,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
 
        /* 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 */
-                       "k::"; /* -k takes list */
+       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);
        /* global b strips leading and trailing spaces */
        if (opts & FLAG_b)
index e67c3de6648f97044125045356ce84a44e84d80b..19d58a21b13e6e11051059d171c8b932fcb748b6 100644 (file)
@@ -81,8 +81,8 @@ int split_main(int argc UNUSED_PARAM, char **argv)
 
        setup_common_bufsiz();
 
-       opt_complementary = "?2:a+"; /* max 2 args; -a N */
-       opt = getopt32(argv, "l:b:a:", &count_p, &count_p, &suffix_len);
+       opt_complementary = "?2"; /* max 2 args; -a N */
+       opt = getopt32(argv, "l:b:a:+", &count_p, &count_p, &suffix_len);
 
        if (opt & SPLIT_OPT_l)
                cnt = XATOOFF(count_p);
index 39f87679e95db8523ddab7964269cd4786b3ebcc..57ad0f3b7a2341ead641be69c124af7a26a736c8 100644 (file)
@@ -121,8 +121,8 @@ int tail_main(int argc, char **argv)
 #endif
 
        /* -s NUM, -F imlies -f */
-       IF_FEATURE_FANCY_TAIL(opt_complementary = "s+:Ff";)
-       opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:vF"),
+       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));
 #define FOLLOW (opt & 0x1)
 #define COUNT_BYTES (opt & 0x2)
index e0133998a51b8db015b76466aa8385caf635e610..ec7bde41890048485e71a2d8f7895393832f1e68 100644 (file)
@@ -50,8 +50,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv)
        skip_fields = skip_chars = 0;
        max_chars = INT_MAX;
 
-       opt_complementary = "f+:s+:w+";
-       opt = getopt32(argv, "cduf:s:w:", &skip_fields, &skip_chars, &max_chars);
+       opt = getopt32(argv, "cduf:+s:+w:+", &skip_fields, &skip_chars, &max_chars);
        argv += optind;
 
        input_filename = argv[0];
index c671b9252abc8dc463da23e90138795daea81d5b..0bb666abc9a234d18a37c71ec27fe3aa7297e352 100644 (file)
@@ -181,8 +181,8 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv)
        applet_long_options = runparts_longopts;
 #endif
        /* We require exactly one argument: the directory name */
-       opt_complementary = "=1:a::";
-       getopt32(argv, "a:u:", &arg_list, &umask_p);
+       opt_complementary = "=1";
+       getopt32(argv, "a:*u:", &arg_list, &umask_p);
 
        umask(xstrtou_range(umask_p, 8, 0, 07777));
 
index 69816464dd7c0673a7f99c5252fc197621a2a8f6..d0269b9f43bd340d2eb5ce7fe6625fe7b9ca1ce8 100644 (file)
 
 
 #define OPTSTR_AWK \
-       "F:v:f:" \
-       IF_FEATURE_AWK_GNU_EXTENSIONS("e:") \
+       "F:v:*f:*" \
+       IF_FEATURE_AWK_GNU_EXTENSIONS("e:*") \
        "W:"
-#define OPTCOMPLSTR_AWK \
-       "v::f::" \
-       IF_FEATURE_AWK_GNU_EXTENSIONS("e::")
 enum {
        OPTBIT_F,       /* define field separator */
        OPTBIT_v,       /* define variable */
@@ -3209,7 +3206,6 @@ int awk_main(int argc, char **argv)
                        *s1 = '=';
                }
        }
-       opt_complementary = OPTCOMPLSTR_AWK;
        opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL);
        argv += optind;
        argc -= optind;
index ff269360f6d9a94f78fdd94f4eefffa3e4dcb91b..75229ad8c134d5839abca17fc13b0ea725a507b7 100644 (file)
@@ -982,11 +982,11 @@ int diff_main(int argc UNUSED_PARAM, char **argv)
        INIT_G();
 
        /* exactly 2 params; collect multiple -L <label>; -U N */
-       opt_complementary = "=2:L::U+";
+       opt_complementary = "=2";
 #if ENABLE_FEATURE_DIFF_LONG_OPTIONS
        applet_long_options = diff_longopts;
 #endif
-       getopt32(argv, "abdiL:NqrsS:tTU:wupBE",
+       getopt32(argv, "abdiL:*NqrsS:tTU:+wupBE",
                        &L_arg, &s_start, &opt_U_context);
        argv += optind;
        while (L_arg)
index f37c37d88cf37ff0429efb09579a3a5d697277fc..c0d79cc7b9e24a951053cc1fe369ebea3b0b2218 100644 (file)
@@ -1503,8 +1503,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
        /* do normal option parsing */
        opt_e = opt_f = NULL;
        opt_i = NULL;
-       opt_complementary = "e::f::" /* can occur multiple times */
-                           "nn"; /* count -n */
+       opt_complementary = "nn"; /* count -n */
 
        IF_LONG_OPTS(applet_long_options = sed_longopts);
 
@@ -1513,7 +1512,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
         * GNU sed 4.2.1 mentions it in neither --help
         * nor manpage, but does recognize it.
         */
-       opt = getopt32(argv, "i::rEne:f:", &opt_i, &opt_e, &opt_f,
+       opt = getopt32(argv, "i::rEne:*f:*", &opt_i, &opt_e, &opt_f,
                            &G.be_quiet); /* counter for -n */
        //argc -= optind;
        argv += optind;
index aeb7977e95394a0d5e5b5714de7ee0d17431bd7d..7e0120ba2171e8f4acc227d68151b601446506b7 100644 (file)
 //usage:#define fgrep_full_usage ""
 
 #define OPTSTR_GREP \
-       "lnqvscFiHhe:f:Lorm:wx" \
-       IF_FEATURE_GREP_CONTEXT("A:B:C:") \
+       "lnqvscFiHhe:*f:*Lorm:+wx" \
+       IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \
        IF_FEATURE_GREP_EGREP_ALIAS("E") \
        IF_EXTRA_COMPAT("z") \
        "aI"
@@ -695,7 +695,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
 #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:e::f::m+:A+:B+:C+";
+       opt_complementary = "H-h:C-AB";
        opts = getopt32(argv,
                OPTSTR_GREP,
                &pattern_head, &fopt, &max_matches,
@@ -724,7 +724,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:e::f::m+";
+       opt_complementary = "H-h:c-n:q-n:l-n:";
        getopt32(argv, OPTSTR_GREP,
                &pattern_head, &fopt, &max_matches);
 #endif
index 572d751b004d1a26900db770ffc3a8001120c03f..29e60657b8056f9b86b968f3a2a053bfe348cd04 100644 (file)
@@ -113,12 +113,11 @@ int halt_main(int argc UNUSED_PARAM, char **argv)
                continue;
 
        /* Parse and handle arguments */
-       opt_complementary = "d+"; /* -d N */
        /* We support -w even if !ENABLE_FEATURE_WTMP,
         * in order to not break scripts.
         * -i (shut down network interfaces) is ignored.
         */
-       flags = getopt32(argv, "d:nfwi", &delay);
+       flags = getopt32(argv, "d:+nfwi", &delay);
 
        sleep(delay);
 
index d0e83d88ee4d31090527a7f2f632907e9ebe0312..15b6efc096ba0ef04f409bcd27f37a6bfece232c 100644 (file)
 uint32_t
 getopt32(char **argv, const char *applet_opts, ...)
 
-        The command line options must be declared in const char
-        *applet_opts as a string of chars, for example:
-
-        flags = getopt32(argv, "rnug");
+        The command line options are passed as the applet_opts string.
 
         If one of the given options is found, a flag value is added to
-        the return value (an unsigned long).
+        the return value.
 
         The flag value is determined by the position of the char in
-        applet_opts string.  For example, in the above case:
+        applet_opts string.  For example:
 
         flags = getopt32(argv, "rnug");
 
-        "r" will add 1    (bit 0)
-        "n" will add 2    (bit 1)
-        "u" will add 4    (bit 2)
-        "g" will add 8    (bit 3)
+        "r" will set 1    (bit 0)
+        "n" will set 2    (bit 1)
+        "u" will set 4    (bit 2)
+        "g" will set 8    (bit 3)
 
         and so on.  You can also look at the return value as a bit
         field and each option sets one bit.
@@ -45,7 +42,7 @@ getopt32(char **argv, const char *applet_opts, ...)
         (options and their parameters will be moved into argv[]
         positions prior to argv[optind]).
 
- ":"    If one of the options requires an argument, then add a ":"
+ "o:"   If one of the options requires an argument, then add a ":"
         after the char in applet_opts and provide a pointer to store
         the argument.  For example:
 
@@ -58,15 +55,39 @@ getopt32(char **argv, const char *applet_opts, ...)
                         &pointer_to_arg_for_a, &pointer_to_arg_for_b,
                         &pointer_to_arg_for_c, &pointer_to_arg_for_d);
 
-        The type of the pointer (char* or llist_t*) may be controlled
-        by the "::" special separator that is set in the external string
-        opt_complementary (see below for more info).
+        The type of the pointer may be controlled by "o::" or "o+" in
+        the external string opt_complementary (see below for more info).
 
- "::"   If option can have an *optional* argument, then add a "::"
+ "o::"  If option can have an *optional* argument, then add a "::"
         after its char in applet_opts and provide a pointer to store
         the argument.  Note that optional arguments _must_
         immediately follow the option: -oparam, not -o param.
 
+ "o:+"  This means that the parameter for this option is a nonnegative integer.
+        It will be processed with xatoi_positive() - allowed range
+        is 0..INT_MAX.
+
+        int param;  // "unsigned param;" will also work
+        getopt32(argv, "p:+", &param);
+
+ "o:*"  This means that the option can occur multiple times. Each occurrence
+        will be saved as a llist_t element instead of char*.
+
+        For example:
+        The grep applet can have one or more "-e pattern" arguments.
+        In this case you should use getopt32() as follows:
+
+        llist_t *patterns = NULL;
+
+        (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).)
+
+        getopt32(argv, "e:*", &patterns);
+
+        $ grep -e user -e root /etc/passwd
+        root:x:0:0:root:/root:/bin/bash
+        user:x:500:500::/home/user:/bin/bash
+
  "+"    If the first character in the applet_opts string is a plus,
         then option processing will stop as soon as a non-option is
         encountered in the argv array.  Useful for applets like env
@@ -82,7 +103,7 @@ const char *applet_long_options
         This struct allows you to define long options:
 
         static const char applet_longopts[] ALIGN1 =
-                //"name\0" has_arg val
+                //"name\0"  has_arg     val
                 "verbose\0" No_argument "v"
                 ;
         applet_long_options = applet_longopts;
@@ -90,7 +111,7 @@ const char *applet_long_options
         The last member of struct option (val) typically is set to
         matching short option from applet_opts. If there is no matching
         char in applet_opts, then:
-        - return bit have next position after short options
+        - return bit has next position after short options
         - if has_arg is not "No_argument", use ptr for arg also
         - opt_complementary affects it too
 
@@ -139,8 +160,8 @@ const char *opt_complementary
 
         llist_t *my_b = NULL;
         int verbose_level = 0;
-        opt_complementary = "vv:b::b-c:c-b";
-        f = getopt32(argv, "vb:c", &my_b, &verbose_level);
+        opt_complementary = "vv:b-c:c-b";
+        f = getopt32(argv, "vb:*c", &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
@@ -233,7 +254,7 @@ Special characters:
  "x--x" Variation of the above, it means that -x option should occur
         at most once.
 
- "a+"   A plus after a char in opt_complementary means that the parameter
+ "o+"   A plus after a char in opt_complementary means that the parameter
         for this option is a nonnegative integer. It will be processed
         with xatoi_positive() - allowed range is 0..INT_MAX.
 
@@ -241,7 +262,7 @@ Special characters:
         opt_complementary = "p+";
         getopt32(argv, "p:", &param);
 
- "a::"  A double colon after a char in opt_complementary means that the
+ "o::"  A double colon after a char in opt_complementary means that the
         option can occur multiple times. Each occurrence will be saved as
         a llist_t element instead of char*.
 
@@ -255,12 +276,17 @@ Special characters:
         as required by llist_add_to_end(llist_t **old_head, char *new_item).)
 
         opt_complementary = "e::";
-
         getopt32(argv, "e:", &patterns);
+
         $ grep -e user -e root /etc/passwd
         root:x:0:0:root:/root:/bin/bash
         user:x:500:500::/home/user:/bin/bash
 
+        "o+" and "o::" can be handled by "o:+" and "o:*" specifiers
+        in option string (and it is preferred), but this does not work
+        for "long options only" cases, such as tar --exclude=PATTERN,
+        wget --header=HDR cases.
+
  "a?b"  A "?" between an option and a group of options means that
         at least one of them is required to occur if the first option
         occurs in preceding command line arguments.
@@ -359,10 +385,11 @@ getopt32(char **argv, const char *applet_opts, ...)
 
        va_start(p, applet_opts);
 
-       c = 0;
        on_off = complementary;
        memset(on_off, 0, sizeof(complementary));
 
+       applet_opts = strcpy(alloca(strlen(applet_opts) + 1), applet_opts);
+
        /* skip bbox extension */
        first_char = applet_opts[0];
        if (first_char == '!')
@@ -372,6 +399,7 @@ getopt32(char **argv, const char *applet_opts, ...)
        s = (const unsigned char *)applet_opts;
        if (*s == '+' || *s == '-')
                s++;
+       c = 0;
        while (*s) {
                if (c >= 32)
                        break;
@@ -379,6 +407,13 @@ getopt32(char **argv, const char *applet_opts, ...)
                on_off->switch_on = (1 << c);
                if (*++s == ':') {
                        on_off->optarg = va_arg(p, void **);
+                       if (s[1] == '+' || s[1] == '*') {
+                               /* 'o:+' or 'o:*' */
+                               on_off->param_type = (s[1] == '+') ?
+                                       PARAM_INT : PARAM_LIST;
+                               overlapping_strcpy((char*)s + 1, (char*)s + 2);
+                       }
+                       /* skip possible 'o::' (or 'o:+:' !) */
                        while (*++s == ':')
                                continue;
                }
@@ -431,6 +466,7 @@ getopt32(char **argv, const char *applet_opts, ...)
                applet_long_options = NULL;
        }
 #endif /* ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG */
+
        for (s = (const unsigned char *)opt_complementary; s && *s; s++) {
                t_complementary *pair;
                unsigned *pair_switch;
index 1590d9a4c0b346663b346432a67d21e90b685886..408439766269feeedb8072a594d6174d8906f2a2 100644 (file)
@@ -42,8 +42,8 @@ int parse_main(int argc UNUSED_PARAM, char **argv)
        int mintokens = 0, ntokens = 128;
        unsigned noout;
 
-       opt_complementary = "-1:n+:m+:f+";
-       noout = 1 & getopt32(argv, "xn:m:d:f:", &ntokens, &mintokens, &delims, &flags);
+       opt_complementary = "-1";
+       noout = 1 & getopt32(argv, "xn:+m:+d:f:+", &ntokens, &mintokens, &delims, &flags);
        //argc -= optind;
        argv += optind;
 
index 23a1884f4298b12585919a30c0baee5a52c9e8b3..9f5f406860357c672c52713ed200e51b5ae6cb8b 100644 (file)
@@ -111,8 +111,8 @@ 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:P+";
-       getopt32(argv, "sP:S:m:a:", &fd, &opt_S, &opt_m, &opt_m);
+       opt_complementary = "?2";
+       getopt32(argv, "sP:+S:m:a:", &fd, &opt_S, &opt_m, &opt_m);
        argv += optind;
 
        /* have no idea how to handle -s... */
index b10bdbdbf3e336c4dbd4f7172552ccc850bdf1fe..162c1697edcdef0895c60b4b94b1afd9e71eebae 100644 (file)
@@ -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";
+static const char opt_string[] ALIGN1 = "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,7 +179,7 @@ static void parse_args(char **argv)
        char *ts;
        int flags;
 
-       opt_complementary = "-2:t+"; /* at least 2 args; -t N */
+       opt_complementary = "-2"; /* at least 2 args; -t N */
        flags = getopt32(argv, opt_string,
                &G.initstring, &G.fakehost, &G.issue,
                &G.login, &G.timeout
index f324695513a0ce6f0a63c42c54ed614d0c879e49..6befea93357220ac57a1a83aadcc7c96e0355795 100644 (file)
@@ -43,8 +43,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
        logmode = LOGMODE_BOTH;
        openlog(applet_name, 0, LOG_AUTH);
 
-       opt_complementary = "t+"; /* -t N */
-       getopt32(argv, "t:", &timeout);
+       getopt32(argv, "t:+", &timeout);
        argv += optind;
 
        if (argv[0]) {
index 1dadd715f4abcb672bb9fe2fc431184fb0e355fa..8e1bc664c483e21b1be7afc718ad984ae236b207 100644 (file)
@@ -184,9 +184,8 @@ int makemime_main(int argc UNUSED_PARAM, char **argv)
        INIT_G();
 
        // parse options
-       opt_complementary = "a::";
        opts = getopt32(argv,
-               "c:e:o:C:N:a:", // "m:j:",
+               "c:e:o:C:N:a:*", // "m:j:",
                &content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL
        );
        //argc -= optind;
index 62030331e06e051c329e74526c534fbc0a094b8a..69eca61649c81c589e2fcefee15c684e5bef0fb6 100644 (file)
@@ -107,9 +107,9 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv)
        INIT_G();
 
        // parse options
-       opt_complementary = "-1:dd:t+:R+:L+:H+";
+       opt_complementary = "-1:dd";
        opts = getopt32(argv,
-               "bdmVcasTkt:" "R:Z:L:H:" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:"),
+               "bdmVcasTkt:+" "R:+Z:L:+H:+" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:"),
                &timeout, NULL, NULL, NULL, &opt_nlines
                IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same
        );
index 86b2cfed344e92c8eb6ece05d5e0e87c729d8c29..b967dfbc785c0d858f1442b6a177ba0cb98098b2 100644 (file)
@@ -265,9 +265,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" IF_FEATURE_REFORMIME_COMPAT(":m::");
+       opt_complementary = "x--X:X--x";
        opts = getopt32(argv,
-               "x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:h:o:O:"),
+               "x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:*h:o:O:"),
                &opt_prefix
                IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL)
        );
index 5143fac8f9f78bc874771780dbfa8b6284d4feb3..fb4dbb3da803761d2e95e550728fcbefdf237ce9 100644 (file)
@@ -247,11 +247,11 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv)
 
        // parse options
        // -v is a counter, -H and -S are mutually exclusive, -a is a list
-       opt_complementary = "vv:w+:H--S:S--H:a::";
+       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,
+       opts = getopt32(argv, "tf:o:iw:+H:S:a:*:v", &opt_from, NULL,
                        &timeout, &opt_connect, &opt_connect, &list, &verbose);
        //argc -= optind;
        argv += optind;
index f6468c116b7b682fe4cf27c98f8668864e83bacc..e80158e39a14a10fec042483da4c8bcac11b1050 100644 (file)
@@ -388,8 +388,8 @@ int conspy_main(int argc UNUSED_PARAM, char **argv)
        INIT_G();
        strcpy(G.vcsa_name, DEV_VCSA);
 
-       opt_complementary = "x+:y+"; // numeric params
-       opts = getopt32(argv, "vcQsndfFx:y:", &G.x, &G.y);
+       // numeric params
+       opts = getopt32(argv, "vcQsndfFx:+y:+", &G.x, &G.y);
        argv += optind;
        ttynum = 0;
        if (argv[0]) {
index 0c14256ab955837034b03a4e24b4dc8add0a8dfd..5fcb653a839485c044e17cb4f71f0882c1e48492 100644 (file)
@@ -60,9 +60,8 @@ int ionice_main(int argc UNUSED_PARAM, char **argv)
        };
 
        /* Numeric params */
-       opt_complementary = "n+:c+:p+";
        /* '+': stop at first non-option */
-       opt = getopt32(argv, "+n:c:p:", &pri, &ioclass, &pid);
+       opt = getopt32(argv, "+n:+c:+p:+", &pri, &ioclass, &pid);
        argv += optind;
 
        if (opt & OPT_c) {
index d9e8f918790e1304fb1233311675626dbac720ea..dfc9771d8b9dd2794aaae910386d00093ddf0a24 100644 (file)
@@ -64,8 +64,7 @@ int microcom_main(int argc UNUSED_PARAM, char **argv)
        unsigned opts;
 
        // fetch options
-       opt_complementary = "=1:s+:d+:t+"; // exactly one arg, numeric options
-       opts = getopt32(argv, "Xs:d:t:", &speed, &delay, &timeout);
+       opts = getopt32(argv, "Xs:+d:+t:+", &speed, &delay, &timeout);
 //     argc -= optind;
        argv += optind;
 
index 9d56593bae4e456964b66266a96039a0e43cbc57..8df9ff0fdc38fe61346f30e1937a896534a8e55b 100644 (file)
@@ -52,9 +52,8 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
        /* -p option is not documented, it is needed to support NOMMU. */
 
        /* -t SECONDS; -p PARENT_PID */
-       opt_complementary = "t+" USE_FOR_NOMMU(":p+");
        /* '+': stop at first non-option */
-       getopt32(argv, "+s:t:" USE_FOR_NOMMU("p:"), &opt_s, &timeout, &parent);
+       getopt32(argv, "+s:t:+" USE_FOR_NOMMU("p:+"), &opt_s, &timeout, &parent);
        /*argv += optind; - no, wait for bb_daemonize_or_rexec! */
        signo = get_signum(opt_s);
        if (signo < 0)
index 4364bc807f5ee5b3dd2038044b841a07a7477550..8e55e9577f54d4554aa6aa6257c9a88bfd49e988 100644 (file)
@@ -134,8 +134,8 @@ 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:d+:n+:a+:O+";
-               opts = getopt32(argv, "md:n:N:s:a:t:O:",
+               opt_complementary = "-1";
+               opts = getopt32(argv, "md:+n:+N:s:a:+t:O:+",
                                &dev_num, &vol_id,
                                &vol_name, &size_bytes_str, &alignment, &type,
                                &vid_hdr_offset
@@ -146,8 +146,8 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
                opts = getopt32(argv, "s:at", &size_bytes_str);
                opts *= OPTION_s;
        } else {
-               opt_complementary = "-1:m+:d+:n+:a+";
-               opts = getopt32(argv, "m:d:n:N:s:a:t:",
+               opt_complementary = "-1";
+               opts = getopt32(argv, "m:+d:+n:+N:s:a:+t:",
                                &mtd_num, &dev_num, &vol_id,
                                &vol_name, &size_bytes_str, &alignment, &type
                );
index 4f207eaa51b02fb3106e3344c4071da16700158b..46bd65e3610207e9c0ed8fa89c454780f0bdcf9e 100644 (file)
@@ -295,8 +295,8 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
                /* Dad also sets quit_on_reply.
                 * Advert also sets unsolicited.
                 */
-               opt_complementary = "=1:Df:AU:c+";
-               opt = getopt32(argv, "DUAqfbc:w:I:s:",
+               opt_complementary = "=1:Df:AU";
+               opt = getopt32(argv, "DUAqfbc:+w:I:s:",
                                &count, &str_timeout, &device, &source);
                if (opt & 0x80) /* -w: timeout */
                        timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000;
index 360d1e6be6901d3b7b6cd233e68d5f9b6d93b947..4cbb9b6fe8830eb0ee22c711ee45ee183ab9ca0d 100644 (file)
@@ -1130,11 +1130,11 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
        abs_timeout = 1 * 60 * 60;
        verbose_S = 0;
        G.timeout = 2 * 60;
-       opt_complementary = "t+:T+:vv:SS";
+       opt_complementary = "vv:SS";
 #if BB_MMU
-       opts = getopt32(argv,    "vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S);
+       opts = getopt32(argv,    "vS" IF_FEATURE_FTP_WRITE("w") "t:+T:+", &G.timeout, &abs_timeout, &G.verbose, &verbose_S);
 #else
-       opts = getopt32(argv, "l1AvS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S);
+       opts = getopt32(argv, "l1AvS" IF_FEATURE_FTP_WRITE("w") "t:+T:+", &G.timeout, &abs_timeout, &G.verbose, &verbose_S);
        if (opts & (OPT_l|OPT_1)) {
                /* Our secret backdoor to ls */
 /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */
index f0defb5c83e5f5f0c6a758fa1bb51b667b3b012f..28c49e218866b1221fe0da2aeac9bb0e77ab3721 100644 (file)
@@ -107,9 +107,9 @@ enum {
 #endif
 };
 #if ENABLE_FEATURE_PIDFILE
-# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:Mk"
+# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:Mk"
 #else
-# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:M"
+# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:M"
 #endif
 
 enum { // interface status
@@ -560,7 +560,6 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
 
        INIT_G();
 
-       opt_complementary = "t+:u+:d+";
        opts = getopt32(argv, OPTION_STR,
                &G.iface, &G.script_name, &G.poll_time, &G.delay_up,
                &G.delay_down, &G.api_mode, &G.extra_arg);
index 8d44b5198add30342d857ce7da4efc67125aefe3..f9295e38b1d49a5ce1ddc2e9e3ca4133fb7b875a 100644 (file)
@@ -1153,8 +1153,8 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
        if (real_uid != 0) /* run by non-root user */
                config_filename = NULL;
 
-       opt_complementary = "R+:q+"; /* -q N, -R N */
-       opt = getopt32(argv, "R:feq:", &max_concurrency, &global_queuelen);
+       /* -q N, -R N */
+       opt = getopt32(argv, "R:+feq:+", &max_concurrency, &global_queuelen);
        argv += optind;
        //argc -= optind;
        if (argv[0])
index 471ae1a12f69ce904a900ceb189cd9ac38328340..192e42fe5ced9abdd4271bd3986a8d36615fdbd0 100644 (file)
@@ -794,8 +794,8 @@ 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:w+"; /* max 2 params; -v and -l are counters; -w N */
-       getopt32(argv, "np:s:uvw:" IF_NC_SERVER("lk")
+       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));
index 8e7175063b3cea1c4f9f0fc1a9fabc24a95664a1..130cef0af0bfc30cd70dff85e04f47254ae4a8d6 100644 (file)
@@ -2197,11 +2197,11 @@ static NOINLINE void ntp_init(char **argv)
 
        /* Parse options */
        peers = NULL;
-       opt_complementary = "dd:p::wn"         /* -d: counter; -p: list; -w implies -n */
+       opt_complementary = "dd:wn"  /* -d: counter; -p: list; -w implies -n */
                IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */
        opts = getopt32(argv,
                        "nqNx" /* compat */
-                       "wp:S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */
+                       "wp:*S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */
                        IF_FEATURE_NTPD_SERVER("I:") /* compat */
                        "d" /* compat */
                        "46aAbgL", /* compat, ignored */
index d8767a39fb0cac066c1941b53e2dc160417c32e8..82d5b7a85ce2f8fc0c85939801a4de28d7cbae48 100644 (file)
@@ -341,7 +341,7 @@ 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"))
+#define OPT_STRING ("qvc:+s:t:+w:+W:+I:np:4" IF_PING6("6"))
 enum {
        OPT_QUIET = 1 << 0,
        OPT_VERBOSE = 1 << 1,
@@ -865,7 +865,7 @@ 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:c+:t+:w+:W+";
+       opt_complementary = "=1:q--v:v--q";
        opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p);
        if (opt & OPT_s)
                datalen = xatou16(str_s); // -s
index 31bc704594833f2781c2cee35ddaf1942eeb84bf..fbd1f1c45ffcce82b9c5808352693f5fc231d1ff 100644 (file)
@@ -232,9 +232,9 @@ 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:b+:c+";
+       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:",
                &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname,
                &backlog, &str_t, &ssluser, &root, &cert, &key, &verbose
        );
index 13c36aa4645ffdf32bbd0c983db82e20c204f29b..2fbdc3bb34e5554191aa1df95edb8efe6cf3bad2 100644 (file)
@@ -496,12 +496,12 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv)
        INIT_G();
 
        /* -w NUM, and implies -F. -w and -i don't mix */
-       IF_FEATURE_TELNETD_INETD_WAIT(opt_complementary = "wF:w+:i--w:w--i";)
+       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"
                        IF_FEATURE_TELNETD_STANDALONE("p:b:F")
-                       IF_FEATURE_TELNETD_INETD_WAIT("Sw:"),
+                       IF_FEATURE_TELNETD_INETD_WAIT("Sw:+"),
                        &G.issuefile, &G.loginpath
                        IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr)
                        IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger)
index eee4f8873a1230723cb05d2f23e896378742659d..e43a36dc7b5464d04172f89d9e12db5bb59f0234 100644 (file)
 
 #define OPT_STRING \
        "FIlnrdvxt:i:m:p:q:s:w:z:f:" \
-       IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \
+       IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:*") \
        "4" IF_TRACEROUTE6("6")
 enum {
        OPT_DONT_FRAGMNT = (1 << 0),    /* F */
@@ -819,7 +819,7 @@ common_traceroute_main(int op, char **argv)
        INIT_G();
 
        /* minimum 1 arg */
-       opt_complementary = "-1:x-x" IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(":g::");
+       opt_complementary = "-1:x-x";
        op |= getopt32(argv, OPT_STRING
                , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
                , &source, &waittime_str, &pausemsecs_str, &first_ttl_str
index 12f8f112505351fb98d6d1c35606f807d1d632d5..6ff040d9ed9121d9d4021cc0a560c40b1b521071 100644 (file)
@@ -944,9 +944,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
 
        /* Parse command line */
        /* O,x: list; -T,-t,-A take numeric param */
-       opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ;
+       IF_UDHCP_VERBOSE(opt_complementary = "vv";)
        IF_LONG_OPTS(applet_long_options = udhcpc6_longopts;)
-       opt = getopt32(argv, "i:np:qRr:s:T:t:SA:O:ox:f"
+       opt = getopt32(argv, "i:np:qRr:s:T:+t:+SA:+O:*ox:*f"
                USE_FOR_MMU("b")
                ///IF_FEATURE_UDHCPC_ARPING("a")
                IF_FEATURE_UDHCP_PORT("P:")
index e58acbaca40b9c0e2ec737c5e4ed92e062c3e6b0..8a16e987d412aedddc7201f756882a1418e6e3d1 100644 (file)
@@ -1283,9 +1283,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
 
        /* Parse command line */
        /* O,x: list; -T,-t,-A take numeric param */
-       opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ;
+       IF_UDHCP_VERBOSE(opt_complementary = "vv";)
        IF_LONG_OPTS(applet_long_options = udhcpc_longopts;)
-       opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB"
+       opt = getopt32(argv, "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:")
index 28c12540be1fdbeecc65d023129ab7c49b67ee30..37950ed398ddbc1810d21854103f29c623bee4be 100644 (file)
@@ -1268,9 +1268,8 @@ IF_DESKTOP(       "no-parent\0"        No_argument       "\xf0")
        applet_long_options = wget_longopts;
 #endif
        opt_complementary = "-1" /* at least one URL */
-               IF_FEATURE_WGET_TIMEOUT(":T+") /* -T NUM */
                IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */
-       getopt32(argv, "csqO:P:Y:U:T:"
+       getopt32(argv, "csqO:P:Y:U:T:+"
                /*ignored:*/ "t:"
                /*ignored:*/ "n::"
                /* wget has exactly four -n<letter> opts, all of which we can ignore:
index 6ba8dfd2009892dc3244065a9f27cfe9b4a8a3db..c9dfcf5ee424396fcf1ecfcf55b0f810868b8572 100644 (file)
@@ -167,8 +167,8 @@ int whois_main(int argc UNUSED_PARAM, char **argv)
        int port = 43;
        const char *host = "whois.iana.org";
 
-       opt_complementary = "-1:p+";
-       getopt32(argv, "ih:p:", &host, &port);
+       opt_complementary = "-1";
+       getopt32(argv, "ih:p:+", &host, &port);
        argv += optind;
 
        do {
index 1c7c7c48b8ddbb62d4b626e7973026d9522f1b3f..1c594cf9694faf7105cbbb508492a855876ce29d 100644 (file)
@@ -106,8 +106,7 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
        /* Parse remaining options */
        ppid2match = -1;
        sid2match = -1;
-       opt_complementary = "s+:P+"; /* numeric opts */
-       opt = getopt32(argv, "vlfxons:P:", &sid2match, &ppid2match);
+       opt = getopt32(argv, "vlfxons:+P:+", &sid2match, &ppid2match);
        argv += optind;
 
        if (pkill && OPT_LIST) { /* -l: print the whole signal list */
index 6d7b591093e363222928895a270bd2731596fa9d..6d265667f711231c7f5a6052385d4071b409e794 100644 (file)
@@ -51,13 +51,12 @@ int pidof_main(int argc UNUSED_PARAM, char **argv)
        unsigned opt;
 #if ENABLE_FEATURE_PIDOF_OMIT
        llist_t *omits = NULL; /* list of pids to omit */
-       opt_complementary = "o::";
 #endif
 
        /* do unconditional option parsing */
        opt = getopt32(argv, ""
                        IF_FEATURE_PIDOF_SINGLE ("s")
-                       IF_FEATURE_PIDOF_OMIT("o:", &omits));
+                       IF_FEATURE_PIDOF_OMIT("o:*", &omits));
 
 #if ENABLE_FEATURE_PIDOF_OMIT
        /* fill omit list.  */
index 08dfce12e18b43140711fe3c53df43fc2c8bd75f..ce638261a657a451114d1456eb37073c7e82ef07 100644 (file)
@@ -593,8 +593,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
         * procps v3.2.7 supports -T and shows tids as SPID column,
         * it also supports -L where it shows tids as LWP column.
         */
-       opt_complementary = "o::";
-       opt = getopt32(argv, "Zo:aAdefl"IF_FEATURE_SHOW_THREADS("T"), &opt_o);
+       opt = getopt32(argv, "Zo:*aAdefl"IF_FEATURE_SHOW_THREADS("T"), &opt_o);
        if (opt_o) {
                do {
                        parse_o(llist_pop(&opt_o));
index 97aa04767bd33de7fd56a6d1d5f166d9081e5872..20859c3cd300f77115fe328878ac68ffc923782b 100644 (file)
@@ -51,9 +51,9 @@ int watch_main(int argc UNUSED_PARAM, char **argv)
        xopen("/dev/null", O_RDONLY);
 #endif
 
-       opt_complementary = "-1:n+"; // at least one param; -n NUM
+       opt_complementary = "-1"; // at least one param; -n NUM
        // "+": stop at first non-option (procps 3.x only)
-       opt = getopt32(argv, "+dtn:", &period);
+       opt = getopt32(argv, "+dtn:+", &period);
        argv += optind;
 
        // watch from both procps 2.x and 3.x does concatenation. Example:
index 7fe5151db66ff2a81bf122475280b3b473a3e516..3769af25ef04eaaa5fbdade1284372a7ff1ca9e1 100644 (file)
@@ -300,8 +300,8 @@ 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:a+:c+:d+:f+:l+:m+:o+:p+:r+:s+:t+";
-               opt = getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:u:U:e:"
+               opt_complementary = "-1";
+               opt = getopt32(argv, "+a:+c:+d:+f:+l:+m:+o:+p:+r:+s:+t:+u:U:e:"
                        IF_CHPST("/:n:vP012"),
                        &limita, &limitc, &limitd, &limitf, &limitl,
                        &limitm, &limito, &limitp, &limitr, &limits, &limitt,
index 2a256a6b406b1d94f4816b59530d0380fb44069f..37df9a9290139a579acfeab7617895bf70498ae0 100644 (file)
@@ -474,8 +474,8 @@ int sv_main(int argc UNUSED_PARAM, char **argv)
        x = getenv("SVWAIT");
        if (x) waitsec = xatou(x);
 
-       opt_complementary = "w+:vv"; /* -w N, -v is a counter */
-       getopt32(argv, "w:v", &waitsec, &verbose);
+       opt_complementary = "vv"; /* -w N, -v is a counter */
+       getopt32(argv, "w:+v", &waitsec, &verbose);
        argv += optind;
        action = *argv++;
        if (!action || !*argv) bb_show_usage();
index 51a7e63bd741376f7dcb330e9622ba0c761f52a2..c9597d54e24d453536cea0b83ed56454af2ee646 100644 (file)
@@ -577,13 +577,13 @@ int setfiles_main(int argc UNUSED_PARAM, char **argv)
 
        set_matchpathcon_flags(matchpathcon_flags);
 
-       opt_complementary = "e::vv:v--p:p--v:v--q:q--v";
+       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",
+               flags = getopt32(argv, "de:*f:ilnpqrsvo:FWR",
                        &exclude_dir, &input_filename, &out_filename, &verbose);
        } else { /* setfiles */
-               flags = getopt32(argv, "de:f:ilnpqr:svo:FW"
+               flags = getopt32(argv, "de:*f:ilnpqr:svo:FW"
                                IF_FEATURE_SETFILES_CHECK_OPTION("c:"),
                        &exclude_dir, &input_filename, &rootpath, &out_filename,
                                IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,)
index a119bdeaeda52eec41903a033d2214b4458a1d7c..ae0840bff5fbf11c4fd4f9cd2c74d212b2124332 100644 (file)
@@ -342,7 +342,7 @@ enum {
 #define OPTION_STR "m:nO:l:S" \
        IF_FEATURE_ROTATE_LOGFILE("s:" ) \
        IF_FEATURE_ROTATE_LOGFILE("b:" ) \
-       IF_FEATURE_REMOTE_LOG(    "R:) \
+       IF_FEATURE_REMOTE_LOG(    "R:*") \
        IF_FEATURE_REMOTE_LOG(    "L"  ) \
        IF_FEATURE_IPC_SYSLOG(    "C::") \
        IF_FEATURE_SYSLOGD_DUP(   "D"  ) \
@@ -1108,8 +1108,8 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv)
 
        INIT_G();
 
-       /* No non-option params, -R can occur multiple times */
-       opt_complementary = "=0" IF_FEATURE_REMOTE_LOG(":R::");
+       /* No non-option params */
+       opt_complementary = "=0";
        opts = getopt32(argv, OPTION_STR, OPTION_PARAM);
 #if ENABLE_FEATURE_REMOTE_LOG
        while (remoteAddrList) {
index e543446c11c87e02c6d92c28518eeda796c1130c..50e8a0fce03f1cf95c3f2b9e36b20c106a37f6ff 100644 (file)
@@ -34,8 +34,7 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv)
                OPT_r = 1 << 3
        };
 
-       opt_complementary = "s+:n+"; /* numeric */
-       opts = getopt32(argv, "cs:n:r", &len, &level);
+       opts = getopt32(argv, "cs:+n:+r", &len, &level);
        if (opts & OPT_n) {
                if (klogctl(8, NULL, (long) level))
                        bb_perror_msg_and_die("klogctl");
index f49ce95a4d2cf73adbf5eef794cd6e2de789bae5..6391f9bd92dbd558ee5e0e0b077951ba168917f9 100644 (file)
@@ -2919,8 +2919,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv)
 
        close_dev_fd(); /* needed: fd 3 must not stay closed */
 
-       opt_complementary = "b+:C+:H+:S+"; /* numeric params */
-       opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"),
+       opt = getopt32(argv, "b:+C:+H:+lS:+u" IF_FEATURE_FDISK_BLKSIZE("s"),
                                &sector_size, &user_cylinders, &user_heads, &user_sectors);
        argv += optind;
        if (opt & OPT_b) {
index b9dadf13c136e181ff4960d4a7bef6504de969d4..18d49098769781ea83cbf826446e60887fa2411d 100644 (file)
@@ -397,8 +397,7 @@ int getopt_main(int argc, char **argv)
        opt = getopt32(argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg);
 #else
        applet_long_options = getopt_longopts;
-       opt_complementary = "l::";
-       opt = getopt32(argv, "+o:n:qQs:Tual:",
+       opt = getopt32(argv, "+o:n:qQs:Tual:*",
                                        &optstr, &name, &s_arg, &l_arg);
        /* Effectuate the read options for the applet itself */
        while (l_arg) {
index f91a0b4bf360eeb48a47fc0eab32277419c14732..413e7aa15cd168ea5ecd793ec2c3c5026305f0bb 100644 (file)
@@ -244,8 +244,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
 
        // using global "option_mask32" instead of local "opts":
        // we are register starved here
-       opt_complementary = "-1:b+:i+:I+:m+";
-       /*opts =*/ getopt32(argv, "cl:b:f:i:I:J:G:N:m:o:g:L:M:O:r:E:T:U:jnqvFS",
+       /*opts =*/ getopt32(argv, "cl:b:+f:i:+I:+J:G:N:m:+o:g:L:M:O:r:E:T:U:jnqvFS",
                /*lbfi:*/ NULL, &bs, NULL, &bpi,
                /*IJGN:*/ &user_inodesize, NULL, NULL, NULL,
                /*mogL:*/ &reserved_percent, NULL, NULL, &label,
index 88d797584cca03aedda8b101734b573621209cd3..aaabf8453e40b7fd093cf63ce515e4823d74a07b 100644 (file)
@@ -604,8 +604,7 @@ int mkfs_minix_main(int argc UNUSED_PARAM, char **argv)
                bb_error_msg_and_die("bad inode size");
 #endif
 
-       opt_complementary = "n+"; /* -n N */
-       opt = getopt32(argv, "ci:l:n:v", &str_i, &listfile, &G.namelen);
+       opt = getopt32(argv, "ci:l:n:+v", &str_i, &listfile, &G.namelen);
        argv += optind;
        //if (opt & 1) -c
        if (opt & 2) G.req_nr_inodes = xatoul(str_i); // -i
index 56c8f0ab52ebf0998902fd18d5125de4a58d90f8..0a31ee44f63e1356fac9a9fc9d9d869e8d9e26d2 100644 (file)
@@ -169,8 +169,8 @@ 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:b+";
-       /*opts =*/ getopt32(argv, "b:j:s:o:t:B:h:u:l:fqd",
+       opt_complementary = "-1";
+       /*opts =*/ getopt32(argv, "b:+j:s:o:t:B:h:u:l:fqd",
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label);
        argv += optind; // argv[0] -- device
 
index cef4f741597ccfbb188e1cf19bd38b03e67e2dea..13590ceb41909202a05db8ffafca4ae1c686bc6b 100644 (file)
@@ -268,7 +268,7 @@ enum {
 };
 
 
-#define OPTION_STR "o:t:rwanfvsiO:" IF_FEATURE_MOUNT_OTHERTAB("T:")
+#define OPTION_STR "o:*t:rwanfvsiO:" IF_FEATURE_MOUNT_OTHERTAB("T:")
 enum {
        OPT_o = (1 << 0),
        OPT_t = (1 << 1),
@@ -2167,7 +2167,7 @@ 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 = "?2o::" IF_FEATURE_MOUNT_VERBOSE("vv");
+       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));
index a64540464307f68a0208612e34f06b24be327c56..345b676ba1ae007bc612dd95ddfcb2579942056d 100644 (file)
@@ -99,8 +99,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
        proFile = defaultpro;
        mapFile = defaultmap;
 
-       opt_complementary = "M+"; /* -M N */
-       opt = getopt32(argv, "M:m:p:nabsirv", &multiplier, &mapFile, &proFile);
+       opt = getopt32(argv, "M:+m:p:nabsirv", &multiplier, &mapFile, &proFile);
 
        if (opt & (OPT_M|OPT_r)) { /* mult or reset, or both */
                int fd, to_write;