diff options
author | Denis Vlasenko | 2007-07-23 17:14:14 +0000 |
---|---|---|
committer | Denis Vlasenko | 2007-07-23 17:14:14 +0000 |
commit | bdc88fdc6844ee6890e31ba4cf56800becc8c682 (patch) | |
tree | 69301e47c6493ad275d72e57ce96467ee13d7ecc /libbb/getopt32.c | |
parent | 9fe9c1a6d8e66032a9783f98606167764e8ab296 (diff) | |
download | busybox-bdc88fdc6844ee6890e31ba4cf56800becc8c682.zip busybox-bdc88fdc6844ee6890e31ba4cf56800becc8c682.tar.gz |
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
Diffstat (limited to 'libbb/getopt32.c')
-rw-r--r-- | libbb/getopt32.c | 78 |
1 files changed, 50 insertions, 28 deletions
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index f5aaa70..e5d97e9 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -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; } |