svn commit: trunk/busybox/shell

vda at busybox.net vda at busybox.net
Thu Jun 12 13:31:05 UTC 2008


Author: vda
Date: 2008-06-12 06:31:04 -0700 (Thu, 12 Jun 2008)
New Revision: 22305

Log:
hush: speed up o_addX{chr,str}

function                                             old     new   delta
o_addQstr                                              -     162    +162
o_addQchr                                              -      89     +89
o_addstr                                               -      58     +58
o_addqchr                                             50      81     +31
expand_on_ifs                                        103      97      -6
add_till_backquote                                    92      82     -10
expand_variables                                    1281    1217     -64
parse_stream                                        1675    1609     -66
o_addqstr                                            155       -    -155
------------------------------------------------------------------------------
(add/remove: 3/1 grow/shrink: 1/4 up/down: 340/-301)           Total: 39 bytes
   text    data     bss     dec     hex filename
 759870     604    6684  767158   bb4b6 busybox_old
 759909     604    6684  767197   bb4dd busybox_unstripped



Modified:
   trunk/busybox/shell/hush.c


Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2008-06-12 12:58:20 UTC (rev 22304)
+++ trunk/busybox/shell/hush.c	2008-06-12 13:31:04 UTC (rev 22305)
@@ -1213,28 +1213,63 @@
 /* My analysis of quoting semantics tells me that state information
  * is associated with a destination, not a source.
  */
-static void o_addqchr(o_string *o, int ch, int quote)
+static void o_addqchr(o_string *o, int ch)
 {
-	if (quote && strchr("*?[\\", ch)) {
-		o_addchr(o, '\\');
+	int sz = 1;
+	if (strchr("*?[\\", ch)) {
+		sz++;
+		o->data[o->length] = '\\';
+		o->length++;
 	}
-	o_addchr(o, ch);
+	o_grow_by(o, sz);
+	o->data[o->length] = ch;
+	o->length++;
+	o->data[o->length] = '\0';
 }
 
-static void o_addqstr(o_string *o, const char *str, int len, int quote)
+static void o_addQchr(o_string *o, int ch)
 {
-	char ch;
-	if (!quote || str[strcspn(str, "*?[\\")] == '\0') {
+	int sz = 1;
+	if (o->o_quote && strchr("*?[\\", ch)) {
+		sz++;
+		o->data[o->length] = '\\';
+		o->length++;
+	}
+	o_grow_by(o, sz);
+	o->data[o->length] = ch;
+	o->length++;
+	o->data[o->length] = '\0';
+}
+
+static void o_addQstr(o_string *o, const char *str, int len)
+{
+	if (!o->o_quote) {
 		o_addstr(o, str, len);
 		return;
 	}
 	while (len) {
+		char ch;
+		int sz;
+		int ordinary_cnt = strcspn(str, "*?[\\");
+		if (ordinary_cnt > len) /* paranoia */
+			ordinary_cnt = len;
+		o_addstr(o, str, ordinary_cnt);
+		if (ordinary_cnt == len)
+			return;
+		str += ordinary_cnt;
+		len -= ordinary_cnt - 1; /* we are processing + 1 char below */
+
 		ch = *str++;
-		if (ch && strchr("*?[\\", ch)) {
-			o_addchr(o, '\\');
+		sz = 1;
+		if (ch) { /* it is necessarily one of "*?[\\" */
+			sz++;
+			o->data[o->length] = '\\';
+			o->length++;
 		}
-		o_addchr(o, ch);
-		len--;
+		o_grow_by(o, sz);
+		o->data[o->length] = ch;
+		o->length++;
+		o->data[o->length] = '\0';
 	}
 }
 
@@ -2566,7 +2601,7 @@
 	while (1) {
 		int word_len = strcspn(str, ifs);
 		if (word_len) {
-			o_addqstr(output, str, word_len, output->o_quote);
+			o_addQstr(output, str, word_len);
 			str += word_len;
 		}
 		if (!*str)  /* EOL - do not finalize word */
@@ -2607,7 +2642,7 @@
 	while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
 		o_string subst_result = NULL_O_STRING;
 
-		o_addqstr(output, arg, p - arg, output->o_quote);
+		o_addQstr(output, arg, p - arg);
 		o_debug_list("expand_vars_to_list[1]", output, n);
 		arg = ++p;
 		p = strchr(p, SPECIAL_VAR_SYMBOL);
@@ -2653,7 +2688,7 @@
 			 * and in this case should treat it like '$*' - see 'else...' below */
 			if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
 				while (1) {
-					o_addqstr(output, global_argv[i], strlen(global_argv[i]), output->o_quote);
+					o_addQstr(output, global_argv[i], strlen(global_argv[i]));
 					if (++i >= global_argc)
 						break;
 					o_addchr(output, '\0');
@@ -2662,7 +2697,7 @@
 				}
 			} else { /* quoted $*: add as one word */
 				while (1) {
-					o_addqstr(output, global_argv[i], strlen(global_argv[i]), output->o_quote);
+					o_addQstr(output, global_argv[i], strlen(global_argv[i]));
 					if (!global_argv[++i])
 						break;
 					if (ifs[0])
@@ -2702,7 +2737,7 @@
 			} /* else: quoted $VAR, val will be appended below */
 		}
 		if (val) {
-			o_addqstr(output, val, strlen(val), output->o_quote);
+			o_addQstr(output, val, strlen(val));
 		}
 
 		o_free(&subst_result);
@@ -2711,7 +2746,7 @@
 
 	if (arg[0]) {
 		o_debug_list("expand_vars_to_list[a]", output, n);
-		o_addqstr(output, arg, strlen(arg) + 1, output->o_quote);
+		o_addQstr(output, arg, strlen(arg) + 1);
 		o_debug_list("expand_vars_to_list[b]", output, n);
 	} else if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
 	 && !(ored_ch & 0x80) /* and all vars were not quoted. */
@@ -3335,10 +3370,10 @@
 			continue;
 		}
 		while (eol_cnt) {
-			o_addqchr(dest, '\n', dest->o_quote);
+			o_addQchr(dest, '\n');
 			eol_cnt--;
 		}
-		o_addqchr(dest, ch, dest->o_quote);
+		o_addQchr(dest, ch);
 	}
 
 	debug_printf("done reading from pipe, pclose()ing\n");
@@ -3407,7 +3442,7 @@
 			break;
 		if (ch == '\'')
 			break;
-		o_addqchr(dest, ch, 1);
+		o_addqchr(dest, ch);
 	}
 }
 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
