libbb: nuke BB_GETOPT_ERROR, always die if there are mutually exclusive options

find_pair                                            164     180     +16
passwd_main                                         1222    1230      +8
display_speed                                         91      96      +5
msh_main                                            1335    1339      +4
qrealloc                                              38      36      -2
refresh                                             1190    1182      -8
cut_main                                             543     532     -11
sendCgi                                             1807    1794     -13
getopt32                                            1063    1045     -18
arith                                               2077    2030     -47
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/6 up/down: 33/-99)            Total: -66 bytes
   text    data     bss     dec     hex filename
 781548    1168   11900  794616   c1ff8 busybox_old
 781452    1168   11900  794520   c1f98 busybox_unstripped
This commit is contained in:
Denis Vlasenko 2007-07-21 13:27:44 +00:00
parent 557fb713e0
commit 091965768d
18 changed files with 28 additions and 45 deletions

View File

@ -50,7 +50,7 @@ int ar_main(int argc, char **argv)
archive_handle = init_handle(); archive_handle = init_handle();
/* Prepend '-' to the first argument if required */ /* Prepend '-' to the first argument if required */
opt_complementary = "--:p:t:x:-1:?:p--tx:t--px:x--pt"; opt_complementary = "--:p:t:x:-1:p--tx:t--px:x--pt";
opt = getopt32(argc, argv, "ptxovcr"); opt = getopt32(argc, argv, "ptxovcr");
if (opt & AR_CTX_PRINT) { if (opt & AR_CTX_PRINT) {

View File

@ -44,7 +44,7 @@ int cp_main(int argc, char **argv)
// -P and -d are the same (-P is POSIX, -d is GNU) // -P and -d are the same (-P is POSIX, -d is GNU)
// -r and -R are the same // -r and -R are the same
// -a = -pdR // -a = -pdR
opt_complementary = "?:l--s:s--l:Pd:rR:apdR"; opt_complementary = "l--s:s--l:Pd:rR:apdR";
flags = getopt32(argc, argv, FILEUTILS_CP_OPTSTR "arPHL"); flags = getopt32(argc, argv, FILEUTILS_CP_OPTSTR "arPHL");
/* Default behavior of cp is to dereference, so we don't have to do /* Default behavior of cp is to dereference, so we don't have to do
* anything special when we are given -L. * anything special when we are given -L.

View File

@ -176,8 +176,6 @@ int cut_main(int argc, char **argv)
argv += optind; argv += optind;
if (!(option_mask32 & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) if (!(option_mask32 & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
bb_error_msg_and_die("expected a list of bytes, characters, or fields"); bb_error_msg_and_die("expected a list of bytes, characters, or fields");
if (option_mask32 & BB_GETOPT_ERROR)
bb_error_msg_and_die("only one type of list may be specified");
if (option_mask32 & CUT_OPT_DELIM_FLGS) { if (option_mask32 & CUT_OPT_DELIM_FLGS) {
if (strlen(ltok) > 1) { if (strlen(ltok) > 1) {

View File

@ -51,7 +51,7 @@ int date_main(int argc, char **argv)
char *isofmt_arg; char *isofmt_arg;
char *hintfmt_arg; char *hintfmt_arg;
opt_complementary = "?:d--s:s--d" opt_complementary = "d--s:s--d"
USE_FEATURE_DATE_ISOFMT(":R--I:I--R"); USE_FEATURE_DATE_ISOFMT(":R--I:I--R");
opt = getopt32(argc, argv, "Rs:ud:r:" opt = getopt32(argc, argv, "Rs:ud:r:"
USE_FEATURE_DATE_ISOFMT("I::D:"), USE_FEATURE_DATE_ISOFMT("I::D:"),

View File

@ -20,7 +20,7 @@ enum {
}; };
/* if fn is NULL then input is stdin and output is stdout */ /* if fn is NULL then input is stdin and output is stdout */
static int convert(char *fn, int ConvType) static int convert(char *fn, int conv_type)
{ {
FILE *in, *out; FILE *in, *out;
int i; int i;
@ -52,7 +52,7 @@ static int convert(char *fn, int ConvType)
if (i == '\r') if (i == '\r')
continue; continue;
if (i == '\n') { if (i == '\n') {
if (ConvType == CT_UNIX2DOS) if (conv_type == CT_UNIX2DOS)
fputc('\r', out); fputc('\r', out);
fputc('\n', out); fputc('\n', out);
continue; continue;
@ -81,29 +81,27 @@ static int convert(char *fn, int ConvType)
int dos2unix_main(int argc, char **argv); int dos2unix_main(int argc, char **argv);
int dos2unix_main(int argc, char **argv) int dos2unix_main(int argc, char **argv)
{ {
int o, ConvType; int o, conv_type;
/* See if we are supposed to be doing dos2unix or unix2dos */ /* See if we are supposed to be doing dos2unix or unix2dos */
if (applet_name[0] == 'd') { if (applet_name[0] == 'd') {
ConvType = CT_DOS2UNIX; /* 2 */ conv_type = CT_DOS2UNIX; /* 2 */
} else { } else {
ConvType = CT_UNIX2DOS; /* 1 */ conv_type = CT_UNIX2DOS; /* 1 */
} }
/* -u and -d are mutally exclusive */
opt_complementary = "?:u--d:d--u"; /* -u convert to unix, -d convert to dos */
/* process parameters */ opt_complementary = "u--d:d--u"; /* mutally exclusive */
/* -u convert to unix */
/* -d convert to dos */
o = getopt32(argc, argv, "du"); o = getopt32(argc, argv, "du");
/* Do the conversion requested by an argument else do the default /* Do the conversion requested by an argument else do the default
* conversion depending on our name. */ * conversion depending on our name. */
if (o) if (o)
ConvType = o; conv_type = o;
do { do {
/* might be convert(NULL) if there is no filename given */ /* might be convert(NULL) if there is no filename given */
o = convert(argv[optind], ConvType); o = convert(argv[optind], conv_type);
if (o < 0) if (o < 0)
break; break;
optind++; optind++;

View File

@ -49,7 +49,7 @@ int id_main(int argc, char **argv)
#endif #endif
/* Don't allow -n -r -nr -ug -rug -nug -rnug */ /* Don't allow -n -r -nr -ug -rug -nug -rnug */
/* Don't allow more than one username */ /* Don't allow more than one username */
opt_complementary = "?1:?:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g"); opt_complementary = "?1:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g");
flags = getopt32(argc, argv, "rnug" USE_SELINUX("Z")); flags = getopt32(argc, argv, "rnug" USE_SELINUX("Z"));
/* This values could be overwritten later */ /* This values could be overwritten later */

View File

@ -99,7 +99,7 @@ int install_main(int argc, char **argv)
#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
applet_long_options = install_long_options; applet_long_options = install_long_options;
#endif #endif
opt_complementary = "?:s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z"); opt_complementary = "s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z");
/* -c exists for backwards compatibility, it's needed */ /* -c exists for backwards compatibility, it's needed */
flags = getopt32(argc, argv, "cdpsg:m:o:" USE_SELINUX("Z:"), flags = getopt32(argc, argv, "cdpsg:m:o:" USE_SELINUX("Z:"),

View File

@ -288,7 +288,7 @@ int sort_main(int argc, 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: maximum one of each */ opt_complementary = "o--o:t--t:" /* -t, -o: maximum one of each */
"k::"; /* -k takes list */ "k::"; /* -k takes list */
getopt32(argc, argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); getopt32(argc, argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t);
#if ENABLE_FEATURE_SORT_BIG #if ENABLE_FEATURE_SORT_BIG

View File

@ -254,7 +254,7 @@ int start_stop_daemon_main(int argc, char **argv)
#endif #endif
/* Check required one context option was given */ /* Check required one context option was given */
opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa"; opt_complementary = "K:S:K--S:S--K:m?p:K?xpun:S?xa";
opt = getopt32(argc, argv, "KSbqma:n:s:u:c:x:p:" opt = getopt32(argc, argv, "KSbqma:n:s:u:c:x:p:"
USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:"), USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:"),
// USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"), // USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"),

View File

@ -57,7 +57,7 @@ int cmp_main(int argc, char **argv)
xfunc_error_retval = 2; /* 1 is returned if files are different. */ xfunc_error_retval = 2; /* 1 is returned if files are different. */
opt_complementary = "?:-1" opt_complementary = "-1"
USE_DESKTOP(":?4") USE_DESKTOP(":?4")
SKIP_DESKTOP(":?2") SKIP_DESKTOP(":?2")
":l--s:s--l"; ":l--s:s--l";

View File

@ -588,8 +588,6 @@ void bb_daemonize_or_rexec(int flags, char **argv);
void bb_sanitize_stdio(void); void bb_sanitize_stdio(void);
// TODO: always error out?
enum { BB_GETOPT_ERROR = 0x80000000 };
extern const char *opt_complementary; extern const char *opt_complementary;
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
extern const struct option *applet_long_options; extern const struct option *applet_long_options;

View File

@ -150,7 +150,7 @@ int tcpudpsvd_main(int argc, char **argv)
tcp = (applet_name[0] == 't'); tcp = (applet_name[0] == 't');
/* 3+ args, -i at most once, -p implies -h, -v is counter */ /* 3+ args, -i at most once, -p implies -h, -v is counter */
opt_complementary = "-3:?:i--i:ph:vv"; opt_complementary = "-3:i--i:ph:vv";
#ifdef SSLSVD #ifdef SSLSVD
getopt32(argc, argv, "+c:C:i:x:u:l:Eb:hpt:vU:/:Z:K:", getopt32(argc, argv, "+c:C:i:x:u:l:Eb:hpt:vU:/:Z:K:",
&str_c, &str_C, &instructs, &instructs, &user, &local_hostname, &str_c, &str_C, &instructs, &instructs, &user, &local_hostname,

View File

@ -217,20 +217,12 @@ Special characters:
-b, -c and -f are mutally exclusive and should raise an error -b, -c and -f are mutally exclusive and should raise an error
if specified together. In this case you must set if specified together. In this case you must set
opt_complementary = "b--cf:c--bf:f--bc". If two of the opt_complementary = "b--cf:c--bf:f--bc". If two of the
mutually exclusive options are found, getopt32's mutually exclusive options are found, getopt32 will call
return value will have the error flag set (BB_GETOPT_ERROR) so bb_show_usage() and die.
that we can check for it:
if (flags & BB_GETOPT_ERROR)
bb_show_usage();
"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 "?" as the first char in a opt_complementary group means:
if BB_GETOPT_ERROR is detected, don't return, call bb_show_usage
and exit instead. Next char after '?' can't be a digit.
"::" A double colon after a char in opt_complementary means that the "::" 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*.
@ -476,11 +468,8 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
if (on_off->opt == 0 && c != 0) if (on_off->opt == 0 && c != 0)
bb_show_usage(); bb_show_usage();
} }
if (flags & on_off->incongruously) { if (flags & on_off->incongruously)
if ((spec_flgs & SHOW_USAGE_IF_ERROR)) bb_show_usage();
bb_show_usage();
flags |= BB_GETOPT_ERROR;
}
trigger = on_off->switch_on & on_off->switch_off; trigger = on_off->switch_on & on_off->switch_off;
flags &= ~(on_off->switch_off ^ trigger); flags &= ~(on_off->switch_off ^ trigger);
flags |= on_off->switch_on ^ trigger; flags |= on_off->switch_on ^ trigger;

View File

@ -32,7 +32,7 @@ int eject_main(int argc, char **argv)
const char *device; const char *device;
int dev, cmd; int dev, cmd;
opt_complementary = "?:?1:t--T:T--t"; opt_complementary = "?1:t--T:T--t";
flags = getopt32(argc, argv, "tT"); flags = getopt32(argc, argv, "tT");
device = argv[optind] ? : "/dev/cdrom"; device = argv[optind] ? : "/dev/cdrom";

View File

@ -210,7 +210,7 @@ int udhcpc_main(int argc, char **argv)
client_config.timeout = 3; client_config.timeout = 3;
/* Parse command line */ /* Parse command line */
opt_complementary = "?:c--C:C--c" // mutually exclusive opt_complementary = "c--C:C--c" // mutually exclusive
":hH:Hh"; // -h and -H are the same ":hH:Hh"; // -h and -H are the same
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
applet_long_options = arg_options; applet_long_options = arg_options;

View File

@ -33,7 +33,7 @@ int dumpleases_main(int argc, char **argv)
applet_long_options = options; applet_long_options = options;
#endif #endif
opt_complementary = "=0:?:a--r:r--a"; opt_complementary = "=0:a--r:r--a";
opt = getopt32(argc, argv, "arf:", &file); opt = getopt32(argc, argv, "arf:", &file);
fd = xopen(file, O_RDONLY); fd = xopen(file, O_RDONLY);

View File

@ -318,7 +318,7 @@ int getopt_main(int argc, char *argv[])
opt = getopt32(argc, argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg); opt = getopt32(argc, argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg);
#else #else
applet_long_options = longopts; applet_long_options = longopts;
opt_complementary = "?:l::"; opt_complementary = "l::";
opt = getopt32(argc, argv, "+o:n:qQs:Tual:", opt = getopt32(argc, 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 */

View File

@ -189,7 +189,7 @@ int hwclock_main(int argc, char **argv)
}; };
applet_long_options = hwclock_long_options; applet_long_options = hwclock_long_options;
#endif #endif
opt_complementary = "?:r--ws:w--rs:s--wr:l--u:u--l"; opt_complementary = "r--ws:w--rs:s--wr:l--u:u--l";
opt = getopt32(argc, argv, "lurswf:", &rtcname); opt = getopt32(argc, argv, "lurswf:", &rtcname);
/* If -u or -l wasn't given check if we are using utc */ /* If -u or -l wasn't given check if we are using utc */