aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-17 16:46:57 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-17 16:46:57 +0200
commite32b6503e75d5bcbf8ffff69cafb09523ff2b482 (patch)
treed0d68a95f68d55215b86f792e11e89b1e75b1ed1
parent203fd7bc66b869e5022ad33d26065e69eaaaf66b (diff)
downloadbusybox-w32-e32b6503e75d5bcbf8ffff69cafb09523ff2b482.tar.gz
busybox-w32-e32b6503e75d5bcbf8ffff69cafb09523ff2b482.tar.bz2
busybox-w32-e32b6503e75d5bcbf8ffff69cafb09523ff2b482.zip
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>
-rw-r--r--shell/hush.c48
-rw-r--r--shell/hush_test/hush-vars/var_bash1b.right23
-rwxr-xr-xshell/hush_test/hush-vars/var_bash1b.tests24
3 files changed, 72 insertions, 23 deletions
diff --git a/shell/hush.c b/shell/hush.c
index fd2a3d0f5..836f3b83c 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5723,32 +5723,34 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha
5723 if (errmsg) 5723 if (errmsg)
5724 goto arith_err; 5724 goto arith_err;
5725 debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len); 5725 debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
5726 if (len >= 0) { 5726 if (beg < 0) {
5727 if (beg < 0) { 5727 /* negative beg counts from the end */
5728 /* negative beg counts from the end */ 5728 beg = (arith_t)strlen(val) + beg;
5729 beg = (arith_t)strlen(val) + beg; 5729 if (beg < 0) /* ${v: -999999} is "" */
5730 if (beg < 0) /* ${v: -999999} is "" */ 5730 beg = len = 0;
5731 beg = len = 0; 5731 }
5732 } 5732 debug_printf_varexp("from val:'%s'\n", val);
5733 debug_printf_varexp("from val:'%s'\n", val); 5733 if (len < 0) {
5734 if (len == 0 || !val || beg >= strlen(val)) { 5734 /* in bash, len=-n means strlen()-n */
5735 len = (arith_t)strlen(val) - beg + len;
5736 if (len < 0) /* bash compat */
5737 die_if_script("%s: substring expression < 0", var);
5738 }
5739 if (len == 0 || !val || beg >= strlen(val)) {
5735 arith_err: 5740 arith_err:
5736 val = NULL;
5737 } else {
5738 /* Paranoia. What if user entered 9999999999999
5739 * which fits in arith_t but not int? */
5740 if (len >= INT_MAX)
5741 len = INT_MAX;
5742 val = to_be_freed = xstrndup(val + beg, len);
5743 }
5744 debug_printf_varexp("val:'%s'\n", val);
5745 } else
5746//TODO: in bash, len=-n means strlen()-n
5747#endif /* HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH */
5748 {
5749 die_if_script("malformed ${%s:...}", var);
5750 val = NULL; 5741 val = NULL;
5742 } else {
5743 /* Paranoia. What if user entered 9999999999999
5744 * which fits in arith_t but not int? */
5745 if (len >= INT_MAX)
5746 len = INT_MAX;
5747 val = to_be_freed = xstrndup(val + beg, len);
5751 } 5748 }
5749 debug_printf_varexp("val:'%s'\n", val);
5750#else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */
5751 die_if_script("malformed ${%s:...}", var);
5752 val = NULL;
5753#endif
5752 } else { /* one of "-=+?" */ 5754 } else { /* one of "-=+?" */
5753 /* Standard-mandated substitution ops: 5755 /* Standard-mandated substitution ops:
5754 * ${var?word} - indicate error if unset 5756 * ${var?word} - indicate error if unset
diff --git a/shell/hush_test/hush-vars/var_bash1b.right b/shell/hush_test/hush-vars/var_bash1b.right
new file mode 100644
index 000000000..fafc0f07c
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash1b.right
@@ -0,0 +1,23 @@
1all |0123456
24: |456
34:2 |45
44:-1 |45
54:-2 |4
64:-3 |
7-4: |3456
8-4:2 |34
9-4:-1 |345
10-4:-2 |34
11-4:-3 |3
12-4:-4 |
13-4:i=2 |34
14-4:i=-2|34
15-4:i=-3|3
16-4:i=-4|
17-5: |23456
18-6: |123456
19-7: |0123456
20-8: |
21-9: |
22-9:-99 |
23Ok:0
diff --git a/shell/hush_test/hush-vars/var_bash1b.tests b/shell/hush_test/hush-vars/var_bash1b.tests
new file mode 100755
index 000000000..efbdef35c
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash1b.tests
@@ -0,0 +1,24 @@
1set -- 0123456
2 echo "all |"$1
3 echo "4: |"${1:4}
4 echo "4:2 |"${1:4:2}
5 echo "4:-1 |"${1:4:-1}
6 echo "4:-2 |"${1:4:-2}
7 echo "4:-3 |"${1:4:-3}
8 echo "-4: |"${1: -4}
9 echo "-4:2 |"${1: -4:2}
10 echo "-4:-1 |"${1: -4:-1}
11 echo "-4:-2 |"${1: -4:-2}
12 echo "-4:-3 |"${1: -4:-3}
13 echo "-4:-4 |"${1: -4:-4}
14i=2; echo "-4:i=2 |"${1: -4:i}
15i=-2; echo "-4:i=-2|"${1: -4:i}
16i=-3; echo "-4:i=-3|"${1: -4:i}
17i=-4; echo "-4:i=-4|"${1: -4:i}
18 echo "-5: |"${1: -5}
19 echo "-6: |"${1: -6}
20 echo "-7: |"${1: -7}
21 echo "-8: |"${1: -8}
22 echo "-9: |"${1: -9}
23 echo "-9:-99 |"${1: -9:-99}
24echo Ok:$?