hush: implement negative start in the ${v: -n[:m]} idiom
No binary (build failed)
—
(log yok)
| @@ -0,0 +1,5 @@ | |
| + | Expected Actual |
| + | a*z : a*z |
| + | \z : \z |
| + | a1z a2z: a1z a2z |
| + | z : z |
| @@ -0,0 +1,9 @@ | |
| + | # This testcase checks globbing correctness in ${v/a/b} |
| + | |
| + | >a1z; >a2z; |
| + | echo 'Expected' 'Actual' |
| + | v='a bz'; echo 'a*z :' "${v/a*z/a*z}" |
| + | v='a bz'; echo '\z :' "${v/a*z/\z}" |
| + | v='a bz'; echo 'a1z a2z:' ${v/a*z/a*z} |
| + | v='a bz'; echo 'z :' ${v/a*z/\z} |
| + | rm a1z a2z |
| @@ -5619,8 +5619,12 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |
| goto arith_err; | |
| debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len); | |
| if (len >= 0) { /* bash compat: len < 0 is illegal */ | |
| - | if (beg < 0) /* bash compat */ |
| - | beg = 0; |
| + | if (beg < 0) { |
| + | /* negative beg counts from the end */ |
| + | beg = (arith_t)strlen(val) + beg; |
| + | if (beg < 0) /* ${v: -999999} is "" */ |
| + | beg = len = 0; |
| + | } |
| debug_printf_varexp("from val:'%s'\n", val); | |
| if (len == 0 || !val || beg >= strlen(val)) { | |
| arith_err: | |
| @@ -0,0 +1,6 @@ | |
| + | parameter 'abcdef' |
| + | varoffset2 'cdef' |
| + | varoffset-2 'ef' |
| + | literal '2' 'cdef' |
| + | literal '-2' 'abcdef' |
| + | literal ' -2' 'ef' |
| @@ -0,0 +1,11 @@ | |
| + | parameter=abcdef |
| + | offset=2 |
| + | noffset=-2 |
| + | echo "parameter '${parameter}'" |
| + | echo "varoffset2 '${parameter:${offset}}'" |
| + | echo "varoffset-2 '${parameter:${noffset}}'" |
| + | echo "literal '2' '${parameter:2}'" |
| + | # This is not inrpreted as ${VAR:POS{:LEN}}, |
| + | # but as ${VAR:=WORD} - if VAR is unset or null, substitute WORD |
| + | echo "literal '-2' '${parameter:-2}'" |
| + | echo "literal ' -2' '${parameter: -2}'" |