getopt32: add new syntax of 'o:+' and 'o:*' for -o NUM and -o LIST

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>
This commit is contained in:
Denys Vlasenko 2016-07-06 21:58:02 +02:00
parent 0844b5afe2
commit 237bedd499
58 changed files with 168 additions and 159 deletions

View File

@ -980,7 +980,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
/* Prepend '-' to the first argument if required */ /* Prepend '-' to the first argument if required */
opt_complementary = "--:" // first arg is options opt_complementary = "--:" // first arg is options
"tt:vv:" // count -t,-v "tt:vv:" // count -t,-v
IF_FEATURE_TAR_FROM("X::T::") // cumulative lists
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
"\xff::" // --exclude=PATTERN is a list "\xff::" // --exclude=PATTERN is a list
#endif #endif
@ -1032,13 +1031,13 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
#endif #endif
opt = getopt32(argv, opt = getopt32(argv,
"txC:f:Oopvk" "txC:f:Oopvk"
IF_FEATURE_TAR_CREATE( "ch" ) IF_FEATURE_TAR_CREATE( "ch" )
IF_FEATURE_SEAMLESS_BZ2( "j" ) IF_FEATURE_SEAMLESS_BZ2( "j" )
IF_FEATURE_SEAMLESS_LZMA("a" ) IF_FEATURE_SEAMLESS_LZMA("a" )
IF_FEATURE_TAR_FROM( "T:X:") IF_FEATURE_TAR_FROM( "T:*X:*")
IF_FEATURE_SEAMLESS_GZ( "z" ) IF_FEATURE_SEAMLESS_GZ( "z" )
IF_FEATURE_SEAMLESS_XZ( "J" ) IF_FEATURE_SEAMLESS_XZ( "J" )
IF_FEATURE_SEAMLESS_Z( "Z" ) IF_FEATURE_SEAMLESS_Z( "Z" )
IF_FEATURE_TAR_NOPRESERVE_TIME("m") IF_FEATURE_TAR_NOPRESERVE_TIME("m")
IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components
, &base_dir // -C dir , &base_dir // -C dir

View 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. * ignore -a. This is consistent with -s being equivalent to -d 0.
*/ */
#if ENABLE_FEATURE_HUMAN_READABLE #if ENABLE_FEATURE_HUMAN_READABLE
opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+"; 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, "aHkLsx" "d:+" "lc" "hm", &G.max_print_depth);
argv += optind; argv += optind;
if (opt & OPT_h_for_humans) { if (opt & OPT_h_for_humans) {
G.disp_unit = 0; G.disp_unit = 0;
@ -239,8 +239,8 @@ int du_main(int argc UNUSED_PARAM, char **argv)
G.disp_unit = 1024; G.disp_unit = 1024;
} }
#else #else
opt_complementary = "H-L:L-H:s-d:d-s:d+"; opt_complementary = "H-L:L-H:s-d:d-s";
opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth); opt = getopt32(argv, "aHkLsx" "d:+" "lc", &G.max_print_depth);
argv += optind; argv += optind;
#if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
if (opt & OPT_k_kbytes) { if (opt & OPT_k_kbytes) {

View File

@ -54,11 +54,10 @@ int env_main(int argc UNUSED_PARAM, char **argv)
unsigned opts; unsigned opts;
llist_t *unset_env = NULL; llist_t *unset_env = NULL;
opt_complementary = "u::";
#if ENABLE_FEATURE_ENV_LONG_OPTIONS #if ENABLE_FEATURE_ENV_LONG_OPTIONS
applet_long_options = env_longopts; applet_long_options = env_longopts;
#endif #endif
opts = getopt32(argv, "+iu:", &unset_env); opts = getopt32(argv, "+iu:+", &unset_env);
argv += optind; argv += optind;
if (argv[0] && LONE_DASH(argv[0])) { if (argv[0] && LONE_DASH(argv[0])) {
opts |= 1; opts |= 1;

View File

@ -62,7 +62,7 @@ enum {
}; };
#define OD_GETOPT32() getopt32(argv, \ #define OD_GETOPT32() getopt32(argv, \
"A:N:abcdfhij:lot:vxsS:w::", \ "A:N:abcdfhij:lot:*vxsS:w:+:", \
/* -w with optional param */ \ /* -w with optional param */ \
/* -S was -s and also had optional parameter */ \ /* -S was -s and also had optional parameter */ \
/* but in coreutils 6.3 it was renamed and now has */ \ /* 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'; address_pad_len_char = '7';
/* Parse command line */ /* Parse command line */
opt_complementary = "w+:t::"; /* -w N, -t is a list */
#if ENABLE_LONG_OPTS #if ENABLE_LONG_OPTS
applet_long_options = od_longopts; applet_long_options = od_longopts;
#endif #endif

View File

@ -73,7 +73,7 @@
*/ */
/* These are sort types */ /* 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 { enum {
FLAG_n = 1, /* Numeric sort */ FLAG_n = 1, /* Numeric sort */
FLAG_g = 2, /* Sort using strtod() */ FLAG_g = 2, /* Sort using strtod() */
@ -358,8 +358,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
/* Parse command line options */ /* Parse command line options */
/* -o and -t can be given at most once */ /* -o and -t can be given at most once */
opt_complementary = "o--o:t--t:" /* -t, -o: at most one of each */ opt_complementary = "o--o:t--t"; /* -t, -o: at most one of each */
"k::"; /* -k takes list */
opts = getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); opts = getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t);
/* global b strips leading and trailing spaces */ /* global b strips leading and trailing spaces */
if (opts & FLAG_b) if (opts & FLAG_b)

View File

@ -81,8 +81,8 @@ int split_main(int argc UNUSED_PARAM, char **argv)
setup_common_bufsiz(); setup_common_bufsiz();
opt_complementary = "?2:a+"; /* max 2 args; -a N */ 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:+", &count_p, &count_p, &suffix_len);
if (opt & SPLIT_OPT_l) if (opt & SPLIT_OPT_l)
cnt = XATOOFF(count_p); cnt = XATOOFF(count_p);

View File

@ -121,8 +121,8 @@ int tail_main(int argc, char **argv)
#endif #endif
/* -s NUM, -F imlies -f */ /* -s NUM, -F imlies -f */
IF_FEATURE_FANCY_TAIL(opt_complementary = "s+:Ff";) IF_FEATURE_FANCY_TAIL(opt_complementary = "Ff";)
opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:vF"), opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:+vF"),
&str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period)); &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period));
#define FOLLOW (opt & 0x1) #define FOLLOW (opt & 0x1)
#define COUNT_BYTES (opt & 0x2) #define COUNT_BYTES (opt & 0x2)

