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>
This commit is contained in:
Denys Vlasenko 2010-05-20 16:27:42 +02:00
parent cddbb610cb
commit e3be7842be

View File

@ -2568,35 +2568,33 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
#endif #endif
default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */ default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
case_default: { case_default: {
bool exp_len = false;
bool exp_null = false;
char *var = arg; char *var = arg;
bool exp_len;
char exp_op;
char exp_save = exp_save; /* for compiler */ char exp_save = exp_save; /* for compiler */
char exp_op = exp_op; /* for compiler */ char *exp_saveptr = exp_saveptr; /* points to expansion operator */
char *exp_word = exp_word; /* for compiler */ char *exp_word = exp_word; /* for compiler */
size_t exp_off = 0;
*p = '\0'; *p = '\0';
arg[0] = first_ch & 0x7f; arg[0] = first_ch & 0x7f;
/* prepare for expansions */ /* prepare for expansions */
exp_len = false;
exp_op = 0;
if (var[0] == '#') { if (var[0] == '#') {
/* handle length expansion ${#var} */ /* handle length expansion ${#var} */
exp_len = true; exp_len = true;
++var; ++var;
} else { } else {
/* maybe handle parameter expansion */ /* maybe handle parameter expansion */
exp_off = strcspn(var, ":-=+?%#"); exp_saveptr = var + strcspn(var, ":-=+?%#");
if (!var[exp_off]) exp_save = *exp_saveptr;
exp_off = 0; if (exp_save) {
if (exp_off) { exp_word = exp_saveptr;
exp_save = var[exp_off]; if (exp_save == ':')
exp_null = exp_save == ':'; exp_word++;
exp_word = var + exp_off;
if (exp_null)
++exp_word;
exp_op = *exp_word++; exp_op = *exp_word++;
var[exp_off] = '\0'; *exp_saveptr = '\0';
} }
} }
@ -2615,7 +2613,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
debug_printf_expand("expand: length of '%s' = ", val); debug_printf_expand("expand: length of '%s' = ", val);
val = utoa(val ? strlen(val) : 0); val = utoa(val ? strlen(val) : 0);
debug_printf_expand("%s\n", val); debug_printf_expand("%s\n", val);
} else if (exp_off) { } else if (exp_op) {
if (exp_op == '%' || exp_op == '#') { if (exp_op == '%' || exp_op == '#') {
if (val) { if (val) {
/* we need to do a pattern match */ /* 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
char *loc; char *loc;
scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left); scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left);
if (exp_op == *exp_word) /* ## or %% */ if (exp_op == *exp_word) /* ## or %% */
++exp_word; exp_word++;
val = dyn_val = xstrdup(val); val = dyn_val = xstrdup(val);
loc = scan(dyn_val, exp_word, match_at_left); loc = scan(dyn_val, exp_word, match_at_left);
if (match_at_left) /* # or ## */ if (match_at_left) /* # or ## */
@ -2631,13 +2629,14 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
else if (loc) /* % or %% and match was found */ else if (loc) /* % or %% and match was found */
*loc = '\0'; *loc = '\0';
} }
} else { } else { /* one of :-=+? */
//TODO: handle ${VAR:N[:M]} here. N, M can be expressions similar to $((EXPR)): 2+2, 2+var etc
/* we need to do an expansion */ /* we need to do an expansion */
int exp_test = (!val || (exp_null && !val[0])); int exp_test = (!val || ((exp_save == ':') && !val[0]));
if (exp_op == '+') if (exp_op == '+')
exp_test = !exp_test; exp_test = !exp_test;
debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
exp_null ? "true" : "false", exp_test); (exp_save == ':') ? "true" : "false", exp_test);
if (exp_test) { if (exp_test) {
if (exp_op == '?') { if (exp_op == '?') {
//TODO: how interactive bash aborts expansion mid-command? //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
} }
} }
var[exp_off] = exp_save; *exp_saveptr = exp_save;
} }
arg[0] = first_ch; arg[0] = first_ch;