aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-05-20 16:27:42 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-05-20 16:27:42 +0200
commite3be7842be3ccac389efd2ac51b18773c58852c5 (patch)
tree9b0cda850de07e6cb10dafb442d60e98b7fb4aa6
parentcddbb610cb0ea8d74668653aeaded710d2d13768 (diff)
downloadbusybox-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.c39
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;