@@ -3418,15 +3453,15 @@
 		if (ch == '"')
 			break;
 		if (ch == '\\') {  /* \x. Copy both chars. */
-			o_addqchr(dest, ch, 1);
+			o_addqchr(dest, ch);
 			ch = i_getch(input);
 		}
 		if (ch == EOF)
 			break;
-		o_addqchr(dest, ch, 1);
+		o_addqchr(dest, ch);
 		if (ch == '`') {
 			add_till_backquote(dest, input);
-			o_addqchr(dest, ch, 1);
+			o_addqchr(dest, ch);
 			continue;
 		}
 //		if (ch == '$') ...
@@ -3455,12 +3490,12 @@
 		if (ch == '\\') {  /* \x. Copy both chars unless it is \` */
 			int ch2 = i_getch(input);
 			if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
-				o_addqchr(dest, ch, 1);
+				o_addqchr(dest, ch);
 			ch = ch2;
 		}
 		if (ch == EOF)
 			break;
-		o_addqchr(dest, ch, 1);
+		o_addqchr(dest, ch);
 	}
 }
 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
@@ -3487,22 +3522,22 @@
 		if (ch == ')')
 			if (--count < 0)
 				break;
-		o_addqchr(dest, ch, 1);
+		o_addqchr(dest, ch);
 		if (ch == '\'') {
 			add_till_single_quote(dest, input);
-			o_addqchr(dest, ch, 1);
+			o_addqchr(dest, ch);
 			continue;
 		}
 		if (ch == '"') {
 			add_till_double_quote(dest, input);
-			o_addqchr(dest, ch, 1);
+			o_addqchr(dest, ch);
 			continue;
 		}
 		if (ch == '\\') { /* \x. Copy verbatim. Important for  \(, \) */
 			ch = i_getch(input);
 			if (ch == EOF)
 				break;
-			o_addqchr(dest, ch, 1);
+			o_addqchr(dest, ch);
 			continue;
 		}
 	}
@@ -3581,7 +3616,7 @@
 			return 1;
 			break;
 		default:
-			o_addqchr(dest, '$', dest->o_quote);
+			o_addQchr(dest, '$');
 	}
 	debug_printf_parse("handle_dollar return 0\n");
 	return 0;
@@ -3621,7 +3656,7 @@
 				debug_printf_parse("parse_stream return 1: unterminated \"\n");
 				return 1;
 			}
-			o_addqchr(dest, ch, dest->o_quote);
+			o_addQchr(dest, ch);
 			continue;
 		}
 		if (m == CHAR_IFS) {
@@ -3656,7 +3691,7 @@
 					i_getch(input);
 				}
 			} else {
-				o_addqchr(dest, ch, dest->o_quote);
+				o_addQchr(dest, ch);
 			}
 			break;
 		case '\\':
@@ -3676,9 +3711,9 @@
 			 */
 			if (dest->o_quote) {
 				if (strchr("$`\"\\", next) != NULL) {
-					o_addqchr(dest, i_getch(input), 1);
+					o_addqchr(dest, i_getch(input));
 				} else {
-					o_addqchr(dest, '\\', 1);
+					o_addqchr(dest, '\\');
 				}
 			} else {
 				o_addchr(dest, '\\');
@@ -3697,7 +3732,7 @@
 				ch = i_getch(input);
 				if (ch == EOF || ch == '\'')
 					break;
-				o_addqchr(dest, ch, 1);
+				o_addqchr(dest, ch);
 			}
 			if (ch == EOF) {
 				syntax("unterminated '");




More information about the busybox-cvs mailing list