diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-20 16:27:42 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-20 16:27:42 +0200 |
commit | e3be7842be3ccac389efd2ac51b18773c58852c5 (patch) | |
tree | 9b0cda850de07e6cb10dafb442d60e98b7fb4aa6 | |
parent | cddbb610cb0ea8d74668653aeaded710d2d13768 (diff) | |
download | busybox-w32-e3be7842be3ccac389efd2ac51b18773c58852c5.tar.gz busybox-w32-e3be7842be3ccac389efd2ac51b18773c58852c5.tar.bz2 busybox-w32-e3be7842be3ccac389efd2ac51b18773c58852c5.zip |
hush: shrink variable expansion code
function old new delta
expand_vars_to_list 2164 2012 -152
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/shell/hush.c b/shell/hush.c index 8da9439c1..824a5b52e 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -2568,35 +2568,33 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char | |||
2568 | #endif | 2568 | #endif |
2569 | default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */ | 2569 | default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */ |
2570 | case_default: { | 2570 | case_default: { |
2571 | bool exp_len = false; | ||
2572 | bool exp_null = false; | ||
2573 | char *var = arg; | 2571 | char *var = arg; |
2572 | bool exp_len; | ||
2573 | char exp_op; | ||
2574 | char exp_save = exp_save; /* for compiler */ | 2574 | char exp_save = exp_save; /* for compiler */ |
2575 | char exp_op = exp_op; /* for compiler */ | 2575 | char *exp_saveptr = exp_saveptr; /* points to expansion operator */ |
2576 | char *exp_word = exp_word; /* for compiler */ | 2576 | char *exp_word = exp_word; /* for compiler */ |
2577 | size_t exp_off = 0; | ||
2578 | 2577 | ||
2579 | *p = '\0'; | 2578 | *p = '\0'; |
2580 | arg[0] = first_ch & 0x7f; | 2579 | arg[0] = first_ch & 0x7f; |
2581 | 2580 | ||
2582 | /* prepare for expansions */ | 2581 | /* prepare for expansions */ |
2582 | exp_len = false; | ||
2583 | exp_op = 0; | ||
2583 | if (var[0] == '#') { | 2584 | if (var[0] == '#') { |
2584 | /* handle length expansion ${#var} */ | 2585 | /* handle length expansion ${#var} */ |
2585 | exp_len = true; | 2586 | exp_len = true; |
2586 | ++var; | 2587 | ++var; |
2587 | } else { | 2588 | } else { |
2588 | /* maybe handle parameter expansion */ | 2589 | /* maybe handle parameter expansion */ |
2589 | exp_off = strcspn(var, ":-=+?%#"); | 2590 | exp_saveptr = var + strcspn(var, ":-=+?%#"); |
2590 | if (!var[exp_off]) | 2591 | exp_save = *exp_saveptr; |
2591 | exp_off = 0; | 2592 | if (exp_save) { |
2592 | if (exp_off) { | 2593 | exp_word = exp_saveptr; |
2593 | exp_save = var[exp_off]; | 2594 | if (exp_save == ':') |
2594 | exp_null = exp_save == ':'; | 2595 | exp_word++; |
2595 | exp_word = var + exp_off; | ||
2596 | if (exp_null) | ||
2597 | ++exp_word; | ||
2598 | exp_op = *exp_word++; | 2596 | exp_op = *exp_word++; |
2599 | var[exp_off] = '\0'; | 2597 | *exp_saveptr = '\0'; |
2600 | } | 2598 | } |
2601 | } | 2599 | } |
2602 | 2600 | ||
@@ -2615,7 +2613,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char | |||
2615 | debug_printf_expand("expand: length of '%s' = ", val); | 2613 | debug_printf_expand("expand: length of '%s' = ", val); |
2616 | val = utoa(val ? strlen(val) : 0); | 2614 | val = utoa(val ? strlen(val) : 0); |
2617 | debug_printf_expand("%s\n", val); | 2615 | debug_printf_expand("%s\n", val); |
2618 | } else if (exp_off) { | 2616 | } else if (exp_op) { |
2619 | if (exp_op == '%' || exp_op == '#') { | 2617 | if (exp_op == '%' || exp_op == '#') { |
2620 | if (val) { | 2618 | if (val) { |
2621 | /* we need to do a pattern match */ | 2619 | /* we need to do a pattern match */ |
@@ -2623,7 +2621,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char | |||
2623 | char *loc; | 2621 | char *loc; |
2624 | scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left); | 2622 | scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left); |
2625 | if (exp_op == *exp_word) /* ## or %% */ | 2623 | if (exp_op == *exp_word) /* ## or %% */ |
2626 | ++exp_word; | 2624 | exp_word++; |
2627 | val = dyn_val = xstrdup(val); | 2625 | val = dyn_val = xstrdup(val); |
2628 | loc = scan(dyn_val, exp_word, match_at_left); | 2626 | loc = scan(dyn_val, exp_word, match_at_left); |
2629 | if (match_at_left) /* # or ## */ | 2627 | if (match_at_left) /* # or ## */ |
@@ -2631,13 +2629,14 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char | |||
2631 | else if (loc) /* % or %% and match was found */ | 2629 | else if (loc) /* % or %% and match was found */ |
2632 | *loc = '\0'; | 2630 | *loc = '\0'; |
2633 | } | 2631 | } |
2634 | } else { | 2632 | } else { /* one of :-=+? */ |
2633 | //TODO: handle ${VAR:N[:M]} here. N, M can be expressions similar to $((EXPR)): 2+2, 2+var etc | ||
2635 | /* we need to do an expansion */ | 2634 | /* we need to do an expansion */ |
2636 | int exp_test = (!val || (exp_null && !val[0])); | 2635 | int exp_test = (!val || ((exp_save == ':') && !val[0])); |
2637 | if (exp_op == '+') | 2636 | if (exp_op == '+') |
2638 | exp_test = !exp_test; | 2637 | exp_test = !exp_test; |
2639 | debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, | 2638 | debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, |
2640 | exp_null ? "true" : "false", exp_test); | 2639 | (exp_save == ':') ? "true" : "false", exp_test); |
2641 | if (exp_test) { | 2640 | if (exp_test) { |
2642 | if (exp_op == '?') { | 2641 | if (exp_op == '?') { |
2643 | //TODO: how interactive bash aborts expansion mid-command? | 2642 | //TODO: how interactive bash aborts expansion mid-command? |
@@ -2666,7 +2665,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char | |||
2666 | } | 2665 | } |
2667 | } | 2666 | } |
2668 | 2667 | ||
2669 | var[exp_off] = exp_save; | 2668 | *exp_saveptr = exp_save; |
2670 | } | 2669 | } |
2671 | 2670 | ||
2672 | arg[0] = first_ch; | 2671 | arg[0] = first_ch; |