rework long option handling. saves ~1.2k

function                                             old     new   delta
tar_longopts                                           -     222    +222
static.udhcpc_longopts                                 -     192    +192
start_stop_daemon_longopts                             -     150    +150
getopt32                                            1045    1185    +140
static.wget_longopts                                   -     111    +111
static.od_longopts                                     -     105    +105
getopt_longopts                                        -      96     +96
install_longopts                                       -      67     +67
ipcalc_longopts                                        -      63     +63
static.hwclock_longopts                                -      54     +54
ftpgetput_longopts                                     -      52     +52
static.dumpleases_longopts                             -      32     +32
env_longopts                                           -      31     +31
runparts_longopts                                      -      30     +30
mv_longopts                                            -      24     +24
mkdir_longopts                                         -      19     +19
find_pair                                            164     180     +16
bb_null_long_options                                   -      16     +16
setconsole_longopts                                    -      10     +10
display_speed                                         91      98      +7
collect_blk                                          467     474      +7
show_color                                             4       1      -3
ls_main                                              913     904      -9
bb_default_long_options                               16       -     -16
ls_color_opt                                          32      10     -22
setconsole_long_options                               32       -     -32
arith                                               2077    2030     -47
mv_long_options                                       48       -     -48
mkdir_long_options                                    48       -     -48
env_long_options                                      48       -     -48
static.options                                       248     184     -64
runparts_long_options                                 80       -     -80
ftpgetput_long_options                                96       -     -96
static.hwclock_long_options                          112       -    -112
install_long_options                                 112       -    -112
static.long_options                                  144       -    -144
static.wget_long_options                             160       -    -160
longopts                                             160       -    -160
static.arg_options                                   304       -    -304
tar_long_options                                     320       -    -320
long_options                                         384       -    -384
------------------------------------------------------------------------------
(add/remove: 17/15 grow/shrink: 4/5 up/down: 1444/-2209)     Total: -765 bytes
   text    data     bss     dec     hex filename
 782618    1328   11900  795846   c24c6 busybox_old
 781354    1328   11900  794582   c1fd6 busybox_unstripped
This commit is contained in:
Denis Vlasenko 2007-07-23 17:14:14 +00:00
parent 9fe9c1a6d8
commit bdc88fdc68
22 changed files with 255 additions and 250 deletions

View File

