summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2010-04-03 22:04:44 +0000
committerjilles <jilles@FreeBSD.org>2010-04-03 22:04:44 +0000
commitd21d692410a270bb6fc76edf61766b0b28bf6c71 (patch)
tree1e39cf9c1a6ff2cc7d02b45795a1ca4b3b2a5960
parent2b94976ff794b04695669e119aa0fe941a54408b (diff)
downloadFreeBSD-src-d21d692410a270bb6fc76edf61766b0b28bf6c71.zip
FreeBSD-src-d21d692410a270bb6fc76edf61766b0b28bf6c71.tar.gz
sh: Do tilde expansion in substitutions.
This applies to word in ${v-word}, ${v+word}, ${v=word}, ${v?word} (which inherits quoting from the outside) and in ${v%word}, ${v%%word}, ${v#word}, ${v##word} (which does not inherit any quoting). In all cases tilde expansion is only attempted at the start of word, even if word contains spaces. This agrees with POSIX and other shells. This is the last part of the patch tested in the exp-run. Exp-run done by: erwin (with some other sh(1) changes)
-rw-r--r--bin/sh/expand.c6
-rw-r--r--tools/regression/bin/sh/expansion/tilde2.090
2 files changed, 93 insertions, 3 deletions
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index a2019b2..ab885ac 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -273,7 +273,6 @@ exptilde(char *p, int flag)
switch(c) {
case CTLESC: /* This means CTL* are always considered quoted. */
case CTLVAR:
- case CTLENDVAR:
case CTLBACKQ:
case CTLBACKQ | CTLQUOTE:
case CTLARI:
@@ -285,6 +284,7 @@ exptilde(char *p, int flag)
goto done;
break;
case '/':
+ case CTLENDVAR:
goto done;
}
p++;
@@ -506,9 +506,9 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
int amount;
herefd = -1;
- argstr(p, subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX ||
+ argstr(p, (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX ||
subtype == VSTRIMRIGHT || subtype == VSTRIMRIGHTMAX ?
- EXP_CASE : 0);
+ EXP_CASE : 0) | EXP_TILDE);
STACKSTRNUL(expdest);
herefd = saveherefd;
argbackq = saveargbackq;
diff --git a/tools/regression/bin/sh/expansion/tilde2.0 b/tools/regression/bin/sh/expansion/tilde2.0
new file mode 100644
index 0000000..4f8ed9b
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/tilde2.0
@@ -0,0 +1,90 @@
+# $FreeBSD$
+
+HOME=/tmp
+roothome=~root
+if [ "$roothome" = "~root" ]; then
+ echo "~root is not expanded!"
+ exit 2
+fi
+
+testcase() {
+ code="$1"
+ expected="$2"
+ oIFS="$IFS"
+ eval "$code"
+ IFS='|'
+ result="$#|$*"
+ IFS="$oIFS"
+ if [ "x$result" = "x$expected" ]; then
+ ok=x$ok
+ else
+ failures=x$failures
+ echo "For $code, expected $expected actual $result"
+ fi
+}
+
+testcase 'set -- ${$+~}' '1|/tmp'
+testcase 'set -- ${$+~/}' '1|/tmp/'
+testcase 'set -- ${$+~/foo}' '1|/tmp/foo'
+testcase 'set -- ${$+x~}' '1|x~'
+testcase 'set -- ${$+~root}' "1|$roothome"
+testcase 'set -- ${$+"~"}' '1|~'
+testcase 'set -- ${$+"~/"}' '1|~/'
+testcase 'set -- ${$+"~/foo"}' '1|~/foo'
+testcase 'set -- ${$+"x~"}' '1|x~'
+testcase 'set -- ${$+"~root"}' "1|~root"
+testcase 'set -- "${$+~}"' '1|~'
+testcase 'set -- "${$+~/}"' '1|~/'
+testcase 'set -- "${$+~/foo}"' '1|~/foo'
+testcase 'set -- "${$+x~}"' '1|x~'
+testcase 'set -- "${$+~root}"' "1|~root"
+testcase 'set -- ${HOME#~}' '0|'
+h=~
+testcase 'set -- "$h"' '1|/tmp'
+f=~/foo
+testcase 'set -- "$f"' '1|/tmp/foo'
+testcase 'set -- ${f#~}' '1|/foo'
+testcase 'set -- ${f#~/}' '1|foo'
+
+ooIFS=$IFS
+IFS=m
+testcase 'set -- ${$+~}' '1|/tmp'
+testcase 'set -- ${$+~/foo}' '1|/tmp/foo'
+testcase 'set -- ${$+$h}' '2|/t|p'
+testcase 'set -- ${HOME#~}' '0|'
+IFS=$ooIFS
+
+t=\~
+testcase 'set -- ${$+$t}' '1|~'
+r=$(cat <<EOF
+${HOME#~}
+EOF
+)
+testcase 'set -- $r' '0|'
+r=$(cat <<EOF
+${HOME#'~'}
+EOF
+)
+testcase 'set -- $r' '1|/tmp'
+r=$(cat <<EOF
+${t#'~'}
+EOF
+)
+testcase 'set -- $r' '0|'
+r=$(cat <<EOF
+${roothome#~root}
+EOF
+)
+testcase 'set -- $r' '0|'
+r=$(cat <<EOF
+${f#~}
+EOF
+)
+testcase 'set -- $r' '1|/foo'
+r=$(cat <<EOF
+${f#~/}
+EOF
+)
+testcase 'set -- $r' '1|foo'
+
+test "x$failures" = x
OpenPOWER on IntegriCloud