hush: support ${VAR:N:-M}
function old new delta expand_one_var 1602 1615 +13 builtin_type 114 116 +2 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
203fd7bc66
commit
e32b6503e7
52
shell/hush.c
52
shell/hush.c
@ -5723,32 +5723,34 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha
|
||||
if (errmsg)
|
||||
goto arith_err;
|
||||
debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
|
||||
if (len >= 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:
|
||||
val = NULL;
|
||||
} else {
|
||||
/* Paranoia. What if user entered 9999999999999
|
||||
* which fits in arith_t but not int? */
|
||||
if (len >= INT_MAX)
|
||||
len = INT_MAX;
|
||||
val = to_be_freed = xstrndup(val + beg, len);
|
||||
}
|
||||
debug_printf_varexp("val:'%s'\n", val);
|
||||
} else
|
||||
//TODO: in bash, len=-n means strlen()-n
|
||||
#endif /* HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH */
|
||||
{
|
||||
die_if_script("malformed ${%s:...}", var);
|
||||
val = NULL;
|
||||
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) {
|
||||
/* in bash, len=-n means strlen()-n */
|
||||
len = (arith_t)strlen(val) - beg + len;
|
||||
if (len < 0) /* bash compat */
|
||||
die_if_script("%s: substring expression < 0", var);
|
||||
}
|
||||
if (len == 0 || !val || beg >= strlen(val)) {
|
||||
arith_err:
|
||||
val = NULL;
|
||||
} else {
|
||||
/* Paranoia. What if user entered 9999999999999
|
||||
* which fits in arith_t but not int? */
|
||||
if (len >= INT_MAX)
|
||||
len = INT_MAX;
|
||||
val = to_be_freed = xstrndup(val + beg, len);
|
||||
}
|
||||
debug_printf_varexp("val:'%s'\n", val);
|
||||
#else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */
|
||||
die_if_script("malformed ${%s:...}", var);
|
||||
val = NULL;
|
||||
#endif
|
||||
} else { /* one of "-=+?" */
|
||||
/* Standard-mandated substitution ops:
|
||||
* ${var?word} - indicate error if unset
|
||||
|
23
shell/hush_test/hush-vars/var_bash1b.right
Normal file
23
shell/hush_test/hush-vars/var_bash1b.right
Normal file
@ -0,0 +1,23 @@
|
||||
all |0123456
|
||||
4: |456
|
||||
4:2 |45
|
||||
4:-1 |45
|
||||
4:-2 |4
|
||||
4:-3 |
|
||||
-4: |3456
|
||||
-4:2 |34
|
||||
-4:-1 |345
|
||||
-4:-2 |34
|
||||
-4:-3 |3
|
||||
-4:-4 |
|
||||
-4:i=2 |34
|
||||
-4:i=-2|34
|
||||
-4:i=-3|3
|
||||
-4:i=-4|
|
||||
-5: |23456
|
||||
-6: |123456
|
||||
-7: |0123456
|
||||
-8: |
|
||||
-9: |
|
||||
-9:-99 |
|
||||
Ok:0
|
24
shell/hush_test/hush-vars/var_bash1b.tests
Executable file
24
shell/hush_test/hush-vars/var_bash1b.tests
Executable file
@ -0,0 +1,24 @@
|
||||
set -- 0123456
|
||||
echo "all |"$1
|
||||
echo "4: |"${1:4}
|
||||
echo "4:2 |"${1:4:2}
|
||||
echo "4:-1 |"${1:4:-1}
|
||||
echo "4:-2 |"${1:4:-2}
|
||||
echo "4:-3 |"${1:4:-3}
|
||||
echo "-4: |"${1: -4}
|
||||
echo "-4:2 |"${1: -4:2}
|
||||
echo "-4:-1 |"${1: -4:-1}
|
||||
echo "-4:-2 |"${1: -4:-2}
|
||||
echo "-4:-3 |"${1: -4:-3}
|
||||
echo "-4:-4 |"${1: -4:-4}
|
||||
i=2; echo "-4:i=2 |"${1: -4:i}
|
||||
i=-2; echo "-4:i=-2|"${1: -4:i}
|
||||
i=-3; echo "-4:i=-3|"${1: -4:i}
|
||||
i=-4; echo "-4:i=-4|"${1: -4:i}
|
||||
echo "-5: |"${1: -5}
|
||||
echo "-6: |"${1: -6}
|
||||
echo "-7: |"${1: -7}
|
||||
echo "-8: |"${1: -8}
|
||||
echo "-9: |"${1: -9}
|
||||
echo "-9:-99 |"${1: -9:-99}
|
||||
echo Ok:$?
|
Loading…
Reference in New Issue
Block a user