@ -715,45 +715,44 @@ enum {
OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions
}; };
#if ENABLE_FEATURE_TAR_LONG_OPTIONS #if ENABLE_FEATURE_TAR_LONG_OPTIONS
static const struct option tar_long_options[] = { static const char tar_longopts[] =
{ "list", 0, NULL, 't' }, "list\0" No_argument "t"
{ "extract", 0, NULL, 'x' }, "extract\0" No_argument "x"
{ "directory", 1, NULL, 'C' }, "directory\0" Required_argument "C"
{ "file", 1, NULL, 'f' }, "file\0" Required_argument "f"
{ "to-stdout", 0, NULL, 'O' }, "to-stdout\0" No_argument "O"
{ "same-permissions", 0, NULL, 'p' }, "same-permissions\0" No_argument "p"
{ "verbose", 0, NULL, 'v' }, "verbose\0" No_argument "v"
{ "keep-old", 0, NULL, 'k' }, "keep-old\0" No_argument "k"
# if ENABLE_FEATURE_TAR_CREATE # if ENABLE_FEATURE_TAR_CREATE
{ "create", 0, NULL, 'c' }, "create\0" No_argument "c"
{ "dereference", 0, NULL, 'h' }, "dereference\0" No_argument "h"
# endif # endif
# if ENABLE_FEATURE_TAR_BZIP2 # if ENABLE_FEATURE_TAR_BZIP2
{ "bzip2", 0, NULL, 'j' }, "bzip2\0" No_argument "j"
# endif # endif
# if ENABLE_FEATURE_TAR_LZMA # if ENABLE_FEATURE_TAR_LZMA
{ "lzma", 0, NULL, 'a' }, "lzma\0" No_argument "a"
# endif # endif
# if ENABLE_FEATURE_TAR_FROM # if ENABLE_FEATURE_TAR_FROM
{ "files-from", 1, NULL, 'T' }, "files-from\0" Required_argument "T"
{ "exclude-from", 1, NULL, 'X' }, "exclude-from\0" Required_argument "X"
# endif # endif
# if ENABLE_FEATURE_TAR_GZIP # if ENABLE_FEATURE_TAR_GZIP
{ "gzip", 0, NULL, 'z' }, "gzip\0" No_argument "z"
# endif # endif
# if ENABLE_FEATURE_TAR_COMPRESS # if ENABLE_FEATURE_TAR_COMPRESS
{ "compress", 0, NULL, 'Z' }, "compress\0" No_argument "Z"
# endif # endif
{ "no-same-owner", 0, NULL, 0xfd }, "no-same-owner\0" No_argument "\xfd"
{ "no-same-permissions",0, NULL, 0xfe }, "no-same-permissions\0" No_argument "\xfe"
/* --exclude takes next bit position in option mask, */ /* --exclude takes next bit position in option mask, */
/* therefore we have to either put it _after_ --no-same-perm */ /* therefore we have to either put it _after_ --no-same-perm */
/* or add OPT[BIT]_EXCLUDE before OPT[BIT]_NOPRESERVE_OWN */ /* or add OPT[BIT]_EXCLUDE before OPT[BIT]_NOPRESERVE_OWN */
# if ENABLE_FEATURE_TAR_FROM # if ENABLE_FEATURE_TAR_FROM
{ "exclude", 1, NULL, 0xff }, "exclude\0" Required_argument "\xff"
# endif # endif
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
int tar_main(int argc, char **argv); int tar_main(int argc, char **argv);
@ -787,7 +786,7 @@ int tar_main(int argc, char **argv)
USE_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive USE_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
SKIP_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive SKIP_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive
#if ENABLE_FEATURE_TAR_LONG_OPTIONS #if ENABLE_FEATURE_TAR_LONG_OPTIONS
applet_long_options = tar_long_options; applet_long_options = tar_longopts;
#endif #endif
opt = getopt32(argc, argv, opt = getopt32(argc, argv,
"txC:f:Opvk" "txC:f:Opvk"

View File

@ -11,10 +11,9 @@
#include "libbb.h" #include "libbb.h"
#if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS #if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS
static const struct option setconsole_long_options[] = { static const char setconsole_longopts[] =
{ "reset", 0, NULL, 'r' }, "reset\0" No_argument "r"
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
#define OPT_SETCONS_RESET 1 #define OPT_SETCONS_RESET 1
@ -26,7 +25,7 @@ int setconsole_main(int argc, char **argv)
const char *device = CURRENT_TTY; const char *device = CURRENT_TTY;
#if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS #if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS
applet_long_options = setconsole_long_options; applet_long_options = setconsole_longopts;
#endif #endif
flags = getopt32(argc, argv, "r"); flags = getopt32(argc, argv, "r");

View File

@ -35,11 +35,10 @@ extern char **environ;
#include "libbb.h" #include "libbb.h"
#if ENABLE_FEATURE_ENV_LONG_OPTIONS #if ENABLE_FEATURE_ENV_LONG_OPTIONS
static const struct option env_long_options[] = { static const char env_longopts[] =
{ "ignore-environment", 0, NULL, 'i' }, "ignore-environment\0" No_argument "i"
{ "unset", 1, NULL, 'u' }, "unset\0" Required_argument "u"
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
int env_main(int argc, char** argv); int env_main(int argc, char** argv);
@ -53,7 +52,7 @@ int env_main(int argc, char** argv)
opt_complementary = "u::"; opt_complementary = "u::";
#if ENABLE_FEATURE_ENV_LONG_OPTIONS #if ENABLE_FEATURE_ENV_LONG_OPTIONS
applet_long_options = env_long_options; applet_long_options = env_longopts;
#endif #endif
opt = getopt32(argc, argv, "+iu:", &unset_env); opt = getopt32(argc, argv, "+iu:", &unset_env);
argv += optind; argv += optind;

View File

@ -16,20 +16,19 @@
#include "libcoreutils/coreutils.h" #include "libcoreutils/coreutils.h"
#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
static const struct option install_long_options[] = { static const char install_longopts[] =
{ "directory", 0, NULL, 'd' }, "directory\0" No_argument "d"
{ "preserve-timestamps", 0, NULL, 'p' }, "preserve-timestamps\0" No_argument "p"
{ "strip", 0, NULL, 's' }, "strip\0" No_argument "s"
{ "group", 0, NULL, 'g' }, "group\0" No_argument "g"
{ "mode", 0, NULL, 'm' }, "mode\0" No_argument "m"
{ "owner", 0, NULL, 'o' }, "owner\0" No_argument "o"
#if ENABLE_SELINUX #if ENABLE_SELINUX
{ "context", 1, NULL, 'Z' }, "context\0" Required_argument "Z"
{ "preserve_context", 0, NULL, 0xff }, "preserve_context\0" No_argument "\xff"
{ "preserve-context", 0, NULL, 0xff }, "preserve-context\0" No_argument "\xff"
#endif #endif
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
@ -97,7 +96,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_longopts;
#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 */

View File

@ -117,13 +117,12 @@ SPLIT_SUBDIR = 2,
/* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */
#if ENABLE_FEATURE_LS_COLOR #if ENABLE_FEATURE_LS_COLOR
static int show_color; static smallint show_color;
/* long option entry used only for --color, which has no short option /* long option entry used only for --color, which has no short option
* equivalent */ * equivalent */
static const struct option ls_color_opt[] = { static const char ls_color_opt[] =
{ "color", optional_argument, NULL, 1 }, "color\0" Optional_argument "\xff" /* no short equivalent */
{ NULL, 0, NULL, 0 } "\0";
};
#else #else
enum { show_color = 0 }; enum { show_color = 0 };
#endif #endif

View File

@ -25,14 +25,13 @@
/* This is a NOFORK applet. Be very careful! */ /* This is a NOFORK applet. Be very careful! */
#if ENABLE_FEATURE_MKDIR_LONG_OPTIONS #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS
static const struct option mkdir_long_options[] = { static const char mkdir_longopts[] =
{ "mode" , 1, NULL, 'm' }, "mode\0" Required_argument "m"
{ "parents", 0, NULL, 'p' }, "parents\0" No_argument "p"
#if ENABLE_SELINUX #if ENABLE_SELINUX
{ "context", 1, NULL, 'Z' }, "context\0" Required_argument "Z"
#endif #endif
{ NULL, 0, NULL, 0 } "\0";
};
#endif #endif
int mkdir_main(int argc, char **argv); int mkdir_main(int argc, char **argv);
@ -48,7 +47,7 @@ int mkdir_main(int argc, char **argv)
#endif #endif
#if ENABLE_FEATURE_MKDIR_LONG_OPTIONS #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS
applet_long_options = mkdir_long_options; applet_long_options = mkdir_longopts;
#endif #endif
opt = getopt32(argc, argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext)); opt = getopt32(argc, argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext));
if (opt & 1) { if (opt & 1) {

View File

@ -21,11 +21,10 @@
#include "libcoreutils/coreutils.h" #include "libcoreutils/coreutils.h"
#if ENABLE_FEATURE_MV_LONG_OPTIONS #if ENABLE_FEATURE_MV_LONG_OPTIONS
static const struct option mv_long_options[] = { static const char mv_longopts[] =
{ "interactive", 0, NULL, 'i' }, "interactive\0" No_argument "i"
{ "force", 0, NULL, 'f' }, "force\0" No_argument "f"
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
#define OPT_FILEUTILS_FORCE 1 #define OPT_FILEUTILS_FORCE 1
@ -45,7 +44,7 @@ int mv_main(int argc, char **argv)
int copy_flag = 0; int copy_flag = 0;
#if ENABLE_FEATURE_MV_LONG_OPTIONS #if ENABLE_FEATURE_MV_LONG_OPTIONS
applet_long_options = mv_long_options; applet_long_options = mv_longopts;
#endif #endif
opt_complementary = "f-i:i-f"; opt_complementary = "f-i:i-f";
flags = getopt32(argc, argv, "fi"); flags = getopt32(argc, argv, "fi");

View File

@ -1242,17 +1242,16 @@ int od_main(int argc, char **argv)
OPT_traditional = (1 << 18) * ENABLE_GETOPT_LONG, OPT_traditional = (1 << 18) * ENABLE_GETOPT_LONG,
}; };
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
static const struct option long_options[] = { static const char od_longopts[] =
{ "skip-bytes", required_argument, NULL, 'j' }, "skip-bytes\0" Required_argument "j"
{ "address-radix", required_argument, NULL, 'A' }, "address-radix\0" Required_argument "A"
{ "read-bytes", required_argument, NULL, 'N' }, "read-bytes\0" Required_argument "N"
{ "format", required_argument, NULL, 't' }, "format\0" Required_argument "t"
{ "output-duplicates", no_argument, NULL, 'v' }, "output-duplicates\0" No_argument "v"
{ "strings", optional_argument, NULL, 'S' }, "strings\0" Optional_argument "S"
{ "width", optional_argument, NULL, 'w' }, "width\0" Optional_argument "w"
{ "traditional", no_argument, NULL, 0xff }, "traditional\0" No_argument "\xff"
{ NULL, 0, NULL, 0 } "\0";
};
#endif #endif
char *str_A, *str_N, *str_j, *str_S; char *str_A, *str_N, *str_j, *str_S;
char *str_w = NULL; char *str_w = NULL;
@ -1267,7 +1266,7 @@ int od_main(int argc, char **argv)
/* Parse command line */ /* Parse command line */
opt_complementary = "t::"; // list opt_complementary = "t::"; // list
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
applet_long_options = long_options; applet_long_options = od_longopts;
#endif #endif
opt = getopt32(argc, argv, "A:N:abcdfhij:lot:vxsS:" opt = getopt32(argc, argv, "A:N:abcdfhij:lot:vxsS:"
"w::", // -w with optional param "w::", // -w with optional param

View File

@ -35,17 +35,16 @@
#include "libbb.h" #include "libbb.h"
#if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS
static const struct option runparts_long_options[] = { static const char runparts_longopts[] =
{ "arg", 1, NULL, 'a' }, "arg\0" Required_argument "a"
{ "umask", 1, NULL, 'u' }, "umask\0" Required_argument "u"
{ "test", 0, NULL, 't' }, "test\0" No_argument "t"
#if ENABLE_FEATURE_RUN_PARTS_FANCY #if ENABLE_FEATURE_RUN_PARTS_FANCY
{ "list", 0, NULL, 'l' }, "list\0" No_argument "l"
//XXX:TODO: { "reverse", 0, NULL, 'r' }, //TODO: "reverse\0" No_argument "r"
//XXX:TODO: { "verbose", 0, NULL, 'v' }, //TODO: "verbose\0" No_argument "v"
#endif #endif
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
struct globals { struct globals {
@ -120,7 +119,7 @@ int run_parts_main(int argc, char **argv)
/* We require exactly one argument: the directory name */ /* We require exactly one argument: the directory name */
opt_complementary = "=1:a::"; opt_complementary = "=1:a::";
#if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS
applet_long_options = runparts_long_options; applet_long_options = runparts_longopts;
#endif #endif
tmp = getopt32(argc, argv, "a:u:t"USE_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p); tmp = getopt32(argc, argv, "a:u:t"USE_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p);
G.mode = tmp &~ (RUN_PARTS_OPT_a|RUN_PARTS_OPT_u); G.mode = tmp &~ (RUN_PARTS_OPT_a|RUN_PARTS_OPT_u);

View File

@ -194,29 +194,28 @@ static int do_stop(void)
} }
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS #if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
static const struct option long_options[] = { static const char start_stop_daemon_longopts[] =
{ "stop", 0, NULL, 'K' }, "stop\0" No_argument "K"
{ "start", 0, NULL, 'S' }, "start\0" No_argument "S"
{ "background", 0, NULL, 'b' }, "background\0" No_argument "b"
{ "quiet", 0, NULL, 'q' }, "quiet\0" No_argument "q"
{ "make-pidfile", 0, NULL, 'm' }, "make-pidfile\0" No_argument "m"
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
{ "oknodo", 0, NULL, 'o' }, "oknodo\0" No_argument "o"
{ "verbose", 0, NULL, 'v' }, "verbose\0" No_argument "v"
{ "nicelevel", 1, NULL, 'N' }, "nicelevel\0" Required_argument "N"
#endif #endif
{ "startas", 1, NULL, 'a' }, "startas\0" Required_argument "a"
{ "name", 1, NULL, 'n' }, "name\0" Required_argument "n"
{ "signal", 1, NULL, 's' }, "signal\0" Required_argument "s"
{ "user", 1, NULL, 'u' }, "user\0" Required_argument "u"
{ "chuid", 1, NULL, 'c' }, "chuid\0" Required_argument "c"
{ "exec", 1, NULL, 'x' }, "exec\0" Required_argument "x"
{ "pidfile", 1, NULL, 'p' }, "pidfile\0" Required_argument "p"
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
{ "retry", 1, NULL, 'R' }, "retry\0" Required_argument "R"
#endif #endif
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
enum { enum {
@ -250,7 +249,7 @@ int start_stop_daemon_main(int argc, char **argv)
char *opt_N; char *opt_N;
#endif #endif
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS #if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
applet_long_options = long_options; applet_long_options = start_stop_daemon_longopts;
#endif #endif
/* Check required one context option was given */ /* Check required one context option was given */

View File

@ -590,7 +590,10 @@ void bb_sanitize_stdio(void);
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; #define No_argument "\0"
#define Required_argument "\001"
#define Optional_argument "\002"
extern const char *applet_long_options;
#endif #endif
extern uint32_t option_mask32; extern uint32_t option_mask32;
extern uint32_t getopt32(int argc, char **argv, const char *applet_opts, ...); extern uint32_t getopt32(int argc, char **argv, const char *applet_opts, ...);

View File

@ -72,24 +72,21 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
env -i ls -d / env -i ls -d /
Here we want env to process just the '-i', not the '-d'. Here we want env to process just the '-i', not the '-d'.
const struct option *applet_long_options const char *applet_long_options
This struct allows you to define long options. The syntax for This struct allows you to define long options:
declaring the array is just like that of getopt's longopts.
(see getopt(3))
static const struct option applet_long_options[] = { static const char applet_longopts[] =
//name,has_arg,flag,val //"name\0" has_arg val
{ "verbose", 0, 0, 'v' }, "verbose\0" No_argument "v"
{ 0, 0, 0, 0 } "\0";
}; applet_long_options = applet_longopts;
applet_long_options = 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 have 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
Note: a good applet will make long options configurable via the Note: a good applet will make long options configurable via the
@ -290,12 +287,10 @@ typedef struct {
/* You can set applet_long_options for parse called long options */ /* You can set applet_long_options for parse called long options */
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
static const struct option bb_default_long_options[] = { static const struct option bb_null_long_options[1] = {
/* { "help", 0, NULL, '?' }, */
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
const char *applet_long_options;
const struct option *applet_long_options = bb_default_long_options;
#endif #endif
uint32_t option_mask32; uint32_t option_mask32;
@ -312,6 +307,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
va_list p; va_list p;
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
const struct option *l_o; const struct option *l_o;
struct option *long_options = NULL;
#endif #endif
unsigned trigger; unsigned trigger;
char **pargv = NULL; char **pargv = NULL;
@ -347,19 +343,42 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
} }
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
for (l_o = applet_long_options; l_o->name; l_o++) { if (applet_long_options) {
if (l_o->flag) const char *optstr;
continue; unsigned i, count;
for (on_off = complementary; on_off->opt != 0; on_off++)
if (on_off->opt == l_o->val) count = 1;
goto next_long; optstr = applet_long_options;
if (c >= 32) break; while (optstr[0]) {
on_off->opt = l_o->val; optstr += strlen(optstr) + 3; /* skip \0, has_arg, val */
on_off->switch_on = (1 << c); count++;
if (l_o->has_arg != no_argument) }
on_off->optarg = va_arg(p, void **); /* count == no. of longopts + 1 */
c++; long_options = xzalloc(count * sizeof(*long_options));
i = 0;
optstr = applet_long_options;
while (--count) {
long_options[i].name = optstr;
optstr += strlen(optstr) + 1;
long_options[i].has_arg = (unsigned char)(*optstr++);
/* long_options[i].flag = NULL; */
long_options[i].val = (unsigned char)(*optstr++);
i++;
}
for (l_o = long_options; l_o->name; l_o++) {
if (l_o->flag)
continue;
for (on_off = complementary; on_off->opt != 0; on_off++)
if (on_off->opt == l_o->val)
goto next_long;
if (c >= 32) break;
on_off->opt = l_o->val;
on_off->switch_on = (1 << c);
if (l_o->has_arg != no_argument)
on_off->optarg = va_arg(p, void **);
c++;
next_long: ; next_long: ;
}
} }
#endif /* ENABLE_GETOPT_LONG */ #endif /* ENABLE_GETOPT_LONG */
for (s = (const unsigned char *)opt_complementary; s && *s; s++) { for (s = (const unsigned char *)opt_complementary; s && *s; s++) {
@ -457,7 +476,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
* (supposed to act as --header, but doesn't) */ * (supposed to act as --header, but doesn't) */
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
while ((c = getopt_long(argc, argv, applet_opts, while ((c = getopt_long(argc, argv, applet_opts,
applet_long_options, NULL)) != -1) { long_options ? long_options : bb_null_long_options, NULL)) != -1) {
#else #else
while ((c = getopt(argc, argv, applet_opts)) != -1) { while ((c = getopt(argc, argv, applet_opts)) != -1) {
#endif #endif
@ -516,6 +535,9 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) if (argc < min_arg || (max_arg >= 0 && argc > max_arg))
bb_show_usage(); bb_show_usage();
#if ENABLE_GETOPT_LONG
free(long_options);
#endif
option_mask32 = flags; option_mask32 = flags;
return flags; return flags;
} }

View File

@ -11,11 +11,10 @@
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
#include <getopt.h> #include <getopt.h>
static const struct option chpasswd_opts[] = { static const char chpasswd_opts[] =
{ "encrypted", no_argument, NULL, 'e' }, "encrypted\0" No_argument "e"
{ "md5", no_argument, NULL, 'm' }, "md5\0" No_argument "m"
{ NULL, 0, NULL, 0 } "\0";
};
#endif #endif
#define OPT_ENC 1 #define OPT_ENC 1

View File

@ -287,14 +287,13 @@ int ftp_send(ftp_host_info_t *server, FILE *control_stream,
#define FTPGETPUT_OPT_PORT 16 #define FTPGETPUT_OPT_PORT 16
#if ENABLE_FEATURE_FTPGETPUT_LONG_OPTIONS #if ENABLE_FEATURE_FTPGETPUT_LONG_OPTIONS
static const struct option ftpgetput_long_options[] = { static const char ftpgetput_longopts[] =
{ "continue", 1, NULL, 'c' }, "continue\0" Required_argument "c"
{ "verbose", 0, NULL, 'v' }, "verbose\0" No_argument "v"
{ "username", 1, NULL, 'u' }, "username\0" Required_argument "u"
{ "password", 1, NULL, 'p' }, "password\0" Required_argument "p"
{ "port", 1, NULL, 'P' }, "port\0" Required_argument "P"
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
int ftpgetput_main(int argc, char **argv); int ftpgetput_main(int argc, char **argv);
@ -329,7 +328,7 @@ int ftpgetput_main(int argc, char **argv)
* Decipher the command line * Decipher the command line
*/ */
#if ENABLE_FEATURE_FTPGETPUT_LONG_OPTIONS #if ENABLE_FEATURE_FTPGETPUT_LONG_OPTIONS
applet_long_options = ftpgetput_long_options; applet_long_options = ftpgetput_longopts;
#endif #endif
opt_complementary = "=3"; /* must have 3 params */ opt_complementary = "=3"; /* must have 3 params */
opt = getopt32(argc, argv, "cvu:p:P:", &server->user, &server->password, &port); opt = getopt32(argc, argv, "cvu:p:P:", &server->user, &server->password, &port);

View File

@ -63,17 +63,16 @@ int get_prefix(unsigned long netmask);
#define SILENT 0x20 #define SILENT 0x20
#if ENABLE_FEATURE_IPCALC_LONG_OPTIONS #if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
static const struct option long_options[] = { static const char ipcalc_longopts[] =
{ "netmask", no_argument, NULL, 'm' }, "netmask\0" No_argument "m"
{ "broadcast", no_argument, NULL, 'b' }, "broadcast\0" No_argument "b"
{ "network", no_argument, NULL, 'n' }, "network\0" No_argument "n"
# if ENABLE_FEATURE_IPCALC_FANCY # if ENABLE_FEATURE_IPCALC_FANCY
{ "prefix", no_argument, NULL, 'p' }, "prefix\0" No_argument "p"
{ "hostname", no_argument, NULL, 'h' }, "hostname\0" No_argument "h"
{ "silent", no_argument, NULL, 's' }, "silent\0" No_argument "s"
# endif # endif
{ NULL, 0, NULL, 0 } "\0";
};
#endif #endif
int ipcalc_main(int argc, char **argv); int ipcalc_main(int argc, char **argv);
@ -86,7 +85,7 @@ int ipcalc_main(int argc, char **argv)
char *ipstr; char *ipstr;
#if ENABLE_FEATURE_IPCALC_LONG_OPTIONS #if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
applet_long_options = long_options; applet_long_options = ipcalc_longopts;
#endif #endif
opt = getopt32(argc, argv, "mbn" USE_FEATURE_IPCALC_FANCY("phs")); opt = getopt32(argc, argv, "mbn" USE_FEATURE_IPCALC_FANCY("phs"));
argc -= optind; argc -= optind;

View File

@ -181,27 +181,26 @@ int udhcpc_main(int argc, char **argv)
OPT_v = 1 << 17, OPT_v = 1 << 17,
}; };
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
static const struct option arg_options[] = { static const char udhcpc_longopts[] =
{ "clientid", required_argument, 0, 'c' }, "clientid\0" Required_argument "c"
{ "clientid-none", no_argument, 0, 'C' }, "clientid-none\0" No_argument "C"
{ "vendorclass", required_argument, 0, 'V' }, "vendorclass\0" Required_argument "V"
{ "foreground", no_argument, 0, 'f' }, "foreground\0" No_argument "f"
{ "background", no_argument, 0, 'b' }, "background\0" No_argument "b"
{ "hostname", required_argument, 0, 'H' }, "hostname\0" Required_argument "H"
{ "hostname", required_argument, 0, 'h' }, "hostname\0" Required_argument "h"
{ "fqdn", required_argument, 0, 'F' }, "fqdn\0" Required_argument "F"
{ "interface", required_argument, 0, 'i' }, "interface\0" Required_argument "i"
{ "now", no_argument, 0, 'n' }, "now\0" No_argument "n"
{ "pidfile", required_argument, 0, 'p' }, "pidfile\0" Required_argument "p"
{ "quit", no_argument, 0, 'q' }, "quit\0" No_argument "q"
{ "release", no_argument, 0, 'R' }, "release\0" No_argument "R"
{ "request", required_argument, 0, 'r' }, "request\0" Required_argument "r"
{ "script", required_argument, 0, 's' }, "script\0" Required_argument "s"
{ "timeout", required_argument, 0, 'T' }, "timeout\0" Required_argument "T"
{ "version", no_argument, 0, 'v' }, "version\0" No_argument "v"
{ "retries", required_argument, 0, 't' }, "retries\0" Required_argument "t"
{ 0, 0, 0, 0 } "\0";
};
#endif #endif
/* Default options. */ /* Default options. */
client_config.interface = "eth0"; client_config.interface = "eth0";
@ -213,7 +212,7 @@ int udhcpc_main(int argc, char **argv)
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 = udhcpc_longopts;
#endif #endif
opt = getopt32(argc, argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:v", opt = getopt32(argc, argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:v",
&str_c, &str_V, &str_h, &str_h, &str_F, &str_c, &str_V, &str_h, &str_h, &str_F,

View File

@ -24,14 +24,13 @@ int dumpleases_main(int argc, char **argv)
OPT_f = 0x4, // -f OPT_f = 0x4, // -f
}; };
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
static const struct option options[] = { static const char dumpleases_longopts[] =
{ "absolute", no_argument, 0, 'a' }, "absolute\0" No_argument "a"
{ "remaining", no_argument, 0, 'r' }, "remaining\0" No_argument "r"
{ "file", required_argument, 0, 'f' }, "file\0" Required_argument "f"
{ NULL, 0, 0, 0 } "\0";
};
applet_long_options = options; applet_long_options = dumpleases_longopts;
#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);

View File

@ -132,20 +132,19 @@ int wget_main(int argc, char **argv)
WGET_OPT_HEADER = 0x100, WGET_OPT_HEADER = 0x100,
}; };
#if ENABLE_FEATURE_WGET_LONG_OPTIONS #if ENABLE_FEATURE_WGET_LONG_OPTIONS
static const struct option wget_long_options[] = { static const char wget_longopts[] =
/* name, has_arg, flag, val */ /* name, has_arg, val */
{ "continue", no_argument, NULL, 'c' }, "continue\0" No_argument "c"
{ "spider", no_argument, NULL, 's' }, "spider\0" No_argument "s"
{ "quiet", no_argument, NULL, 'q' }, "quiet\0" No_argument "q"
{ "output-document", required_argument, NULL, 'O' }, "output-document\0" Required_argument "O"
{ "directory-prefix", required_argument, NULL, 'P' }, "directory-prefix\0" Required_argument "P"
{ "proxy", required_argument, NULL, 'Y' }, "proxy\0" Required_argument "Y"
{ "user-agent", required_argument, NULL, 'U' }, "user-agent\0" Required_argument "U"
{ "passive-ftp", no_argument, NULL, 0xff }, "passive-ftp\0" No_argument "\xff"
{ "header", required_argument, NULL, 0xfe }, "header\0" Required_argument "\xfe"
{ 0, 0, 0, 0 } "\0";
}; applet_long_options = wget_longopts;
applet_long_options = wget_long_options;
#endif #endif
/* server.allocated = target.allocated = NULL; */ /* server.allocated = target.allocated = NULL; */
opt_complementary = "-1" USE_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); opt_complementary = "-1" USE_FEATURE_WGET_LONG_OPTIONS(":\xfe::");

View File

@ -105,20 +105,19 @@ skip:
} }
#if ENABLE_FEATURE_CHCON_LONG_OPTIONS #if ENABLE_FEATURE_CHCON_LONG_OPTIONS
static struct option chcon_options[] = { static const char chcon_longopts[] =
{ "recursive", 0, NULL, 'R' }, "recursive\0" No_argument "R"
{ "changes", 0, NULL, 'c' }, "changes\0" No_argument "c"
{ "no-dereference", 0, NULL, 'h' }, "no-dereference\0" No_argument "h"
{ "silent", 0, NULL, 'f' }, "silent\0" No_argument "f"
{ "quiet", 0, NULL, 'f' }, "quiet\0" No_argument "f"
{ "user", 1, NULL, 'u' }, "user\0" Required_argument "u"
{ "role", 1, NULL, 'r' }, "role\0" Required_argument "r"
{ "type", 1, NULL, 't' }, "type\0" Required_argument "t"
{ "range", 1, NULL, 'l' }, "range\0" Required_argument "l"
{ "verbose", 0, NULL, 'v' }, "verbose\0" No_argument "v"
{ "reference", 1, NULL, 0xff }, /* no short option */ "reference\0" Required_argument "\xff" /* no short option */
{ NULL, 0, NULL, 0 }, "\0";
};
#endif #endif
int chcon_main(int argc, char **argv); int chcon_main(int argc, char **argv);
@ -129,7 +128,7 @@ int chcon_main(int argc, char **argv)
int i, errors = 0; int i, errors = 0;
#if ENABLE_FEATURE_CHCON_LONG_OPTIONS #if ENABLE_FEATURE_CHCON_LONG_OPTIONS
applet_long_options = chcon_options; applet_long_options = chcon_longopts;
#endif #endif
opt_complementary = "-1" /* at least 1 param */ opt_complementary = "-1" /* at least 1 param */
":?" /* error if exclusivity constraints are violated */ ":?" /* error if exclusivity constraints are violated */

View File

@ -69,15 +69,14 @@ static context_t runcon_compute_new_context(char *user, char *role, char *type,
} }
#if ENABLE_FEATURE_RUNCON_LONG_OPTIONS #if ENABLE_FEATURE_RUNCON_LONG_OPTIONS
static const struct option runcon_options[] = { static const char runcon_options[] =
{ "user", 1, NULL, 'u' }, "user\0" Required_argument "u"
{ "role", 1, NULL, 'r' }, "role\0" Required_argument "r"
{ "type", 1, NULL, 't' }, "type\0" Required_argument "t"
{ "range", 1, NULL, 'l' }, "range\0" Required_argument "l"
{ "compute", 0, NULL, 'c' }, "compute\0" No_argument "c"
{ "help", 0, NULL, 'h' }, "help\0" No_argument "h"
{ NULL, 0, NULL, 0 }, "\0";
};
#endif #endif
#define OPTS_ROLE (1<<0) /* r */ #define OPTS_ROLE (1<<0) /* r */

View File

@ -266,18 +266,17 @@ static void set_shell(const char *new_shell)
*/ */
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
static const struct option longopts[] = { static const char getopt_longopts[] =
{ "options", required_argument, NULL, 'o' }, "options\0" Required_argument "o"
{ "longoptions", required_argument, NULL, 'l' }, "longoptions\0" Required_argument "l"
{ "quiet", no_argument, NULL, 'q' }, "quiet\0" No_argument "q"
{ "quiet-output", no_argument, NULL, 'Q' }, "quiet-output\0" No_argument "Q"
{ "shell", required_argument, NULL, 's' }, "shell\0" Required_argument "s"
{ "test", no_argument, NULL, 'T' }, "test\0" No_argument "T"
{ "unquoted", no_argument, NULL, 'u' }, "unquoted\0" No_argument "u"
{ "alternative", no_argument, NULL, 'a' }, "alternative\0" No_argument "a"
{ "name", required_argument, NULL, 'n' }, "name\0" Required_argument "n"
{ NULL, 0, NULL, 0 } "\0";
};
#endif #endif
int getopt_main(int argc, char *argv[]); int getopt_main(int argc, char *argv[]);
@ -317,7 +316,7 @@ int getopt_main(int argc, char *argv[])
#if !ENABLE_GETOPT_LONG #if !ENABLE_GETOPT_LONG
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 = getopt_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);

View File

@ -178,16 +178,15 @@ int hwclock_main(int argc, char **argv)
int utc; int utc;
#if ENABLE_FEATURE_HWCLOCK_LONG_OPTIONS #if ENABLE_FEATURE_HWCLOCK_LONG_OPTIONS
static const struct option hwclock_long_options[] = { static const char hwclock_longopts[] =
{ "localtime", 0, 0, 'l' }, "localtime\0" No_argument "l"
{ "utc", 0, 0, 'u' }, "utc\0" No_argument "u"
{ "show", 0, 0, 'r' }, "show\0" No_argument "r"
{ "hctosys", 0, 0, 's' }, "hctosys\0" No_argument "s"
{ "systohc", 0, 0, 'w' }, "systohc\0" No_argument "w"
{ "file", 1, 0, 'f' }, "file\0" Required_argument "f"
{ 0, 0, 0, 0 } "\0";
}; applet_long_options = hwclock_longopts;
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);