diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-12 13:31:04 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-12 13:31:04 +0000 |
commit | 7e3d33b6ce36776debecc8a504e66dae1b7d0bb4 (patch) | |
tree | cbd7cc63c8b6d200d1bf0dbcabc5adcf10fd397b | |
parent | 76db5adbf70046dec92309a9785da08d1acf4e9d (diff) | |
download | busybox-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.c | 105 |
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 | */ |
1216 | static void o_addqchr(o_string *o, int ch, int quote) | 1216 | static 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 | |||
1230 | static 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 | ||
1224 | static void o_addqstr(o_string *o, const char *str, int len, int quote) | 1244 | static 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 '"); |