View File

@ -50,8 +50,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv)
skip_fields = skip_chars = 0; skip_fields = skip_chars = 0;
max_chars = INT_MAX; 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; argv += optind;
input_filename = argv[0]; input_filename = argv[0];

View File

@ -181,8 +181,8 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv)
applet_long_options = runparts_longopts; applet_long_options = runparts_longopts;
#endif #endif
/* We require exactly one argument: the directory name */ /* We require exactly one argument: the directory name */
opt_complementary = "=1:a::"; opt_complementary = "=1";
getopt32(argv, "a:u:", &arg_list, &umask_p); getopt32(argv, "a:*u:", &arg_list, &umask_p);
umask(xstrtou_range(umask_p, 8, 0, 07777)); umask(xstrtou_range(umask_p, 8, 0, 07777));

View File

@ -72,12 +72,9 @@
#define OPTSTR_AWK \ #define OPTSTR_AWK \
"F:v:f:" \ "F:v:*f:*" \
IF_FEATURE_AWK_GNU_EXTENSIONS("e:") \ IF_FEATURE_AWK_GNU_EXTENSIONS("e:*") \
"W:" "W:"
#define OPTCOMPLSTR_AWK \
"v::f::" \
IF_FEATURE_AWK_GNU_EXTENSIONS("e::")
enum { enum {
OPTBIT_F, /* define field separator */ OPTBIT_F, /* define field separator */
OPTBIT_v, /* define variable */ OPTBIT_v, /* define variable */
@ -3209,7 +3206,6 @@ int awk_main(int argc, char **argv)
*s1 = '='; *s1 = '=';
} }
} }
opt_complementary = OPTCOMPLSTR_AWK;
opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL); opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL);
argv += optind; argv += optind;
argc -= optind; argc -= optind;

View File

@ -982,11 +982,11 @@ int diff_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
/* exactly 2 params; collect multiple -L <label>; -U N */ /* exactly 2 params; collect multiple -L <label>; -U N */
opt_complementary = "=2:L::U+"; opt_complementary = "=2";
#if ENABLE_FEATURE_DIFF_LONG_OPTIONS #if ENABLE_FEATURE_DIFF_LONG_OPTIONS
applet_long_options = diff_longopts; applet_long_options = diff_longopts;
#endif #endif
getopt32(argv, "abdiL:NqrsS:tTU:wupBE", getopt32(argv, "abdiL:*NqrsS:tTU:+wupBE",
&L_arg, &s_start, &opt_U_context); &L_arg, &s_start, &opt_U_context);
argv += optind; argv += optind;
while (L_arg) while (L_arg)

View File

@ -1503,8 +1503,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
/* do normal option parsing */ /* do normal option parsing */
opt_e = opt_f = NULL; opt_e = opt_f = NULL;
opt_i = NULL; opt_i = NULL;
opt_complementary = "e::f::" /* can occur multiple times */ opt_complementary = "nn"; /* count -n */
"nn"; /* count -n */
IF_LONG_OPTS(applet_long_options = sed_longopts); 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 * GNU sed 4.2.1 mentions it in neither --help
* nor manpage, but does recognize it. * 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 */ &G.be_quiet); /* counter for -n */
//argc -= optind; //argc -= optind;
argv += optind; argv += optind;

View File

