[git commit] hush: implement negative start in the ${v: -n[:m]} idiom

Denys Vlasenko vda.linux at googlemail.com
Thu Jul 6 17:48:20 UTC 2017


commit: https://git.busybox.net/busybox/commit/?id=5dad7bdc3bdad8e9934d45301d5a8c51e843cd7b
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash_test/ash-vars/var_bash6.right    |  5 +++++
 shell/ash_test/ash-vars/var_bash6.tests    |  9 +++++++++
 shell/hush.c                               |  8 ++++++--
 shell/hush_test/hush-vars/var_bash1a.right |  6 ++++++
 shell/hush_test/hush-vars/var_bash1a.tests | 11 +++++++++++
 5 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/shell/ash_test/ash-vars/var_bash6.right b/shell/ash_test/ash-vars/var_bash6.right
new file mode 100644
index 0000000..63fc23d
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_bash6.right
@@ -0,0 +1,5 @@
+Expected Actual
+a*z    : a*z
+\z     : \z
+a1z a2z: a1z a2z
+z      : z
diff --git a/shell/ash_test/ash-vars/var_bash6.tests b/shell/ash_test/ash-vars/var_bash6.tests
new file mode 100755
index 0000000..cf2e4f0
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_bash6.tests
@@ -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
diff --git a/shell/hush.c b/shell/hush.c
index 64b33cf..f6b50de 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -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:
diff --git a/shell/hush_test/hush-vars/var_bash1a.right b/shell/hush_test/hush-vars/var_bash1a.right
new file mode 100644
index 0000000..1965b5c
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash1a.right
@@ -0,0 +1,6 @@
+parameter     'abcdef'
+varoffset2    'cdef'
+varoffset-2   'ef'
+literal '2'   'cdef'
+literal '-2'  'abcdef'
+literal ' -2' 'ef'
diff --git a/shell/hush_test/hush-vars/var_bash1a.tests b/shell/hush_test/hush-vars/var_bash1a.tests
new file mode 100755
index 0000000..551dd9a
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash1a.tests
@@ -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}'"


More information about the busybox-cvs mailing list