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)
This commit is contained in:
parent
2b94976ff7
commit
d21d692410
@ -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;
|
||||
|
90
tools/regression/bin/sh/expansion/tilde2.0
Normal file
90
tools/regression/bin/sh/expansion/tilde2.0
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user