@ -115,8 +115,8 @@
//usage:#define fgrep_full_usage "" //usage:#define fgrep_full_usage ""
#define OPTSTR_GREP \ #define OPTSTR_GREP \
"lnqvscFiHhe:f:Lorm:wx" \ "lnqvscFiHhe:*f:*Lorm:+wx" \
IF_FEATURE_GREP_CONTEXT("A:B:C:") \ IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \
IF_FEATURE_GREP_EGREP_ALIAS("E") \ IF_FEATURE_GREP_EGREP_ALIAS("E") \
IF_EXTRA_COMPAT("z") \ IF_EXTRA_COMPAT("z") \
"aI" "aI"
@ -695,7 +695,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
#if ENABLE_FEATURE_GREP_CONTEXT #if ENABLE_FEATURE_GREP_CONTEXT
/* -H unsets -h; -C unsets -A,-B; -e,-f are lists; /* -H unsets -h; -C unsets -A,-B; -e,-f are lists;
* -m,-A,-B,-C have numeric param */ * -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, opts = getopt32(argv,
OPTSTR_GREP, OPTSTR_GREP,
&pattern_head, &fopt, &max_matches, &pattern_head, &fopt, &max_matches,
@ -724,7 +724,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
#else #else
/* with auto sanity checks */ /* with auto sanity checks */
/* -H unsets -h; -c,-q or -l unset -n; -e,-f are lists; -m N */ /* -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, getopt32(argv, OPTSTR_GREP,
&pattern_head, &fopt, &max_matches); &pattern_head, &fopt, &max_matches);
#endif #endif

View File

@ -113,12 +113,11 @@ int halt_main(int argc UNUSED_PARAM, char **argv)
continue; continue;
/* Parse and handle arguments */ /* Parse and handle arguments */
opt_complementary = "d+"; /* -d N */
/* We support -w even if !ENABLE_FEATURE_WTMP, /* We support -w even if !ENABLE_FEATURE_WTMP,
* in order to not break scripts. * in order to not break scripts.
* -i (shut down network interfaces) is ignored. * -i (shut down network interfaces) is ignored.
*/ */
flags = getopt32(argv, "d:nfwi", &delay); flags = getopt32(argv, "d:+nfwi", &delay);
sleep(delay); sleep(delay);

View File

@ -17,23 +17,20 @@
uint32_t uint32_t
getopt32(char **argv, const char *applet_opts, ...) getopt32(char **argv, const char *applet_opts, ...)
The command line options must be declared in const char The command line options are passed as the applet_opts string.
*applet_opts as a string of chars, for example:
flags = getopt32(argv, "rnug");
If one of the given options is found, a flag value is added to 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 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"); flags = getopt32(argv, "rnug");
"r" will add 1 (bit 0) "r" will set 1 (bit 0)
"n" will add 2 (bit 1) "n" will set 2 (bit 1)
"u" will add 4 (bit 2) "u" will set 4 (bit 2)
"g" will add 8 (bit 3) "g" will set 8 (bit 3)
and so on. You can also look at the return value as a bit and so on. You can also look at the return value as a bit
field and each option sets one 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[] (options and their parameters will be moved into argv[]
positions prior to argv[optind]). 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 after the char in applet_opts and provide a pointer to store
the argument. For example: 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_a, &pointer_to_arg_for_b,
&pointer_to_arg_for_c, &pointer_to_arg_for_d); &pointer_to_arg_for_c, &pointer_to_arg_for_d);
The type of the pointer (char* or llist_t*) may be controlled The type of the pointer may be controlled by "o::" or "o+" in
by the "::" special separator that is set in the external string the external string opt_complementary (see below for more info).
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 after its char in applet_opts and provide a pointer to store
the argument. Note that optional arguments _must_ the argument. Note that optional arguments _must_
immediately follow the option: -oparam, not -o param. 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, "+" If the first character in the applet_opts string is a plus,
then option processing will stop as soon as a non-option is then option processing will stop as soon as a non-option is
encountered in the argv array. Useful for applets like env 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: This struct allows you to define long options:
static const char applet_longopts[] ALIGN1 = static const char applet_longopts[] ALIGN1 =
//"name\0" has_arg val //"name\0" has_arg val
"verbose\0" No_argument "v" "verbose\0" No_argument "v"
; ;
applet_long_options = applet_longopts; 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 The last member of struct option (val) typically is set to
matching short option from applet_opts. If there is no matching matching short option from applet_opts. If there is no matching
char in applet_opts, then: 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 - if has_arg is not "No_argument", use ptr for arg also
- opt_complementary affects it too - opt_complementary affects it too
@ -139,8 +160,8 @@ const char *opt_complementary
llist_t *my_b = NULL; llist_t *my_b = NULL;
int verbose_level = 0; int verbose_level = 0;
opt_complementary = "vv:b::b-c:c-b"; opt_complementary = "vv:b-c:c-b";
f = getopt32(argv, "vb:c", &my_b, &verbose_level); f = getopt32(argv, "vb:*c", &my_b, &verbose_level);
if (f & 2) // -c after -b unsets -b flag if (f & 2) // -c after -b unsets -b flag
while (my_b) dosomething_with(llist_pop(&my_b)); while (my_b) dosomething_with(llist_pop(&my_b));
if (my_b) // but llist is stored if -b is specified 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 "x--x" Variation of the above, it means that -x option should occur
at most once. 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 for this option is a nonnegative integer. It will be processed
with xatoi_positive() - allowed range is 0..INT_MAX. with xatoi_positive() - allowed range is 0..INT_MAX.
@ -241,7 +262,7 @@ Special characters:
opt_complementary = "p+"; opt_complementary = "p+";
getopt32(argv, "p:", &param); 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 option can occur multiple times. Each occurrence will be saved as
a llist_t element instead of char*. 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).) as required by llist_add_to_end(llist_t **old_head, char *new_item).)
opt_complementary = "e::"; opt_complementary = "e::";
getopt32(argv, "e:", &patterns); getopt32(argv, "e:", &patterns);
$ grep -e user -e root /etc/passwd $ grep -e user -e root /etc/passwd
root:x:0:0:root:/root:/bin/bash root:x:0:0:root:/root:/bin/bash
user:x:500:500::/home/user:/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 "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 at least one of them is required to occur if the first option
occurs in preceding command line arguments. occurs in preceding command line arguments.
@ -359,10 +385,11 @@ getopt32(char **argv, const char *applet_opts, ...)
va_start(p, applet_opts); va_start(p, applet_opts);
c = 0;
on_off = complementary; on_off = complementary;
memset(on_off, 0, sizeof(complementary)); memset(on_off, 0, sizeof(complementary));
applet_opts = strcpy(alloca(strlen(applet_opts) + 1), applet_opts);
/* skip bbox extension */ /* skip bbox extension */
first_char = applet_opts[0]; first_char = applet_opts[0];
if (first_char == '!') if (first_char == '!')
@ -372,6 +399,7 @@ getopt32(char **argv, const char *applet_opts, ...)
s = (const unsigned char *)applet_opts; s = (const unsigned char *)applet_opts;
if (*s == '+' || *s == '-') if (*s == '+' || *s == '-')
s++; s++;
c = 0;
while (*s) { while (*s) {
if (c >= 32) if (c >= 32)
break; break;
@ -379,6 +407,13 @@ getopt32(char **argv, const char *applet_opts, ...)
on_off->switch_on = (1 << c); on_off->switch_on = (1 << c);
if (*++s == ':') { if (*++s == ':') {
on_off->optarg = va_arg(p, void **); 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 == ':') while (*++s == ':')
continue; continue;
} }
@ -431,6 +466,7 @@ getopt32(char **argv, const char *applet_opts, ...)
applet_long_options = NULL; applet_long_options = NULL;
} }
#endif /* ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG */ #endif /* ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG */
for (s = (const unsigned char *)opt_complementary; s && *s; s++) { for (s = (const unsigned char *)opt_complementary; s && *s; s++) {
t_complementary *pair; t_complementary *pair;
unsigned *pair_switch; unsigned *pair_switch;

View File

@ -42,8 +42,8 @@ int parse_main(int argc UNUSED_PARAM, char **argv)
int mintokens = 0, ntokens = 128; int mintokens = 0, ntokens = 128;
unsigned noout; unsigned noout;
opt_complementary = "-1:n+:m+:f+"; opt_complementary = "-1";
noout = 1 & getopt32(argv, "xn:m:d:f:", &ntokens, &mintokens, &delims, &flags); noout = 1 & getopt32(argv, "xn:+m:+d:f:+", &ntokens, &mintokens, &delims, &flags);
//argc -= optind; //argc -= optind;
argv += optind; argv += optind;

View File

@ -111,8 +111,8 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv)
opt_m = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO; opt_m = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO;
opt_S = NULL; opt_S = NULL;
/* at most two non-option arguments; -P NUM */ /* at most two non-option arguments; -P NUM */
opt_complementary = "?2:P+"; opt_complementary = "?2";
getopt32(argv, "sP:S:m:a:", &fd, &opt_S, &opt_m, &opt_m); getopt32(argv, "sP:+S:m:a:", &fd, &opt_S, &opt_m, &opt_m);
argv += optind; argv += optind;
/* have no idea how to handle -s... */ /* have no idea how to handle -s... */

View File

@ -131,7 +131,7 @@ struct globals {
//usage: "\n" //usage: "\n"
//usage: "\nBAUD_RATE of 0 leaves it unchanged" //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_INITSTRING (1 << 0) /* -I */
#define F_LOCAL (1 << 1) /* -L */ #define F_LOCAL (1 << 1) /* -L */
#define F_FAKEHOST (1 << 2) /* -H */ #define F_FAKEHOST (1 << 2) /* -H */
@ -179,7 +179,7 @@ static void parse_args(char **argv)
char *ts; char *ts;
int flags; 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, flags = getopt32(argv, opt_string,
&G.initstring, &G.fakehost, &G.issue, &G.initstring, &G.fakehost, &G.issue,
&G.login, &G.timeout &G.login, &G.timeout

View File

@ -43,8 +43,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
logmode = LOGMODE_BOTH; logmode = LOGMODE_BOTH;
openlog(applet_name, 0, LOG_AUTH); openlog(applet_name, 0, LOG_AUTH);
opt_complementary = "t+"; /* -t N */ getopt32(argv, "t:+", &timeout);
getopt32(argv, "t:", &timeout);
argv += optind; argv += optind;
if (argv[0]) { if (argv[0]) {

View File

@ -184,9 +184,8 @@ int makemime_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
// parse options // parse options
opt_complementary = "a::";
opts = getopt32(argv, 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 &content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL
); );
//argc -= optind; //argc -= optind;

View File

@ -107,9 +107,9 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
// parse options // parse options
opt_complementary = "-1:dd:t+:R+:L+:H+"; opt_complementary = "-1:dd";
opts = getopt32(argv, 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 &timeout, NULL, NULL, NULL, &opt_nlines
IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same
); );

View File

@ -265,9 +265,9 @@ int reformime_main(int argc UNUSED_PARAM, char **argv)
// parse options // parse options
// N.B. only -x and -X are supported so far // 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, 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 &opt_prefix
IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL) IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL)
); );

