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 /shell | |
| 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>
Diffstat (limited to 'shell')
| -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; |
