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

@@ -72,24 +72,21 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
env -i ls -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
declaring the array is just like that of getopt's longopts.
(see getopt(3))
This struct allows you to define long options:
static const struct option applet_long_options[] = {
//name,has_arg,flag,val
{ "verbose", 0, 0, 'v' },
{ 0, 0, 0, 0 }
};
applet_long_options = applet_long_options;
static const char applet_longopts[] =
//"name\0" has_arg val
"verbose\0" No_argument "v"
"\0";
applet_long_options = applet_longopts;
The last member of struct option (val) typically is set to
matching short option from applet_opts. If there is no matching
char in applet_opts, then:
- return bit have next position after short options
- 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
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 */
#if ENABLE_GETOPT_LONG
static const struct option bb_default_long_options[] = {
/* { "help", 0, NULL, '?' }, */
static const struct option bb_null_long_options[1] = {
{ 0, 0, 0, 0 }
};
const struct option *applet_long_options = bb_default_long_options;
const char *applet_long_options;
#endif
uint32_t option_mask32;
@@ -312,6 +307,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
va_list p;
#if ENABLE_GETOPT_LONG
const struct option *l_o;
struct option *long_options = NULL;
#endif
unsigned trigger;
char **pargv = NULL;
@@ -347,19 +343,42 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
}
#if ENABLE_GETOPT_LONG
for (l_o = applet_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++;
if (applet_long_options) {
const char *optstr;
unsigned i, count;
count = 1;
optstr = applet_long_options;
while (optstr[0]) {
optstr += strlen(optstr) + 3; /* skip \0, has_arg, val */
count++;
}
/* count == no. of longopts + 1 */
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: ;
}
}
#endif /* ENABLE_GETOPT_LONG */
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) */
#if ENABLE_GETOPT_LONG
while ((c = getopt_long(argc, argv, applet_opts,
applet_long_options, NULL)) != -1) {
long_options ? long_options : bb_null_long_options, NULL)) != -1) {
#else
while ((c = getopt(argc, argv, applet_opts)) != -1) {
#endif
@@ -516,6 +535,9 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
if (argc < min_arg || (max_arg >= 0 && argc > max_arg))
bb_show_usage();
#if ENABLE_GETOPT_LONG
free(long_options);
#endif
option_mask32 = flags;
return flags;
}