View File

@ -247,11 +247,11 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv)
// parse options // parse options
// -v is a counter, -H and -S are mutually exclusive, -a is a list // -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 // 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, // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility,
// it is still under development. // 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); &timeout, &opt_connect, &opt_connect, &list, &verbose);
//argc -= optind; //argc -= optind;
argv += optind; argv += optind;

View File

@ -388,8 +388,8 @@ int conspy_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
strcpy(G.vcsa_name, DEV_VCSA); strcpy(G.vcsa_name, DEV_VCSA);
opt_complementary = "x+:y+"; // numeric params // numeric params
opts = getopt32(argv, "vcQsndfFx:y:", &G.x, &G.y); opts = getopt32(argv, "vcQsndfFx:+y:+", &G.x, &G.y);
argv += optind; argv += optind;
ttynum = 0; ttynum = 0;
if (argv[0]) { if (argv[0]) {

View File

@ -60,9 +60,8 @@ int ionice_main(int argc UNUSED_PARAM, char **argv)
}; };
/* Numeric params */ /* Numeric params */
opt_complementary = "n+:c+:p+";
/* '+': stop at first non-option */ /* '+': 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; argv += optind;
if (opt & OPT_c) { if (opt & OPT_c) {

View File

@ -64,8 +64,7 @@ int microcom_main(int argc UNUSED_PARAM, char **argv)
unsigned opts; unsigned opts;
// fetch options // 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; // argc -= optind;
argv += optind; argv += optind;

View 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. */ /* -p option is not documented, it is needed to support NOMMU. */
/* -t SECONDS; -p PARENT_PID */ /* -t SECONDS; -p PARENT_PID */
opt_complementary = "t+" USE_FOR_NOMMU(":p+");
/* '+': stop at first non-option */ /* '+': 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! */ /*argv += optind; - no, wait for bb_daemonize_or_rexec! */
signo = get_signum(opt_s); signo = get_signum(opt_s);
if (signo < 0) if (signo < 0)

