diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-23 17:14:14 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-23 17:14:14 +0000 |
commit | bdc88fdc6844ee6890e31ba4cf56800becc8c682 (patch) | |
tree | 69301e47c6493ad275d72e57ce96467ee13d7ecc /libbb | |
parent | 9fe9c1a6d8e66032a9783f98606167764e8ab296 (diff) | |
download | busybox-w32-bdc88fdc6844ee6890e31ba4cf56800becc8c682.tar.gz busybox-w32-bdc88fdc6844ee6890e31ba4cf56800becc8c682.tar.bz2 busybox-w32-bdc88fdc6844ee6890e31ba4cf56800becc8c682.zip |
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')
-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 f5aaa70df..e5d97e98c 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -72,24 +72,21 @@ getopt32(int argc, char **argv, const char *applet_opts, ...) | |||
72 | env -i ls -d / | 72 | env -i ls -d / |
73 | Here we want env to process just the '-i', not the '-d'. | 73 | Here we want env to process just the '-i', not the '-d'. |
74 | 74 | ||
75 | const struct option *applet_long_options | 75 | const char *applet_long_options |
76 | 76 | ||
77 | This struct allows you to define long options. The syntax for | 77 | This struct allows you to define long options: |
78 | declaring the array is just like that of getopt's longopts. | ||
79 | (see getopt(3)) | ||
80 | 78 | ||
81 | static const struct option applet_long_options[] = { | 79 | static const char applet_longopts[] = |
82 | //name,has_arg,flag,val | 80 | //"name\0" has_arg val |
83 | { "verbose", 0, 0, 'v' }, | 81 | "verbose\0" No_argument "v" |
84 | { 0, 0, 0, 0 } | 82 | "\0"; |
85 | }; | 83 | applet_long_options = applet_longopts; |
86 | applet_long_options = applet_long_options; | ||
87 | 84 | ||
88 | The last member of struct option (val) typically is set to | 85 | The last member of struct option (val) typically is set to |
89 | matching short option from applet_opts. If there is no matching | 86 | matching short option from applet_opts. If there is no matching |
90 | char in applet_opts, then: | 87 | char in applet_opts, then: |
91 | - return bit have next position after short options | 88 | - return bit have next position after short options |
92 | - if has_arg is not "no_argument", use ptr for arg also | 89 | - if has_arg is not "No_argument", use ptr for arg also |
93 | - opt_complementary affects it too | 90 | - opt_complementary affects it too |
94 | 91 | ||
95 | Note: a good applet will make long options configurable via the | 92 | Note: a good applet will make long options configurable via the |
@@ -290,12 +287,10 @@ typedef struct { | |||
290 | 287 | ||
291 | /* You can set applet_long_options for parse called long options */ | 288 | /* You can set applet_long_options for parse called long options */ |
292 | #if ENABLE_GETOPT_LONG | 289 | #if ENABLE_GETOPT_LONG |
293 | static const struct option bb_default_long_options[] = { | 290 | static const struct option bb_null_long_options[1] = { |
294 | /* { "help", 0, NULL, '?' }, */ | ||
295 | { 0, 0, 0, 0 } | 291 | { 0, 0, 0, 0 } |
296 | }; | 292 | }; |
297 | 293 | const char *applet_long_options; | |
298 | const struct option *applet_long_options = bb_default_long_options; | ||
299 | #endif | 294 | #endif |
300 | 295 | ||
301 | uint32_t option_mask32; | 296 | uint32_t option_mask32; |
@@ -312,6 +307,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...) | |||
312 | va_list p; | 307 | va_list p; |
313 | #if ENABLE_GETOPT_LONG | 308 | #if ENABLE_GETOPT_LONG |
314 | const struct option *l_o; | 309 | const struct option *l_o; |
310 | struct option *long_options = NULL; | ||
315 | #endif | 311 | #endif |
316 | unsigned trigger; | 312 | unsigned trigger; |
317 | char **pargv = NULL; | 313 | char **pargv = NULL; |
@@ -347,19 +343,42 @@ getopt32(int argc, char **argv, const char *applet_opts, ...) | |||
347 | } | 343 | } |
348 | 344 | ||
349 | #if ENABLE_GETOPT_LONG | 345 | #if ENABLE_GETOPT_LONG |
350 | for (l_o = applet_long_options; l_o->name; l_o++) { | 346 | if (applet_long_options) { |
351 | if (l_o->flag) | 347 | const char *optstr; |
352 | continue; | 348 | unsigned i, count; |
353 | for (on_off = complementary; on_off->opt != 0; on_off++) | 349 | |
354 | if (on_off->opt == l_o->val) | 350 | count = 1; |
355 | goto next_long; | 351 | optstr = applet_long_options; |
356 | if (c >= 32) break; | 352 | while (optstr[0]) { |
357 | on_off->opt = l_o->val; | 353 | optstr += strlen(optstr) + 3; /* skip \0, has_arg, val */ |
358 | on_off->switch_on = (1 << c); | 354 | count++; |
359 | if (l_o->has_arg != no_argument) | 355 | } |
360 | on_off->optarg = va_arg(p, void **); | 356 | /* count == no. of longopts + 1 */ |
361 | c++; | 357 | long_options = xzalloc(count * sizeof(*long_options)); |
358 | i = 0; | ||
359 | optstr = applet_long_options; | ||
360 | while (--count) { | ||
361 | long_options[i].name = optstr; | ||
362 | optstr += strlen(optstr) + 1; | ||
363 | long_options[i].has_arg = (unsigned char)(*optstr++); | ||
364 | /* long_options[i].flag = NULL; */ | ||
365 | long_options[i].val = (unsigned char)(*optstr++); | ||
366 | i++; | ||
367 | } | ||
368 | for (l_o = long_options; l_o->name; l_o++) { | ||
369 | if (l_o->flag) | ||
370 | continue; | ||
371 | for (on_off = complementary; on_off->opt != 0; on_off++) | ||
372 | if (on_off->opt == l_o->val) | ||
373 | goto next_long; | ||
374 | if (c >= 32) break; | ||
375 | on_off->opt = l_o->val; | ||
376 | on_off->switch_on = (1 << c); | ||
377 | if (l_o->has_arg != no_argument) | ||
378 | on_off->optarg = va_arg(p, void **); | ||
379 | c++; | ||
362 | next_long: ; | 380 | next_long: ; |
381 | } | ||
363 | } | 382 | } |
364 | #endif /* ENABLE_GETOPT_LONG */ | 383 | #endif /* ENABLE_GETOPT_LONG */ |
365 | for (s = (const unsigned char *)opt_complementary; s && *s; s++) { | 384 | for (s = (const unsigned char *)opt_complementary; s && *s; s++) { |
@@ -457,7 +476,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...) | |||
457 | * (supposed to act as --header, but doesn't) */ | 476 | * (supposed to act as --header, but doesn't) */ |
458 | #if ENABLE_GETOPT_LONG | 477 | #if ENABLE_GETOPT_LONG |
459 | while ((c = getopt_long(argc, argv, applet_opts, | 478 | while ((c = getopt_long(argc, argv, applet_opts, |
460 | applet_long_options, NULL)) != -1) { | 479 | long_options ? long_options : bb_null_long_options, NULL)) != -1) { |
461 | #else | 480 | #else |
462 | while ((c = getopt(argc, argv, applet_opts)) != -1) { | 481 | while ((c = getopt(argc, argv, applet_opts)) != -1) { |
463 | #endif | 482 | #endif |
@@ -516,6 +535,9 @@ getopt32(int argc, char **argv, const char *applet_opts, ...) | |||
516 | if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) | 535 | if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) |
517 | bb_show_usage(); | 536 | bb_show_usage(); |
518 | 537 | ||
538 | #if ENABLE_GETOPT_LONG | ||
539 | free(long_options); | ||
540 | #endif | ||
519 | option_mask32 = flags; | 541 | option_mask32 = flags; |
520 | return flags; | 542 | return flags; |
521 | } | 543 | } |