diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-26 23:22:40 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-26 23:22:40 +0000 |
commit | 28e67966f3fc0728fb2f923265a8b2275f410655 (patch) | |
tree | 0c522b97ed681180f68d028094bd02b89b292b49 /libbb | |
parent | 572930027d5d86a18ebd68d5f4273150a2f302e1 (diff) | |
download | busybox-w32-28e67966f3fc0728fb2f923265a8b2275f410655.tar.gz busybox-w32-28e67966f3fc0728fb2f923265a8b2275f410655.tar.bz2 busybox-w32-28e67966f3fc0728fb2f923265a8b2275f410655.zip |
hush: make getopt32 usable in builtins. use it in unset.
more uses are expected in the future.
function old new delta
getopt32 1356 1393 +37
builtin_export 256 266 +10
builtin_unset 418 380 -38
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/getopt32.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 5190fa61a..1eb868c97 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -72,6 +72,9 @@ getopt32(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 | "!" Report bad option, missing required options, | ||
76 | inconsistent options with all-ones return value (instead of abort). | ||
77 | |||
75 | const char *applet_long_options | 78 | const char *applet_long_options |
76 | 79 | ||
77 | This struct allows you to define long options: | 80 | This struct allows you to define long options: |
@@ -327,6 +330,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
327 | unsigned flags = 0; | 330 | unsigned flags = 0; |
328 | unsigned requires = 0; | 331 | unsigned requires = 0; |
329 | t_complementary complementary[33]; /* last stays zero-filled */ | 332 | t_complementary complementary[33]; /* last stays zero-filled */ |
333 | char first_char; | ||
330 | int c; | 334 | int c; |
331 | const unsigned char *s; | 335 | const unsigned char *s; |
332 | t_complementary *on_off; | 336 | t_complementary *on_off; |
@@ -357,6 +361,11 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
357 | on_off = complementary; | 361 | on_off = complementary; |
358 | memset(on_off, 0, sizeof(complementary)); | 362 | memset(on_off, 0, sizeof(complementary)); |
359 | 363 | ||
364 | /* skip bbox extension */ | ||
365 | first_char = applet_opts[0]; | ||
366 | if (first_char == '!') | ||
367 | applet_opts++; | ||
368 | |||
360 | /* skip GNU extension */ | 369 | /* skip GNU extension */ |
361 | s = (const unsigned char *)applet_opts; | 370 | s = (const unsigned char *)applet_opts; |
362 | if (*s == '+' || *s == '-') | 371 | if (*s == '+' || *s == '-') |
@@ -549,11 +558,11 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
549 | * is always NULL (see above) */ | 558 | * is always NULL (see above) */ |
550 | if (on_off->opt_char == '\0' /* && c != '\0' */) { | 559 | if (on_off->opt_char == '\0' /* && c != '\0' */) { |
551 | /* c is probably '?' - "bad option" */ | 560 | /* c is probably '?' - "bad option" */ |
552 | bb_show_usage(); | 561 | goto error; |
553 | } | 562 | } |
554 | } | 563 | } |
555 | if (flags & on_off->incongruously) | 564 | if (flags & on_off->incongruously) |
556 | bb_show_usage(); | 565 | goto error; |
557 | trigger = on_off->switch_on & on_off->switch_off; | 566 | trigger = on_off->switch_on & on_off->switch_off; |
558 | flags &= ~(on_off->switch_off ^ trigger); | 567 | flags &= ~(on_off->switch_off ^ trigger); |
559 | flags |= on_off->switch_on ^ trigger; | 568 | flags |= on_off->switch_on ^ trigger; |
@@ -577,16 +586,24 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
577 | 586 | ||
578 | /* check depending requires for given options */ | 587 | /* check depending requires for given options */ |
579 | for (on_off = complementary; on_off->opt_char; on_off++) { | 588 | for (on_off = complementary; on_off->opt_char; on_off++) { |
580 | if (on_off->requires && (flags & on_off->switch_on) && | 589 | if (on_off->requires |
581 | (flags & on_off->requires) == 0) | 590 | && (flags & on_off->switch_on) |
582 | bb_show_usage(); | 591 | && (flags & on_off->requires) == 0 |
592 | ) { | ||
593 | goto error; | ||
594 | } | ||
583 | } | 595 | } |
584 | if (requires && (flags & requires) == 0) | 596 | if (requires && (flags & requires) == 0) |
585 | bb_show_usage(); | 597 | goto error; |
586 | argc -= optind; | 598 | argc -= optind; |
587 | if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) | 599 | if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) |
588 | bb_show_usage(); | 600 | goto error; |
589 | 601 | ||
590 | option_mask32 = flags; | 602 | option_mask32 = flags; |
591 | return flags; | 603 | return flags; |
604 | |||
605 | error: | ||
606 | if (first_char != '!') | ||
607 | bb_show_usage(); | ||
608 | return (int32_t)-1; | ||
592 | } | 609 | } |