diff options
Diffstat (limited to 'shell/hush.c')
-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 8da9439..824a5b5 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 #endif default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */ case_default: { - bool exp_len = false; - bool exp_null = false; char *var = arg; + bool exp_len; + char exp_op; 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 */ - size_t exp_off = 0; *p = '\0'; arg[0] = first_ch & 0x7f; /* prepare for expansions */ + exp_len = false; + exp_op = 0; if (var[0] == '#') { /* handle length expansion ${#var} */ exp_len = true; ++var; } else { /* maybe handle parameter expansion */ - exp_off = strcspn(var, ":-=+?%#"); - if (!var[exp_off]) - exp_off = 0; - if (exp_off) { - exp_save = var[exp_off]; - exp_null = exp_save == ':'; - exp_word = var + exp_off; - if (exp_null) - ++exp_word; + exp_saveptr = var + strcspn(var, ":-=+?%#"); + exp_save = *exp_saveptr; + if (exp_save) { + exp_word = exp_saveptr; + if (exp_save == ':') + 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); val = utoa(val ? strlen(val) : 0); debug_printf_expand("%s\n", val); - } else if (exp_off) { + } else if (exp_op) { if (exp_op == '%' || exp_op == '#') { if (val) { /* 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; scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left); if (exp_op == *exp_word) /* ## or %% */ - ++exp_word; + exp_word++; val = dyn_val = xstrdup(val); loc = scan(dyn_val, exp_word, match_at_left); 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 */ *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 */ - int exp_test = (!val || (exp_null && !val[0])); + int exp_test = (!val || ((exp_save == ':') && !val[0])); if (exp_op == '+') exp_test = !exp_test; 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_op == '?') { //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; |