aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-12 13:31:04 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-12 13:31:04 +0000
commit7e3d33b6ce36776debecc8a504e66dae1b7d0bb4 (patch)
treecbd7cc63c8b6d200d1bf0dbcabc5adcf10fd397b
parent76db5adbf70046dec92309a9785da08d1acf4e9d (diff)
downloadbusybox-w32-7e3d33b6ce36776debecc8a504e66dae1b7d0bb4.tar.gz
busybox-w32-7e3d33b6ce36776debecc8a504e66dae1b7d0bb4.tar.bz2
busybox-w32-7e3d33b6ce36776debecc8a504e66dae1b7d0bb4.zip
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
-rw-r--r--shell/hush.c105
1 files changed, 70 insertions, 35 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 77a305191..8b218aba9 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1213,28 +1213,63 @@ static void o_addstr(o_string *o, const char *str, int len)
1213/* My analysis of quoting semantics tells me that state information 1213/* My analysis of quoting semantics tells me that state information
1214 * is associated with a destination, not a source. 1214 * is associated with a destination, not a source.
1215 */ 1215 */
1216static void o_addqchr(o_string *o, int ch, int quote) 1216static void o_addqchr(o_string *o, int ch)
1217{ 1217{
1218 if (quote && strchr("*?[\\", ch)) { 1218 int sz = 1;
1219 o_addchr(o, '\\'); 1219 if (strchr("*?[\\", ch)) {
1220 sz++;
1221 o->data[o->length] = '\\';
1222 o->length++;
1220 } 1223 }
1221 o_addchr(o, ch); 1224 o_grow_by(o, sz);
1225 o->data[o->length] = ch;
1226 o->length++;
1227 o->data[o->length] = '\0';
1228}
1229
1230static void o_addQchr(o_string *o, int ch)
1231{
1232 int sz = 1;
1233 if (o->o_quote && strchr("*?[\\", ch)) {
1234 sz++;
1235 o->data[o->length] = '\\';
1236 o->length++;
1237 }
1238 o_grow_by(o, sz);
1239 o->data[o->length] = ch;
1240 o->length++;
1241 o->data[o->length] = '\0';
1222} 1242}
1223 1243
1224static void o_addqstr(o_string *o, const char *str, int len, int quote) 1244static void o_addQstr(o_string *o, const char *str, int len)
1225{ 1245{
1226 char ch; 1246 if (!o->o_quote) {
1227 if (!quote || str[strcspn(str, "*?[\\")] == '\0') {
1228 o_addstr(o, str, len); 1247 o_addstr(o, str, len);
1229 return; 1248 return;
1230 } 1249 }
1231 while (len) { 1250 while (len) {
1251 char ch;
1252 int sz;
1253 int ordinary_cnt = strcspn(str, "*?[\\");
1254 if (ordinary_cnt > len) /* paranoia */
1255 ordinary_cnt = len;
1256 o_addstr(o, str, ordinary_cnt);
1257 if (ordinary_cnt == len)
1258 return;
1259 str += ordinary_cnt;
1260 len -= ordinary_cnt - 1; /* we are processing + 1 char below */
1261
1232 ch = *str++; 1262 ch = *str++;
1233 if (ch && strchr("*?[\\", ch)) { 1263 sz = 1;
1234 o_addchr(o, '\\'); 1264 if (ch) { /* it is necessarily one of "*?[\\" */
1265 sz++;
1266 o->data[o->length] = '\\';
1267 o->length++;
1235 } 1268 }
1236 o_addchr(o, ch); 1269 o_grow_by(o, sz);
1237 len--; 1270 o->data[o->length] = ch;
1271 o->length++;
1272 o->data[o->length] = '\0';
1238 } 1273 }
1239} 1274}
1240 1275
@@ -2566,7 +2601,7 @@ static int expand_on_ifs(o_string *output, int n, const char *str)
2566 while (1) { 2601 while (1) {
2567 int word_len = strcspn(str, ifs); 2602 int word_len = strcspn(str, ifs);
2568 if (word_len) { 2603 if (word_len) {
2569 o_addqstr(output, str, word_len, output->o_quote); 2604 o_addQstr(output, str, word_len);
2570 str += word_len; 2605 str += word_len;
2571 } 2606 }
2572 if (!*str) /* EOL - do not finalize word */ 2607 if (!*str) /* EOL - do not finalize word */
@@ -2607,7 +2642,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2607 while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { 2642 while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
2608 o_string subst_result = NULL_O_STRING; 2643 o_string subst_result = NULL_O_STRING;
2609 2644
2610 o_addqstr(output, arg, p - arg, output->o_quote); 2645 o_addQstr(output, arg, p - arg);
2611 o_debug_list("expand_vars_to_list[1]", output, n); 2646 o_debug_list("expand_vars_to_list[1]", output, n);
2612 arg = ++p; 2647 arg = ++p;
2613 p = strchr(p, SPECIAL_VAR_SYMBOL); 2648 p = strchr(p, SPECIAL_VAR_SYMBOL);
@@ -2653,7 +2688,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2653 * and in this case should treat it like '$*' - see 'else...' below */ 2688 * and in this case should treat it like '$*' - see 'else...' below */
2654 if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */ 2689 if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
2655 while (1) { 2690 while (1) {
2656 o_addqstr(output, global_argv[i], strlen(global_argv[i]), output->o_quote); 2691 o_addQstr(output, global_argv[i], strlen(global_argv[i]));
2657 if (++i >= global_argc) 2692 if (++i >= global_argc)
2658 break; 2693 break;
2659 o_addchr(output, '\0'); 2694 o_addchr(output, '\0');
@@ -2662,7 +2697,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2662 } 2697 }
2663 } else { /* quoted $*: add as one word */ 2698 } else { /* quoted $*: add as one word */
2664 while (1) { 2699 while (1) {
2665 o_addqstr(output, global_argv[i], strlen(global_argv[i]), output->o_quote); 2700 o_addQstr(output, global_argv[i], strlen(global_argv[i]));
2666 if (!global_argv[++i]) 2701 if (!global_argv[++i])
2667 break; 2702 break;
2668 if (ifs[0]) 2703 if (ifs[0])
@@ -2702,7 +2737,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2702 } /* else: quoted $VAR, val will be appended below */ 2737 } /* else: quoted $VAR, val will be appended below */
2703 } 2738 }
2704 if (val) { 2739 if (val) {
2705 o_addqstr(output, val, strlen(val), output->o_quote); 2740 o_addQstr(output, val, strlen(val));
2706 } 2741 }
2707 2742
2708 o_free(&subst_result); 2743 o_free(&subst_result);
@@ -2711,7 +2746,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2711 2746
2712 if (arg[0]) { 2747 if (arg[0]) {
2713 o_debug_list("expand_vars_to_list[a]", output, n); 2748 o_debug_list("expand_vars_to_list[a]", output, n);
2714 o_addqstr(output, arg, strlen(arg) + 1, output->o_quote); 2749 o_addQstr(output, arg, strlen(arg) + 1);
2715 o_debug_list("expand_vars_to_list[b]", output, n); 2750 o_debug_list("expand_vars_to_list[b]", output, n);
2716 } else if (output->length == o_get_last_ptr(output, n) /* expansion is empty */ 2751 } else if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
2717 && !(ored_ch & 0x80) /* and all vars were not quoted. */ 2752 && !(ored_ch & 0x80) /* and all vars were not quoted. */
@@ -3335,10 +3370,10 @@ static int process_command_subs(o_string *dest,
3335 continue; 3370 continue;
3336 } 3371 }
3337 while (eol_cnt) { 3372 while (eol_cnt) {
3338 o_addqchr(dest, '\n', dest->o_quote); 3373 o_addQchr(dest, '\n');
3339 eol_cnt--; 3374 eol_cnt--;
3340 } 3375 }
3341 o_addqchr(dest, ch, dest->o_quote); 3376 o_addQchr(dest, ch);
3342 } 3377 }
3343 3378
3344 debug_printf("done reading from pipe, pclose()ing\n"); 3379 debug_printf("done reading from pipe, pclose()ing\n");
@@ -3407,7 +3442,7 @@ static void add_till_single_quote(o_string *dest, struct in_str *input)
3407 break; 3442 break;
3408 if (ch == '\'') 3443 if (ch == '\'')
3409 break; 3444 break;
3410 o_addqchr(dest, ch, 1); 3445 o_addqchr(dest, ch);
3411 } 3446 }
3412} 3447}
3413/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ 3448/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
@@ -3418,15 +3453,15 @@ static void add_till_double_quote(o_string *dest, struct in_str *input)
3418 if (ch == '"') 3453 if (ch == '"')
3419 break; 3454 break;
3420 if (ch == '\\') { /* \x. Copy both chars. */ 3455 if (ch == '\\') { /* \x. Copy both chars. */
3421 o_addqchr(dest, ch, 1); 3456 o_addqchr(dest, ch);
3422 ch = i_getch(input); 3457 ch = i_getch(input);
3423 } 3458 }
3424 if (ch == EOF) 3459 if (ch == EOF)
3425 break; 3460 break;
3426 o_addqchr(dest, ch, 1); 3461 o_addqchr(dest, ch);
3427 if (ch == '`') { 3462 if (ch == '`') {
3428 add_till_backquote(dest, input); 3463 add_till_backquote(dest, input);
3429 o_addqchr(dest, ch, 1); 3464 o_addqchr(dest, ch);
3430 continue; 3465 continue;
3431 } 3466 }
3432// if (ch == '$') ... 3467// if (ch == '$') ...
@@ -3455,12 +3490,12 @@ static void add_till_backquote(o_string *dest, struct in_str *input)
3455 if (ch == '\\') { /* \x. Copy both chars unless it is \` */ 3490 if (ch == '\\') { /* \x. Copy both chars unless it is \` */
3456 int ch2 = i_getch(input); 3491 int ch2 = i_getch(input);
3457 if (ch2 != '`' && ch2 != '$' && ch2 != '\\') 3492 if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
3458 o_addqchr(dest, ch, 1); 3493 o_addqchr(dest, ch);
3459 ch = ch2; 3494 ch = ch2;
3460 } 3495 }
3461 if (ch == EOF) 3496 if (ch == EOF)
3462 break; 3497 break;
3463 o_addqchr(dest, ch, 1); 3498 o_addqchr(dest, ch);
3464 } 3499 }
3465} 3500}
3466/* Process $(cmd) - copy contents until ")" is seen. Complicated by 3501/* Process $(cmd) - copy contents until ")" is seen. Complicated by
@@ -3487,22 +3522,22 @@ static void add_till_closing_curly_brace(o_string *dest, struct in_str *input)
3487 if (ch == ')') 3522 if (ch == ')')
3488 if (--count < 0) 3523 if (--count < 0)
3489 break; 3524 break;
3490 o_addqchr(dest, ch, 1); 3525 o_addqchr(dest, ch);
3491 if (ch == '\'') { 3526 if (ch == '\'') {
3492 add_till_single_quote(dest, input); 3527 add_till_single_quote(dest, input);
3493 o_addqchr(dest, ch, 1); 3528 o_addqchr(dest, ch);
3494 continue; 3529 continue;
3495 } 3530 }
3496 if (ch == '"') { 3531 if (ch == '"') {
3497 add_till_double_quote(dest, input); 3532 add_till_double_quote(dest, input);
3498 o_addqchr(dest, ch, 1); 3533 o_addqchr(dest, ch);
3499 continue; 3534 continue;
3500 } 3535 }
3501 if (ch == '\\') { /* \x. Copy verbatim. Important for \(, \) */ 3536 if (ch == '\\') { /* \x. Copy verbatim. Important for \(, \) */
3502 ch = i_getch(input); 3537 ch = i_getch(input);
3503 if (ch == EOF) 3538 if (ch == EOF)
3504 break; 3539 break;
3505 o_addqchr(dest, ch, 1); 3540 o_addqchr(dest, ch);
3506 continue; 3541 continue;
3507 } 3542 }
3508 } 3543 }
@@ -3581,7 +3616,7 @@ static int handle_dollar(o_string *dest, struct in_str *input)
3581 return 1; 3616 return 1;
3582 break; 3617 break;
3583 default: 3618 default:
3584 o_addqchr(dest, '$', dest->o_quote); 3619 o_addQchr(dest, '$');
3585 } 3620 }
3586 debug_printf_parse("handle_dollar return 0\n"); 3621 debug_printf_parse("handle_dollar return 0\n");
3587 return 0; 3622 return 0;
@@ -3621,7 +3656,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3621 debug_printf_parse("parse_stream return 1: unterminated \"\n"); 3656 debug_printf_parse("parse_stream return 1: unterminated \"\n");
3622 return 1; 3657 return 1;
3623 } 3658 }
3624 o_addqchr(dest, ch, dest->o_quote); 3659 o_addQchr(dest, ch);
3625 continue; 3660 continue;
3626 } 3661 }
3627 if (m == CHAR_IFS) { 3662 if (m == CHAR_IFS) {
@@ -3656,7 +3691,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3656 i_getch(input); 3691 i_getch(input);
3657 } 3692 }
3658 } else { 3693 } else {
3659 o_addqchr(dest, ch, dest->o_quote); 3694 o_addQchr(dest, ch);
3660 } 3695 }
3661 break; 3696 break;
3662 case '\\': 3697 case '\\':
@@ -3676,9 +3711,9 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3676 */ 3711 */
3677 if (dest->o_quote) { 3712 if (dest->o_quote) {
3678 if (strchr("$`\"\\", next) != NULL) { 3713 if (strchr("$`\"\\", next) != NULL) {
3679 o_addqchr(dest, i_getch(input), 1); 3714 o_addqchr(dest, i_getch(input));
3680 } else { 3715 } else {
3681 o_addqchr(dest, '\\', 1); 3716 o_addqchr(dest, '\\');
3682 } 3717 }
3683 } else { 3718 } else {
3684 o_addchr(dest, '\\'); 3719 o_addchr(dest, '\\');
@@ -3697,7 +3732,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3697 ch = i_getch(input); 3732 ch = i_getch(input);
3698 if (ch == EOF || ch == '\'') 3733 if (ch == EOF || ch == '\'')
3699 break; 3734 break;
3700 o_addqchr(dest, ch, 1); 3735 o_addqchr(dest, ch);
3701 } 3736 }
3702 if (ch == EOF) { 3737 if (ch == EOF) {
3703 syntax("unterminated '"); 3738 syntax("unterminated '");