svn commit: [26215] trunk/busybox: libbb shell shell/hush_test/hush-vars

vda at busybox.net vda at busybox.net
Sun Apr 26 23:22:41 UTC 2009


Author: vda
Date: 2009-04-26 23:22:40 +0000 (Sun, 26 Apr 2009)
New Revision: 26215

Log:
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



Modified:
   trunk/busybox/libbb/getopt32.c
   trunk/busybox/shell/hush.c
   trunk/busybox/shell/hush_test/hush-vars/unset.right


Changeset:
Modified: trunk/busybox/libbb/getopt32.c
===================================================================
--- trunk/busybox/libbb/getopt32.c	2009-04-26 21:40:32 UTC (rev 26214)
+++ trunk/busybox/libbb/getopt32.c	2009-04-26 23:22:40 UTC (rev 26215)
@@ -72,6 +72,9 @@
         env -i ls -d /
         Here we want env to process just the '-i', not the '-d'.
 
+ "!"    Report bad option, missing required options,
+        inconsistent options with all-ones return value (instead of abort).
+
 const char *applet_long_options
 
         This struct allows you to define long options:
@@ -327,6 +330,7 @@
 	unsigned flags = 0;
 	unsigned requires = 0;
 	t_complementary complementary[33]; /* last stays zero-filled */
+	char first_char;
 	int c;
 	const unsigned char *s;
 	t_complementary *on_off;
@@ -357,6 +361,11 @@
 	on_off = complementary;
 	memset(on_off, 0, sizeof(complementary));
 
+	/* skip bbox extension */
+	first_char = applet_opts[0];
+	if (first_char == '!')
+		applet_opts++;
+
 	/* skip GNU extension */
 	s = (const unsigned char *)applet_opts;
 	if (*s == '+' || *s == '-')
@@ -549,11 +558,11 @@
 			 * is always NULL (see above) */
 			if (on_off->opt_char == '\0' /* && c != '\0' */) {
 				/* c is probably '?' - "bad option" */
-				bb_show_usage();
+				goto error;
 			}
 		}
 		if (flags & on_off->incongruously)
-			bb_show_usage();
+			goto error;
 		trigger = on_off->switch_on & on_off->switch_off;
 		flags &= ~(on_off->switch_off ^ trigger);
 		flags |= on_off->switch_on ^ trigger;
@@ -577,16 +586,24 @@
 
 	/* check depending requires for given options */
 	for (on_off = complementary; on_off->opt_char; on_off++) {
-		if (on_off->requires && (flags & on_off->switch_on) &&
-					(flags & on_off->requires) == 0)
-			bb_show_usage();
+		if (on_off->requires
+		 && (flags & on_off->switch_on)
+		 && (flags & on_off->requires) == 0
+		) {
+			goto error;
+		}
 	}
 	if (requires && (flags & requires) == 0)
-		bb_show_usage();
+		goto error;
 	argc -= optind;
 	if (argc < min_arg || (max_arg >= 0 && argc > max_arg))
-		bb_show_usage();
+		goto error;
 
 	option_mask32 = flags;
 	return flags;
+
+ error:
+	if (first_char != '!')
+		bb_show_usage();
+	return (int32_t)-1;
 }

Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2009-04-26 21:40:32 UTC (rev 26214)
+++ trunk/busybox/shell/hush.c	2009-04-26 23:22:40 UTC (rev 26215)
@@ -6451,7 +6451,11 @@
 	}
 
 #if ENABLE_HUSH_EXPORT_N
-	opt_unexport = getopt32(argv, "+n"); /* "+": stop at 1st non-option */
+	/* "!": do not abort on errors */
+	/* "+": stop at 1st non-option */
+	opt_unexport = getopt32(argv, "!+n");
+	if (opt_unexport == (unsigned)-1)
+		return EXIT_FAILURE;
 	argv += optind;
 #else
 	opt_unexport = 0;
@@ -6918,36 +6922,22 @@
 static int builtin_unset(char **argv)
 {
 	int ret;
-	char var;
-	char *arg;
+	unsigned opts;
 
-	if (!*++argv)
-		return EXIT_SUCCESS;
-
-	var = 0;
-	while ((arg = *argv) != NULL && arg[0] == '-') {
-		arg++;
-		do {
-			switch (*arg) {
-			case 'v':
-			case 'f':
-				if (var == 0 || var == *arg) {
-					var = *arg;
-					break;
-				}
-				/* else: unset -vf, which is illegal.
-				 * fall through */
-			default:
-				bb_error_msg("unset: %s: invalid option", *argv);
-				return EXIT_FAILURE;
-			}
-		} while (*++arg);
-		argv++;
+	/* "!": do not abort on errors */
+	/* "+": stop at 1st non-option */
+	opts = getopt32(argv, "!+vf");
+	if (opts == (unsigned)-1)
+		return EXIT_FAILURE;
+	if (opts == 3) {
+		bb_error_msg("unset: -v and -f are exclusive");
+		return EXIT_FAILURE;
 	}
+	argv += optind;
 
 	ret = EXIT_SUCCESS;
 	while (*argv) {
-		if (var != 'f') {
+		if (!(opts & 2)) { /* not -f */
 			if (unset_local_var(*argv)) {
 				/* unset <nonexistent_var> doesn't fail.
 				 * Error is when one tries to unset RO var.

Modified: trunk/busybox/shell/hush_test/hush-vars/unset.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-vars/unset.right	2009-04-26 21:40:32 UTC (rev 26214)
+++ trunk/busybox/shell/hush_test/hush-vars/unset.right	2009-04-26 23:22:40 UTC (rev 26215)
@@ -1,7 +1,6 @@
-hush: unset: -: invalid option
+0
+unset: invalid option -- m
 1
-hush: unset: -m: invalid option
-1
 0
 ___
 0 f g



More information about the busybox-cvs mailing list