aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-26 23:22:40 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-26 23:22:40 +0000
commit28e67966f3fc0728fb2f923265a8b2275f410655 (patch)
tree0c522b97ed681180f68d028094bd02b89b292b49 /libbb
parent572930027d5d86a18ebd68d5f4273150a2f302e1 (diff)
downloadbusybox-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.c31
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
75const char *applet_long_options 78const 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}