View File

@ -134,8 +134,8 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
#define OPTION_a (1 << 5) #define OPTION_a (1 << 5)
#define OPTION_t (1 << 6) #define OPTION_t (1 << 6)
if (do_mkvol) { if (do_mkvol) {
opt_complementary = "-1:d+:n+:a+:O+"; opt_complementary = "-1";
opts = getopt32(argv, "md:n:N:s:a:t:O:", opts = getopt32(argv, "md:+n:+N:s:a:+t:O:+",
&dev_num, &vol_id, &dev_num, &vol_id,
&vol_name, &size_bytes_str, &alignment, &type, &vol_name, &size_bytes_str, &alignment, &type,
&vid_hdr_offset &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 = getopt32(argv, "s:at", &size_bytes_str);
opts *= OPTION_s; opts *= OPTION_s;
} else { } else {
opt_complementary = "-1:m+:d+:n+:a+"; opt_complementary = "-1";
opts = getopt32(argv, "m:d:n:N:s:a:t:", opts = getopt32(argv, "m:+d:+n:+N:s:a:+t:",
&mtd_num, &dev_num, &vol_id, &mtd_num, &dev_num, &vol_id,
&vol_name, &size_bytes_str, &alignment, &type &vol_name, &size_bytes_str, &alignment, &type
); );

View File

@ -295,8 +295,8 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
/* Dad also sets quit_on_reply. /* Dad also sets quit_on_reply.
* Advert also sets unsolicited. * Advert also sets unsolicited.
*/ */
opt_complementary = "=1:Df:AU:c+"; opt_complementary = "=1:Df:AU";
opt = getopt32(argv, "DUAqfbc:w:I:s:", opt = getopt32(argv, "DUAqfbc:+w:I:s:",
&count, &str_timeout, &device, &source); &count, &str_timeout, &device, &source);
if (opt & 0x80) /* -w: timeout */ if (opt & 0x80) /* -w: timeout */
timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000; timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000;

View File

@ -1130,11 +1130,11 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
abs_timeout = 1 * 60 * 60; abs_timeout = 1 * 60 * 60;
verbose_S = 0; verbose_S = 0;
G.timeout = 2 * 60; G.timeout = 2 * 60;
opt_complementary = "t+:T+:vv:SS"; opt_complementary = "vv:SS";
#if BB_MMU #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 #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)) { if (opts & (OPT_l|OPT_1)) {
/* Our secret backdoor to ls */ /* Our secret backdoor to ls */
/* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */

View File

@ -107,9 +107,9 @@ enum {
#endif #endif
}; };
#if ENABLE_FEATURE_PIDFILE #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 #else
# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:M" # define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:M"
#endif #endif
enum { // interface status enum { // interface status
@ -560,7 +560,6 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
opt_complementary = "t+:u+:d+";
opts = getopt32(argv, OPTION_STR, opts = getopt32(argv, OPTION_STR,
&G.iface, &G.script_name, &G.poll_time, &G.delay_up, &G.iface, &G.script_name, &G.poll_time, &G.delay_up,
&G.delay_down, &G.api_mode, &G.extra_arg); &G.delay_down, &G.api_mode, &G.extra_arg);

View File

@ -1153,8 +1153,8 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
if (real_uid != 0) /* run by non-root user */ if (real_uid != 0) /* run by non-root user */
config_filename = NULL; config_filename = NULL;
opt_complementary = "R+:q+"; /* -q N, -R N */ /* -q N, -R N */
opt = getopt32(argv, "R:feq:", &max_concurrency, &global_queuelen); opt = getopt32(argv, "R:+feq:+", &max_concurrency, &global_queuelen);
argv += optind; argv += optind;
//argc -= optind; //argc -= optind;
if (argv[0]) if (argv[0])

View File

@ -794,8 +794,8 @@ int nc_main(int argc UNUSED_PARAM, char **argv)
e_found: e_found:
// -g -G -t -r deleted, unimplemented -a deleted too // -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 */ opt_complementary = "?2:vv:ll"; /* max 2 params; -v and -l are counters; -w N */
getopt32(argv, "np:s:uvw:" IF_NC_SERVER("lk") getopt32(argv, "np:s:uvw:+" IF_NC_SERVER("lk")
IF_NC_EXTRA("i:o:z"), IF_NC_EXTRA("i:o:z"),
&str_p, &str_s, &o_wait &str_p, &str_s, &o_wait
IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l)); IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l));

View File

@ -2197,11 +2197,11 @@ static NOINLINE void ntp_init(char **argv)
/* Parse options */ /* Parse options */
peers = NULL; 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 */ IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */
opts = getopt32(argv, opts = getopt32(argv,
"nqNx" /* compat */ "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 */ IF_FEATURE_NTPD_SERVER("I:") /* compat */
"d" /* compat */ "d" /* compat */
"46aAbgL", /* compat, ignored */ "46aAbgL", /* compat, ignored */

View File

@ -341,7 +341,7 @@ static int common_ping_main(sa_family_t af, char **argv)
/* Full(er) version */ /* 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 { enum {
OPT_QUIET = 1 << 0, OPT_QUIET = 1 << 0,
OPT_VERBOSE = 1 << 1, OPT_VERBOSE = 1 << 1,
@ -865,7 +865,7 @@ static int common_ping_main(int opt, char **argv)
INIT_G(); INIT_G();
/* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */ /* 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); opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p);
if (opt & OPT_s) if (opt & OPT_s)
datalen = xatou16(str_s); // -s datalen = xatou16(str_s); // -s

View File

@ -232,9 +232,9 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
tcp = (applet_name[0] == 't'); tcp = (applet_name[0] == 't');
/* 3+ args, -i at most once, -p implies -h, -v is counter, -b N, -c N */ /* 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 #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, &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname,
&backlog, &str_t, &ssluser, &root, &cert, &key, &verbose &backlog, &str_t, &ssluser, &root, &cert, &key, &verbose
); );

View File

@ -496,12 +496,12 @@ int telnetd_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
/* -w NUM, and implies -F. -w and -i don't mix */ /* -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 /* Even if !STANDALONE, we accept (and ignore) -i, thus people
* don't need to guess whether it's ok to pass -i to us */ * 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_STANDALONE("p:b:F")
IF_FEATURE_TELNETD_INETD_WAIT("Sw:"), IF_FEATURE_TELNETD_INETD_WAIT("Sw:+"),
&G.issuefile, &G.loginpath &G.issuefile, &G.loginpath
IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr) IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr)
IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger) IF_FEATURE_TELNETD_INETD_WAIT(, &sec_linger)

View File

@ -294,7 +294,7 @@
#define OPT_STRING \ #define OPT_STRING \
"FIlnrdvxt:i:m:p:q:s:w:z:f:" \ "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") "4" IF_TRACEROUTE6("6")
enum { enum {
OPT_DONT_FRAGMNT = (1 << 0), /* F */ OPT_DONT_FRAGMNT = (1 << 0), /* F */
@ -819,7 +819,7 @@ common_traceroute_main(int op, char **argv)
INIT_G(); INIT_G();
/* minimum 1 arg */ /* minimum 1 arg */
opt_complementary = "-1:x-x" IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(":g::"); opt_complementary = "-1:x-x";
op |= getopt32(argv, OPT_STRING op |= getopt32(argv, OPT_STRING
, &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str
, &source, &waittime_str, &pausemsecs_str, &first_ttl_str , &source, &waittime_str, &pausemsecs_str, &first_ttl_str

View File

@ -944,9 +944,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* Parse command line */ /* Parse command line */
/* O,x: list; -T,-t,-A take numeric param */ /* 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;) 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") USE_FOR_MMU("b")
///IF_FEATURE_UDHCPC_ARPING("a") ///IF_FEATURE_UDHCPC_ARPING("a")
IF_FEATURE_UDHCP_PORT("P:") IF_FEATURE_UDHCP_PORT("P:")

View File

@ -1283,9 +1283,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
/* Parse command line */ /* Parse command line */
/* O,x: list; -T,-t,-A take numeric param */ /* 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;) 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") USE_FOR_MMU("b")
IF_FEATURE_UDHCPC_ARPING("a::") IF_FEATURE_UDHCPC_ARPING("a::")
IF_FEATURE_UDHCP_PORT("P:") IF_FEATURE_UDHCP_PORT("P:")

View File

@ -1268,9 +1268,8 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0")
applet_long_options = wget_longopts; applet_long_options = wget_longopts;
#endif #endif
opt_complementary = "-1" /* at least one URL */ opt_complementary = "-1" /* at least one URL */
IF_FEATURE_WGET_TIMEOUT(":T+") /* -T NUM */
IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ 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:*/ "t:"
/*ignored:*/ "n::" /*ignored:*/ "n::"
/* wget has exactly four -n<letter> opts, all of which we can ignore: /* wget has exactly four -n<letter> opts, all of which we can ignore:

View File

@ -167,8 +167,8 @@ int whois_main(int argc UNUSED_PARAM, char **argv)
int port = 43; int port = 43;
const char *host = "whois.iana.org"; const char *host = "whois.iana.org";
opt_complementary = "-1:p+"; opt_complementary = "-1";
getopt32(argv, "ih:p:", &host, &port); getopt32(argv, "ih:p:+", &host, &port);
argv += optind; argv += optind;
do { do {

View File

@ -106,8 +106,7 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
/* Parse remaining options */ /* Parse remaining options */
ppid2match = -1; ppid2match = -1;
sid2match = -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; argv += optind;
if (pkill && OPT_LIST) { /* -l: print the whole signal list */ if (pkill && OPT_LIST) { /* -l: print the whole signal list */

View File

@ -51,13 +51,12 @@ int pidof_main(int argc UNUSED_PARAM, char **argv)
unsigned opt; unsigned opt;
#if ENABLE_FEATURE_PIDOF_OMIT #if ENABLE_FEATURE_PIDOF_OMIT
llist_t *omits = NULL; /* list of pids to omit */ llist_t *omits = NULL; /* list of pids to omit */
opt_complementary = "o::";
#endif #endif
/* do unconditional option parsing */ /* do unconditional option parsing */
opt = getopt32(argv, "" opt = getopt32(argv, ""
IF_FEATURE_PIDOF_SINGLE ("s") IF_FEATURE_PIDOF_SINGLE ("s")
IF_FEATURE_PIDOF_OMIT("o:", &omits)); IF_FEATURE_PIDOF_OMIT("o:*", &omits));
#if ENABLE_FEATURE_PIDOF_OMIT #if ENABLE_FEATURE_PIDOF_OMIT
/* fill omit list. */ /* fill omit list. */

View 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, * procps v3.2.7 supports -T and shows tids as SPID column,
* it also supports -L where it shows tids as LWP 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) { if (opt_o) {
do { do {
parse_o(llist_pop(&opt_o)); parse_o(llist_pop(&opt_o));

View File

@ -51,9 +51,9 @@ int watch_main(int argc UNUSED_PARAM, char **argv)
xopen("/dev/null", O_RDONLY); xopen("/dev/null", O_RDONLY);
#endif #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) // "+": stop at first non-option (procps 3.x only)
opt = getopt32(argv, "+dtn:", &period); opt = getopt32(argv, "+dtn:+", &period);
argv += optind; argv += optind;
// watch from both procps 2.x and 3.x does concatenation. Example: // watch from both procps 2.x and 3.x does concatenation. Example:

View File

@ -300,8 +300,8 @@ int chpst_main(int argc UNUSED_PARAM, char **argv)
// FIXME: can we live with int-sized limits? // FIXME: can we live with int-sized limits?
// can we live with 40000 days? // can we live with 40000 days?
// if yes -> getopt converts strings to numbers for us // if yes -> getopt converts strings to numbers for us
opt_complementary = "-1:a+:c+:d+:f+:l+:m+:o+:p+:r+:s+:t+"; opt_complementary = "-1";
opt = getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:u:U:e:" opt = getopt32(argv, "+a:+c:+d:+f:+l:+m:+o:+p:+r:+s:+t:+u:U:e:"
IF_CHPST("/:n:vP012"), IF_CHPST("/:n:vP012"),
&limita, &limitc, &limitd, &limitf, &limitl, &limita, &limitc, &limitd, &limitf, &limitl,
&limitm, &limito, &limitp, &limitr, &limits, &limitt, &limitm, &limito, &limitp, &limitr, &limits, &limitt,

View File

@ -474,8 +474,8 @@ int sv_main(int argc UNUSED_PARAM, char **argv)
x = getenv("SVWAIT"); x = getenv("SVWAIT");
if (x) waitsec = xatou(x); if (x) waitsec = xatou(x);
opt_complementary = "w+:vv"; /* -w N, -v is a counter */ opt_complementary = "vv"; /* -w N, -v is a counter */
getopt32(argv, "w:v", &waitsec, &verbose); getopt32(argv, "w:+v", &waitsec, &verbose);
argv += optind; argv += optind;
action = *argv++; action = *argv++;
if (!action || !*argv) bb_show_usage(); if (!action || !*argv) bb_show_usage();

View File

@ -577,13 +577,13 @@ int setfiles_main(int argc UNUSED_PARAM, char **argv)
set_matchpathcon_flags(matchpathcon_flags); 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! */ /* Option order must match OPT_x definitions! */
if (applet_name[0] == 'r') { /* restorecon */ 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); &exclude_dir, &input_filename, &out_filename, &verbose);
} else { /* setfiles */ } else { /* setfiles */
flags = getopt32(argv, "de:f:ilnpqr:svo:FW" flags = getopt32(argv, "de:*f:ilnpqr:svo:FW"
IF_FEATURE_SETFILES_CHECK_OPTION("c:"), IF_FEATURE_SETFILES_CHECK_OPTION("c:"),
&exclude_dir, &input_filename, &rootpath, &out_filename, &exclude_dir, &input_filename, &rootpath, &out_filename,
IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,)

View File

@ -342,7 +342,7 @@ enum {
#define OPTION_STR "m:nO:l:S" \ #define OPTION_STR "m:nO:l:S" \
IF_FEATURE_ROTATE_LOGFILE("s:" ) \ IF_FEATURE_ROTATE_LOGFILE("s:" ) \
IF_FEATURE_ROTATE_LOGFILE("b:" ) \ IF_FEATURE_ROTATE_LOGFILE("b:" ) \
IF_FEATURE_REMOTE_LOG( "R:" ) \ IF_FEATURE_REMOTE_LOG( "R:*") \
IF_FEATURE_REMOTE_LOG( "L" ) \ IF_FEATURE_REMOTE_LOG( "L" ) \
IF_FEATURE_IPC_SYSLOG( "C::") \ IF_FEATURE_IPC_SYSLOG( "C::") \
IF_FEATURE_SYSLOGD_DUP( "D" ) \ IF_FEATURE_SYSLOGD_DUP( "D" ) \
@ -1108,8 +1108,8 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
/* No non-option params, -R can occur multiple times */ /* No non-option params */
opt_complementary = "=0" IF_FEATURE_REMOTE_LOG(":R::"); opt_complementary = "=0";
opts = getopt32(argv, OPTION_STR, OPTION_PARAM); opts = getopt32(argv, OPTION_STR, OPTION_PARAM);
#if ENABLE_FEATURE_REMOTE_LOG #if ENABLE_FEATURE_REMOTE_LOG
while (remoteAddrList) { while (remoteAddrList) {

View File

@ -34,8 +34,7 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv)
OPT_r = 1 << 3 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 (opts & OPT_n) {
if (klogctl(8, NULL, (long) level)) if (klogctl(8, NULL, (long) level))
bb_perror_msg_and_die("klogctl"); bb_perror_msg_and_die("klogctl");

View File

@ -2919,8 +2919,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv)
close_dev_fd(); /* needed: fd 3 must not stay closed */ 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); &sector_size, &user_cylinders, &user_heads, &user_sectors);
argv += optind; argv += optind;
if (opt & OPT_b) { if (opt & OPT_b) {

View File

@ -397,8 +397,7 @@ int getopt_main(int argc, char **argv)
opt = getopt32(argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg); opt = getopt32(argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg);
#else #else
applet_long_options = getopt_longopts; 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); &optstr, &name, &s_arg, &l_arg);
/* Effectuate the read options for the applet itself */ /* Effectuate the read options for the applet itself */
while (l_arg) { while (l_arg) {

View File

@ -244,8 +244,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
// using global "option_mask32" instead of local "opts": // using global "option_mask32" instead of local "opts":
// we are register starved here // 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, /*lbfi:*/ NULL, &bs, NULL, &bpi,
/*IJGN:*/ &user_inodesize, NULL, NULL, NULL, /*IJGN:*/ &user_inodesize, NULL, NULL, NULL,
/*mogL:*/ &reserved_percent, NULL, NULL, &label, /*mogL:*/ &reserved_percent, NULL, NULL, &label,

View File

@ -604,8 +604,7 @@ int mkfs_minix_main(int argc UNUSED_PARAM, char **argv)
bb_error_msg_and_die("bad inode size"); bb_error_msg_and_die("bad inode size");
#endif #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; argv += optind;
//if (opt & 1) -c //if (opt & 1) -c
if (opt & 2) G.req_nr_inodes = xatoul(str_i); // -i if (opt & 2) G.req_nr_inodes = xatoul(str_i); // -i

View File

@ -169,8 +169,8 @@ int mkfs_reiser_main(int argc UNUSED_PARAM, char **argv)
// using global "option_mask32" instead of local "opts": // using global "option_mask32" instead of local "opts":
// we are register starved here // we are register starved here
opt_complementary = "-1:b+"; 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",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label); NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label);
argv += optind; // argv[0] -- device argv += optind; // argv[0] -- device

View 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 { enum {
OPT_o = (1 << 0), OPT_o = (1 << 0),
OPT_t = (1 << 1), OPT_t = (1 << 1),
@ -2167,7 +2167,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
// Parse remaining options // Parse remaining options
// Max 2 params; -o is a list, -v is a counter // 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 opt = getopt32(argv, OPTION_STR, &lst_o, &fstype, &O_optmatch
IF_FEATURE_MOUNT_OTHERTAB(, &fstabname) IF_FEATURE_MOUNT_OTHERTAB(, &fstabname)
IF_FEATURE_MOUNT_VERBOSE(, &verbose)); IF_FEATURE_MOUNT_VERBOSE(, &verbose));

View File

@ -99,8 +99,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
proFile = defaultpro; proFile = defaultpro;
mapFile = defaultmap; 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 */ if (opt & (OPT_M|OPT_r)) { /* mult or reset, or both */
int fd, to_write; int fd, to_write;