summaryrefslogtreecommitdiffstats
path: root/tests/dollar-at-star
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/dollar-at-star332
-rw-r--r--tests/dollar-at-star1.sub36
-rw-r--r--tests/dollar-at-star10.sub66
-rw-r--r--tests/dollar-at-star11.sub80
-rw-r--r--tests/dollar-at-star2.sub220
-rw-r--r--tests/dollar-at-star3.sub57
-rw-r--r--tests/dollar-at-star4.sub112
-rw-r--r--tests/dollar-at-star5.sub66
-rw-r--r--tests/dollar-at-star6.sub42
-rw-r--r--tests/dollar-at-star7.sub38
-rw-r--r--tests/dollar-at-star8.sub14
-rw-r--r--tests/dollar-at-star9.sub278
12 files changed, 1341 insertions, 0 deletions
diff --git a/tests/dollar-at-star b/tests/dollar-at-star
new file mode 100644
index 0000000..721eea1
--- /dev/null
+++ b/tests/dollar-at-star
@@ -0,0 +1,332 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# first, let's start with the basics
+
+recho "$@"
+recho "$*"
+
+recho $@
+recho $*
+
+foo=$*
+foo=$@
+
+foo="$*"
+foo="$@"
+
+unset -v bar
+
+foo=${bar:-$*}
+foo=${bar:-$@}
+
+foo=${bar:-"$*"}
+foo=${bar:-"$@"}
+
+foo=${!*}
+foo=${!@}
+
+set a b
+
+recho "$*"
+
+# If IFS is null, the parameters are joined without separators
+IFS=''
+recho "$*"
+
+# If IFS is unset, the parameters are separated by spaces
+unset IFS
+recho "${*}"
+
+recho "$@"
+recho $@
+
+IFS='/'
+set bob 'tom dick harry' joe
+set $*
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set ${*}
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set $@
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set ${@}
+recho $#
+recho $1
+recho $2
+recho $3
+
+# according to POSIX.2, unquoted $* should expand to multiple words if
+# $IFS is null, just like unquoted $@
+IFS=''
+set bob 'tom dick harry' joe
+set $*
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set $@
+recho $#
+recho $1
+recho $2
+recho $3
+
+# if IFS is unset, the individual positional parameters are split on
+# " \t\n" if $* or $@ are unquoted
+unset IFS
+set bob 'tom dick harry' joe
+set $*
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set $@
+recho $#
+recho $1
+recho $2
+recho $3
+
+# but not for "$@" or "$*"
+set bob 'tom dick harry' joe
+set "$*"
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set "$@"
+recho $#
+recho $1
+recho $2
+recho $3
+
+# POSIX.2 says these should both expand the positional parameters
+# to multiple words
+set a b c d e
+IFS=""
+recho $@
+recho "$@"
+
+# this example is straight from the POSIX.2 rationale
+set foo bar bam
+
+recho "$@"
+recho "$*"
+
+unset IFS
+
+recho "$@"
+recho $@
+recho "$*"
+
+IFS=:
+
+# special variables
+set -- 1 2 3 4 5 6 7 8 9 10
+
+bar=${*}
+foo=$*
+echo foo = "$foo"
+echo bar = "$bar"
+
+foo1=$@
+bar1=${@}
+
+echo foo1 = "$foo1"
+echo bar1 = "$bar1"
+
+foo2="$*"
+bar2="${*}"
+
+echo foo2 = "$foo2"
+echo bar2 = "$bar2"
+
+eval foo3='$*' bar3='${*}'
+echo foo3 = "$foo3"
+echo bar3 = "$bar3"
+
+case $* in
+*\:*) echo ok 1;;
+*) echo bad 1;;
+esac
+
+case $@ in
+*\:*) echo bad 2;;
+*) echo ok 2;;
+esac
+
+case "$*" in
+*\:*) echo ok 3;;
+*) echo bad 3;;
+esac
+
+case "$@" in
+*\:*) echo bad 4;;
+*) echo ok 4;;
+esac
+
+IFS=$' \t\n'
+
+bar=${*}
+foo=$*
+echo foo = "$foo"
+echo bar = "$bar"
+
+foo1=$@
+bar1=${@}
+
+echo foo1 = "$foo1"
+echo bar1 = "$bar1"
+
+foo2="$*"
+bar2="${*}"
+
+echo foo2 = "$foo2"
+echo bar2 = "$bar2"
+
+eval foo3='$*' bar3='${*}'
+echo foo3 = "$foo3"
+echo bar3 = "$bar3"
+
+case $* in
+*\ *) echo ok 1;;
+*) echo bad 1;;
+esac
+
+case $@ in
+*\ *) echo ok 2;;
+*) echo bad 2;;
+esac
+
+case "$*" in
+*\ *) echo ok 3;;
+*) echo bad 3;;
+esac
+
+case "$@" in
+*\ *) echo ok 4;;
+*) echo bad 4;;
+esac
+
+# tests for the effect of quoting $* and $@ in an assignment context (plus
+# arrays) -- bugs through bash 4.2
+${THIS_SH} ./dollar-at-star1.sub
+
+# more tests for expanding $@ and $* in a context where there is no word
+# splitting
+${THIS_SH} ./dollar-at-star2.sub
+${THIS_SH} ./dollar-at-star3.sub
+${THIS_SH} ./dollar-at-star4.sub
+${THIS_SH} ./dollar-at-star5.sub
+${THIS_SH} ./dollar-at-star6.sub
+${THIS_SH} ./dollar-at-star7.sub
+
+# tests for expansions of $@ and ${a[@]} (vs. $* and ${a[*]}) on the RHS of
+# assignment statements with non-default IFS: $@ expands to args or array
+# members separated by spaces
+${THIS_SH} ./dollar-at-star8.sub
+
+# more tests of the expansions of $@ and $* (and their array equivalents)
+# with different values for IFS
+${THIS_SH} ./dollar-at-star9.sub
+
+# tests for expansions of "$*" and "$@" and their array equivalents when $1 == ''
+# and we're using the POSIX word expansions
+${THIS_SH} ./dollar-at-star10.sub
+${THIS_SH} ./dollar-at-star11.sub
+
+# tests for special expansion of "$*" and "${array[*]}" when used with other
+# expansions -- bugs through bash-2.05b
+${THIS_SH} ./dollar-star1.sub
+
+# tests for expansion of "$@" on rhs of things like ${param:+word}. Bugs
+# though bash-2.05b
+${THIS_SH} ./dollar-at1.sub
+
+# tests for expansion of other variables in double-quoted strings containing
+# $@. Bugs through bash-2.05b
+${THIS_SH} ./dollar-at2.sub
+
+# tests for various expansions of $* in different contexts -- word split,
+# no splitting, etc. when $IFS is NUL
+${THIS_SH} ./dollar-star2.sub
+
+# tests for expansions of "${array[*]}" and "${array[@]}" when $IFS is not the
+# default and the array contains null elements
+${THIS_SH} ./dollar-star3.sub
+
+# test for set -u and expansions of $@ when there are no positional parameters
+${THIS_SH} ./dollar-at3.sub
+# test for set -u and expansions of $* when there are no positional parameters
+${THIS_SH} ./dollar-star4.sub
+
+# tests for expansions of $* when IFS is null
+${THIS_SH} ./dollar-star5.sub
+
+# tests for inappropriate word splitting through bash-4.2
+${THIS_SH} ./dollar-at4.sub
+
+# tests for problems with "$@" preceded and followed by other quoted expansions
+# through bash-4.2
+${THIS_SH} ./dollar-at5.sub
+
+# tests for problems with "${@:1}" and other expansions with null entries
+# in positional parameters
+${THIS_SH} ./dollar-at6.sub
+
+# tests for expansions of $* when $1 == ""; problem through bash-4.2
+${THIS_SH} ./dollar-star6.sub
+
+# tests for expansions of $* (unquoted) when IFS changes (e.g., ${IFS:=-})
+# problem through bash-4.2
+${THIS_SH} ./dollar-star7.sub
+
+# tests for expansions of $* (unquoted) when IFS is null and word splitting is
+# not going to be performed.
+# problem through bash-4.4 in some parameter expansion contexts
+${THIS_SH} ./dollar-star8.sub
+
+# tests for expansions of "$@" when there are no positional parameter or when
+# $1 == '' and the expansion is preceded by something that results in a quoted
+# null string
+${THIS_SH} ./dollar-at7.sub
+
+# tests for expansions of $* when in an assignment context (no splitting) and
+# IFS is null
+${THIS_SH} ./dollar-star9.sub
+
+# more tests for expansions of $* when not splitting with IFS set or unset and
+# null strings as the positional parameters
+${THIS_SH} ./dollar-star10.sub
+
+exit 0
diff --git a/tests/dollar-at-star1.sub b/tests/dollar-at-star1.sub
new file mode 100644
index 0000000..ef15efc
--- /dev/null
+++ b/tests/dollar-at-star1.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# from dan douglas
+expassign()
+{
+ typeset -a a
+ a=("$@")
+ typeset var asn
+
+ while IFS= read -r asn; do
+ IFS=: command eval "$asn"
+ printf '%-14s... %s\n' "$asn" "$var"
+ done <<\EOF
+var=${a[*]}
+var="${a[*]}"
+var=$*
+var="$*"
+var=${a[@]}
+var="${a[@]}"
+var=$@
+var="$@"
+EOF
+}
+
+expassign one:::two three:::four
diff --git a/tests/dollar-at-star10.sub b/tests/dollar-at-star10.sub
new file mode 100644
index 0000000..6b52b01
--- /dev/null
+++ b/tests/dollar-at-star10.sub
@@ -0,0 +1,66 @@
+# checks for array variables and positional parameter expansions losing quoted
+# null string expansions -- problem through bash-5.1
+
+set -- ''
+myvar[0]=
+a="${myvar[*]}"
+
+recho "$*"
+recho "${*}"
+
+recho "${a}"
+recho "${myvar[*]}"
+
+recho "${a:+nonnull}"
+recho "${myvar[*]:+nonnull}"
+
+a="${myvar[@]}"
+
+recho "$@"
+recho "${@}"
+
+recho "${a}"
+recho "${myvar[@]}"
+
+recho "${a:+nonnull}"
+recho "${myvar[@]:+nonnull}"
+
+# check to make sure literal CTLNULs are handled correctly
+set -- $'\x7f'
+
+recho "$@"
+recho "${@}"
+recho "${@:+nonnull}"
+
+recho "$*"
+recho "${*}"
+recho "${*:+nonnull}"
+
+shift $#
+
+# these should echo nothing
+recho "${@}"
+recho "${@:+nonnull}"
+
+unset -v a
+
+# make sure that other null expansions result in null strings where appropriate
+set -- ''
+a[0]=
+
+recho "$*"$x
+recho "${*}"$x
+
+recho "$@"$x
+recho "${@}"$x
+
+recho "${a[*]}"$x
+recho "${a[@]}"$x
+
+
+recho "$@"$x
+recho "${@}"$x
+
+recho "${a[*]}"
+recho "${a[@]}"
+
diff --git a/tests/dollar-at-star11.sub b/tests/dollar-at-star11.sub
new file mode 100644
index 0000000..b7a6ec4
--- /dev/null
+++ b/tests/dollar-at-star11.sub
@@ -0,0 +1,80 @@
+a[0]='/'
+set -- /
+
+# these should all result in the empty (null) string
+
+recho "${a[0]%?}"
+recho "${a[*]%?}"
+recho "${a[@]%?}"
+
+recho "${*%?}"
+recho "${@%?}"
+
+recho "${a[0]#?}"
+recho "${a[*]#?}"
+recho "${a[@]#?}"
+
+recho "${*#?}"
+recho "${@#?}"
+
+recho "${a[0]/\//}"
+recho "${a[*]/\//}"
+recho "${a[@]/\//}"
+
+recho "${*/\//}"
+recho "${@/\//}"
+
+recho "${a[0]:1:1}"
+# these next four will all echo /
+
+# arrays are zero-based
+recho "${a[*]:0:1}"
+recho "${a[@]:0:1}"
+# but the positional parameters start at 1
+recho "${*:1:1}"
+recho "${@:1:1}"
+
+a[0]=''
+set -- ''
+
+# arrays are zero-based
+recho "${a[*]:0:1}"
+recho "${a[@]:0:1}"
+
+recho "${*:1:1}"
+recho "${@:1:1}"
+
+# these should all result in the empty (null) string, or quoted as such
+
+recho "${a[0]@Q}"
+recho "${a[*]@Q}"
+recho "${a[@]@Q}"
+
+recho "${*@Q}"
+recho "${@@Q}"
+
+recho "${a[0]@L}"
+recho "${a[*]@L}"
+recho "${a[@]@L}"
+
+recho "${*@L}"
+recho "${@@L}"
+
+# examples from the bug report
+unset -v a
+
+a[0]='/'
+for i in "${a[@]%/}"; do recho "$i"; done
+
+a[0]=''
+for i in "${a[@]}"; do recho "$i"; done
+
+a[0]='/'
+a[1]="//"
+for i in "${a[@]%/}"; do recho "$i"; done
+
+unset -v x y
+x=('/')
+y=("${x[@]%/}")
+
+echo "${#x[@]}:${#y[@]}"
diff --git a/tests/dollar-at-star2.sub b/tests/dollar-at-star2.sub
new file mode 100644
index 0000000..64ab1eb
--- /dev/null
+++ b/tests/dollar-at-star2.sub
@@ -0,0 +1,220 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+OIFS="$IFS"
+foo=' ,foo'
+set -- "$foo"
+
+if [[ $foo = ,* ]]; then echo bad 1; else echo ok 1; fi
+if [[ $@ = ,* ]]; then echo bad 2; else echo ok 2; fi
+if [[ $* = ,* ]]; then echo bad 3; else echo ok 3; fi
+if [[ ${@} = ,* ]]; then echo bad 4; else echo ok 4; fi
+if [[ ${*} = ,* ]]; then echo bad 5; else echo ok 5; fi
+if [[ $1 = ,* ]]; then echo bad 6; else echo ok 6; fi
+
+set -- ' ,foo'
+if [[ $foo = ,* ]]; then echo bad 7; else echo ok 7; fi
+if [[ $@ = ,* ]]; then echo bad 8; else echo ok 8; fi
+if [[ $* = ,* ]]; then echo bad 9; else echo ok 9; fi
+if [[ ${@} = ,* ]]; then echo bad 10; else echo ok 10; fi
+if [[ ${*} = ,* ]]; then echo bad 11; else echo ok 11; fi
+if [[ $1 = ,* ]]; then echo bad 12; else echo ok 12; fi
+
+IFS=
+if [[ $@ = ,* ]]; then echo bad 13; else echo ok 13; fi
+if [[ $* = ,* ]]; then echo bad 14; else echo ok 14; fi
+IFS="$OIFS"
+
+foo=' ,foo'
+set -- ' ' ',foo'
+
+if [[ $@ = ,* ]]; then echo bad at 1; else echo ok at 1; fi
+if [[ ${@} = ,* ]]; then echo bad at 2; else echo ok at 2; fi
+
+if [[ $* = ,* ]]; then echo bad star 1; else echo ok star 1; fi
+if [[ ${*} = ,* ]]; then echo bad star 2; else echo ok star 2; fi
+
+foo=' ,foo'
+set -- "$foo"
+
+# expand_string_for_rhs
+
+foo2=$@
+echo "$foo2"
+
+foo2=$*
+echo "$foo2"
+
+foo2="$@"
+echo "$foo2"
+
+foo2="$*"
+echo "$foo2"
+
+# expand_word_unsplit
+case $@ in
+$foo2) echo ok at 1 ;;
+*) echo bad at 1 ;;
+esac
+
+# also uses expand_word_leave_quoted
+case $@ in
+$@) echo ok at 2;;
+*) echo bad at 2;;
+esac
+
+case $@ in
+$foo) echo ok at 3 ;;
+*) echo bad at 3;;
+esac
+
+# expand_word_unsplit
+case $* in
+$foo2) echo ok star 1 ;;
+*) echo bad star 1 ;;
+esac
+
+# also uses expand_word_leave_quoted
+case $* in
+$*) echo ok star 2;;
+*) echo bad star 2;;
+esac
+
+case $* in
+$foo) echo ok star 3 ;;
+*) echo bad star 3;;
+esac
+
+case $@ in
+$*) echo ok at-star 1;;
+*) echo bad at-star 1;;
+esac
+
+case $* in
+$@) echo ok at-star 2;;
+*) echo bad at-star 2;;
+esac
+
+foo='a b c'
+set -- $foo
+
+# expand_string_for_rhs
+IFS='|'
+foo2=$@
+echo "$foo2"
+
+foo2=$*
+echo "$foo2"
+
+foo2="$@"
+echo "$foo2"
+
+foo2="$*"
+echo "$foo2"
+
+foo="a b c"
+set -- $foo
+
+if [[ $@ = $foo ]]; then echo ok at 1; else echo bad at 1; fi
+if [[ $foo = $@ ]]; then echo ok at 2; else echo bad at 2; fi
+
+case $@ in
+$@) echo ok at 3 ;;
+*) echo bad at 3 ;;
+esac
+
+case $@ in
+$foo) echo ok at 4;;
+*) echo bad at 4;;
+esac
+
+case $foo in
+$@) echo ok at 5;;
+*) echo bad at 5;;
+esac
+IFS="$OIFS"
+
+foo="a b c"
+set -- $foo
+
+IFS=:
+if [[ $@ = $foo ]]; then echo ok at 1; else echo bad at 1; fi
+if [[ $foo = $@ ]]; then echo ok at 2; else echo bad at 2; fi
+
+case $@ in
+$@) echo ok at 3 ;;
+*) echo bad at 3 ;;
+esac
+
+case $@ in
+$foo) echo ok at 4;;
+*) echo bad at 4;;
+esac
+
+case $foo in
+$@) echo ok at 5;;
+*) echo bad at 5;;
+esac
+IFS="$OIFS"
+
+foo="a b c"
+set -- $foo
+
+IFS='|'
+foo2=$@
+
+case $@ in
+$@) echo ok at 1 ;;
+*) echo bad at 1 ;;
+esac
+
+case $foo2 in
+$foo) echo ok at 2;;
+*) echo bad at 2;;
+esac
+
+case $foo in
+$foo2) echo ok at 3;;
+*) echo bad at 3;;
+esac
+
+case $foo in
+$foo) echo ok at 4;;
+*) echo bad at 4;;
+esac
+
+case $foo2 in
+$foo2) echo ok at 5;;
+*) echo bad at 5;;
+esac
+
+case $foo2 in
+$@) echo ok at 6;;
+*) echo bad at 6;;
+esac
+
+case $@ in
+$foo2) echo ok at 7;;
+*) echo bad at 7;;
+esac
+
+case $foo in
+$@) echo ok at 8;;
+*) echo bad at 8;;
+esac
+
+case $@ in
+$foo) echo ok at 9;;
+*) echo bad at 9;;
+esac
+IFS="$OIFS"
diff --git a/tests/dollar-at-star3.sub b/tests/dollar-at-star3.sub
new file mode 100644
index 0000000..da05444
--- /dev/null
+++ b/tests/dollar-at-star3.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+unset f ; f=abcd
+
+first_char=${f[@]:0:1}
+recho $first_char
+
+first_char=${f[0]:0:1}
+recho $first_char
+
+first_char=${f:0:1}
+recho $first_char
+
+first_char="${f[@]:0:1}"
+recho $first_char
+
+first_char="${f[@]:0:1}"
+recho $first_char
+
+first_char="${f[0]:0:1}"
+recho $first_char
+
+first_char="${f:0:1}"
+recho $first_char
+
+unset f;
+f=( one two three )
+first_word=${f[@]:0:1}
+recho $first_word
+
+first_word=${f[0]:0:1}
+recho $first_word
+
+first_word=${f:0:1}
+recho $first_word
+
+unset f;
+f=( one two three )
+first_word=${f[@]:0:1}
+recho $first_word
+
+set -- abc def ghi
+
+printf '<%s> ' "123 $@ 456"; echo
+printf '<%s> ' "123 $@\ 456"; echo
+
diff --git a/tests/dollar-at-star4.sub b/tests/dollar-at-star4.sub
new file mode 100644
index 0000000..9f7da8e
--- /dev/null
+++ b/tests/dollar-at-star4.sub
@@ -0,0 +1,112 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests for quoted and unquoted, split and unsplit expansions of $@ and $*
+# Posix interpretation 221 speaks to this issue
+
+set -- a b
+IFS=
+x=abc
+
+printf "<%s>\n" ${x#$*}
+
+a="a bc"
+echo ${a#$*}
+unset x a
+
+a=$@
+echo "$a"
+
+a=$*
+echo "$a"
+
+printf '<%s>' $@ ; echo
+
+IFS='
+'
+
+a=$@
+echo "$a"
+
+a=$*
+echo "$a"
+
+unset a
+
+unset IFS
+set a b "c d"
+printf '<%s>' $* ; echo
+printf '<%s>' ${q-$*} ; echo
+
+IFS=
+set a b "c d"
+printf '<%s>' $* ; echo
+printf '<%s>' ${q-$*} ; echo
+
+IFS=:
+set a b
+printf '<%s>' ${foo=$*} ; echo
+printf '<%s>' "${foo}" ; echo
+
+unset foo
+IFS='
+'
+printf '<%s>' ${foo=$@} ; echo
+printf '<%s>' "$foo" ; echo
+
+IFS=?
+set a c
+foo=abcd
+
+echo ${foo#"$*"}
+echo "${foo#$*}"
+
+echo "${foo#'a?c'}"
+echo "${foo#a?c}"
+
+IFS=?
+set a c
+str=a$'\001'c
+pat=a$'\001'
+echo "${str#$pat}"
+
+set a b
+IFS=:
+
+a=$@
+recho "$a"
+
+recho ${foo=$*}
+recho "$foo"
+
+unset foo
+IFS='
+'
+recho ${foo=$@}
+recho "$foo"
+
+shift $#
+unset foo x
+
+set -- a b
+x=abc
+
+IFS=
+printf "<%s>\n" ${x#$*}
+printf "<%s>\n" "${x#$*}"
+
+x=abcd
+set a c
+IFS='?'
+printf "<%s>\n" ${x#$*}
+printf "<%s>\n" "${x#$*}"
diff --git a/tests/dollar-at-star5.sub b/tests/dollar-at-star5.sub
new file mode 100644
index 0000000..d07c61a
--- /dev/null
+++ b/tests/dollar-at-star5.sub
@@ -0,0 +1,66 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# testing various combinations of quoted and unquoted expansions of $@, and
+# whether they generate empty words after expansion
+
+n() { echo "$#"; }
+
+n "$@"
+n ${foo-"$@"}
+n "${foo-$@}"
+
+n ""$@
+n """$@"
+
+n $(true)$@
+n "$(true)$@"
+n "$(true)$@"
+n "$(true)""$@"
+
+n $xxx$@
+n "$xxx$@"
+n $xxx"$@"
+n "$xxx""$@"
+
+recho $xxx"$@"
+echo after 1
+
+recho "$xxx$@"
+echo after 2
+
+recho ${foo:-$xxx"$@"}
+echo after 3
+
+# this is where these things start to differ
+echo same as 1
+recho "${foo:-$xxx"$@"}"
+echo same as 2
+recho "${foo:-$xxx$@}"
+
+echo null fields
+recho ""$@
+recho """$@"
+
+echo null fields in rhs
+echo null string with unquoted '$@'
+recho ${foo:-""$@}
+echo null string with quoted '$@'
+recho ${foo:-"""$@"}
+
+echo assignment
+recho "${foo=$@}"
+echo variable
+recho "$foo"
+echo dollar-at
+recho "${@}"
diff --git a/tests/dollar-at-star6.sub b/tests/dollar-at-star6.sub
new file mode 100644
index 0000000..09353b8
--- /dev/null
+++ b/tests/dollar-at-star6.sub
@@ -0,0 +1,42 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+OIFS="$IFS"
+arr=(a b c)
+
+recho ${arr[@]@Q}
+recho "${arr[@]@Q}"
+
+IFS="'"
+recho ${arr[@]@Q}
+recho "${arr[@]@Q}"
+IFS="$OIFS"
+
+arr=("'a'" "'b'" "'c'")
+
+IFS="'"
+recho ${arr[@]}
+recho "${arr[@]}"
+IFS="$OIFS"
+
+IFS="'"
+a="'a'"
+recho $a
+recho "$a"
+IFS="$OIFS"
+
+set -- "'a'" "'b'" "'c'"
+
+IFS="'"
+recho "${@}"
+recho "$@"
diff --git a/tests/dollar-at-star7.sub b/tests/dollar-at-star7.sub
new file mode 100644
index 0000000..e4e63b7
--- /dev/null
+++ b/tests/dollar-at-star7.sub
@@ -0,0 +1,38 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS='' # testing with only empty IFS
+
+set -- this is a test
+
+printf '|%s|\n' ${1+"$@"}
+echo
+printf '|%s|\n' "${1+$@}"
+echo
+printf '|%s|\n' "$@"
+echo
+
+printf '|%s|\n' ${1-"$@"}
+printf '|%s|\n' "${1-$@}"
+
+echo
+: ${foo:="$@"}
+printf '|%s|\n' "$foo"
+
+unset foo
+: "${foo:=$@}"
+printf '|%s|\n' "$foo"
+
+unset foo
+printf '|%s|\n' ${foo-"$@"}
+printf '|%s|\n' "${foo-$@}"
diff --git a/tests/dollar-at-star8.sub b/tests/dollar-at-star8.sub
new file mode 100644
index 0000000..7e1b688
--- /dev/null
+++ b/tests/dollar-at-star8.sub
@@ -0,0 +1,14 @@
+function f {
+ typeset -a a
+ a=("$@")
+ typeset IFS=,
+ typeset a1="${a[@]} ${a[*]} $@ $* ${@} ${*}"
+ typeset a2=${a[@]}\ ${a[*]}\ $@\ $*\ ${@}\ ${*} a3 a4
+ a3="${a[@]} ${a[*]} $@ $* ${@} ${*}"
+ a4=${a[@]}\ ${a[*]}\ $@\ $*\ ${@}\ ${*}
+ unset -v IFS
+ printf '%s\n' "a1=$a1" "a2=$a2" "a3=$a3" "a4=$a4"
+}
+
+echo
+f a b c
diff --git a/tests/dollar-at-star9.sub b/tests/dollar-at-star9.sub
new file mode 100644
index 0000000..e5062f7
--- /dev/null
+++ b/tests/dollar-at-star9.sub
@@ -0,0 +1,278 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS=$' \t\n' # or any other IFS
+set -- ''
+recho ${v= "$*" }
+recho "$v"
+unset -v v
+
+IFS=''
+set -- '' ''
+recho ${v= "$*" }
+recho "$v"
+unset -v v
+
+IFS=$' \t\n' # or any other IFS
+unset -v v
+
+set -- ''
+recho ${v= "$@" }
+recho "$v"
+unset v
+recho ${v= $@ }
+recho "$v"
+unset v
+recho ${v= $@"" }
+recho "$v"
+unset v
+recho ${v= ${@} }
+recho "$v"
+unset v
+recho ${v= ${@}"" }
+recho "$v"
+unset v
+
+set -- '' ''
+recho ${v= $@ }
+recho "$v"
+unset v
+recho ${v= "$@" }
+recho "$v"
+unset v
+recho "${v= $@}"
+recho "$v"
+unset v
+recho ${v= "$@"}
+recho "$v"
+unset v
+
+IFS=
+
+set -- X
+X=X
+
+recho ${0+ "$@" }
+recho ${0+ $@ }
+recho ${0+ $* }
+
+recho ${0+ "$X" }
+recho ${0+ $X }
+recho ${0+ $X }
+
+recho ${0+ "$@" }
+recho "$Y"
+unset Y
+recho ${0+ $@ }
+recho "$Y"
+unset Y
+recho ${0+ $* }
+recho "$Y"
+unset Y
+
+recho ${Y:= "$X" }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+
+IFS=
+
+unset -v X Y
+
+set -- X Y
+X='X Y'
+
+recho ${0+ "$@" }
+recho ${0+ $@ }
+recho ${0+ $* }
+
+recho ${0+ "$X" }
+recho ${0+ $X }
+recho ${0+ $X }
+
+recho ${Y:= "$@" }
+recho "$Y"
+unset Y
+recho ${Y:= $@ }
+recho "$Y"
+unset Y
+recho ${Y:= $* }
+recho "$Y"
+unset Y
+
+recho ${Y:= "$X" }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+
+IFS=''
+set -- ' X '
+
+unset x y
+
+x=$*
+y=${*:1}
+
+recho "$x"
+recho "$y"
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${*:1}}
+
+set -- b a
+declare -A A=([b]= [a]=)
+
+x=$*
+y=${!A[*]}
+
+unset A
+
+recho "$x"
+recho "$y"
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${!A[*]}}
+
+unset x y
+
+recho ${x-$*}
+recho ${y-${!A[*]}} # this isn't right yet
+
+IFS=:
+set -- a b
+ind=*
+
+unset x y
+
+x=$*
+y=${!ind}
+
+recho "$x"
+recho "$y"
+
+unset x y
+
+recho ${x-$*}
+recho ${y-${!ind}} # this isn't right yet
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${!ind}}
+
+set -- ' X '
+IFS=$' \t\n'
+
+x=$*
+y=${!ind};
+
+recho "$x"
+recho "$y"
+
+IFS=''
+x=$*
+y=${!ind}
+
+recho "$x"
+recho "$y"
+
+IFS=:
+set -- a b
+ind=*
+
+unset x y
+
+recho ${x-$*}
+recho ${y-${!ind}} # this isn't right yet
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${!ind}}
+
+set -- ' X '
+IFS=$' \t\n'
+
+unset x y
+
+x=$*
+y=${!ind};
+
+recho "$x"
+recho "$y"
+
+IFS=''
+x=$*
+y=${!ind}
+
+recho "$x"
+recho "$y"
+
+IFS=''
+set -- $'\177'
+
+unset -v var
+
+recho "${*:1}"
+var=${*:1}
+recho "$var"
+
+unset var
+recho ${var=${*:1}}
+recho "$var"
+
+declare -a a=($'\177')
+
+unset var
+var=${a[*]:0}
+recho "$var"
+
+unset var
+recho ${var=${a[*]:0}}
+unset var
+
+set -- $'\177'
+ind='*'
+
+recho $*
+var=${!ind}
+recho "$var"
+
+unset var
+recho ${var=${!ind}}
+recho "$var"
+
+declare -A A=([0]=$'\177')
+
+unset var
+var=${A[*]:0}
+recho "$var"
+
+# this isn't really right yet
+unset var
+recho ${var=${A[*]:0}}
+recho "$var"