######################################################################## # # # This software is part of the ast package # # Copyright (c) 1982-2012 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # David Korn # # # ######################################################################## . "${SHTESTS_COMMON:-${0%/*}/_common}" bincat=$(whence -p cat) f=$tmp/here1 g=$tmp/here2 cat > $f < $g <<\! hello world ! cmp $f $g 2> /dev/null || err_exit "'hello world' quoted here doc not working" cat > $g <<- ! hello world ! cmp $f $g 2> /dev/null || err_exit "'hello world' tabbed here doc not working" cat > $g <<- \! hello world ! cmp $f $g 2> /dev/null || err_exit "'hello world' quoted tabbed here doc not working" x=hello cat > $g < /dev/null || err_exit "'$x world' here doc not working" cat > $g < /dev/null || err_exit "'$(print hello) world' here doc not working" cat > $f <<\!! !@#$%%^^&*()_+~"::~;'`<>?/.,{}[] !! if [[ $(<$f) != '!@#$%%^^&*()_+~"::~;'\''`<>?/.,{}[]' ]] then err_exit "'hello world' here doc not working" fi cat > $g <?/.,{}[] !! cmp $f $g 2> /dev/null || err_exit "unquoted here doc not working" exec 3< /dev/null <$g << : : : cmp /dev/null $g 2> /dev/null || err_exit "empty here doc not working" x=$(print $( cat < /dev/null || err_exit '100 empty here docs fails' { print 'builtin -d cat cat <<- EOF' for ((i=0; i < 100; i++)) do print XXXXXXXXXXXXXXXXXXXX done print ' XXX$(date)XXXX EOF' } > $f chmod +x "$f" $SHELL "$f" > /dev/null || err_exit "large here-doc with command substitution fails" x=$("$bincat" < /dev/null || err_exit 'here-doc cannot be terminated by )' if [[ $( IFS=:;cat <<-! $IFS$(print hi)$IFS !) != :hi: ]] then err_exit '$IFS unset by command substitution in here docs' fi if x=$($SHELL -c 'cat <<< "hello world"' 2> /dev/null) then [[ $x == 'hello world' ]] || err_exit '<<< documents not working' x=$($SHELL -c 'v="hello world";cat <<< $v' 2> /dev/null) [[ $x == 'hello world' ]] || err_exit '<<< documents with $x not working' x=$($SHELL -c 'v="hello world";cat <<< "$v"' 2> /dev/null) [[ $x == 'hello world' ]] || err_exit '<<< documents with $x not working' else err_exit '<<< syntax not supported' fi if [[ $(cat << EOF #testing #abc abc EOF) != $'#abc\nabc' ]] then err_exit 'comments not preserved in here-documents' fi cat > "$f" <<- '!!!!' builtin cat : << EOF $PWD xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx EOF command exec 3>&- 4>&- 5>&- 6>&- 7>&- 8>&- 9>&- x=abc cat << EOF $x EOF !!!! chmod 755 "$f" if [[ $($SHELL "$f") != abc ]] then err_exit 'here document descriptor was closed' fi cat > "$f" <<- '!!!!' exec 0<&- foobar() { "$bincat" <<- ! foobar ! } : << EOF $PWD xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx EOF print -r -- "$(foobar)" !!!! if [[ $(export bincat; "$SHELL" "$f") != foobar ]] then err_exit 'here document with stdin closed failed' fi printf $'cat <<# \\!!!\n\thello\n\t\tworld\n!!!' > $f [[ $($SHELL "$f") == $'hello\n\tworld' ]] || err_exit "<<# not working for quoted here documents" printf $'w=world;cat <<# !!!\n\thello\n\t\t$w\n!!!' > $f [[ $($SHELL "$f") == $'hello\n\tworld' ]] || err_exit "<<# not working for non-quoted here documents" [[ $( $SHELL <<- \++++ S=( typeset a ) function S.a.get { .sh.value=$__a } __a=1234 cat <<-EOF ${S.a} EOF ++++ ) == 1234 ]] 2> /dev/null || err_exit 'here document with get discipline failed' [[ $($SHELL -c 'g(){ print ok;}; cat <<- EOF ${ g;} EOF ' 2> /dev/null) == ok ]] || err_exit '${ command;} not working in heredoc' script=$f { for ((i=0; i < 406; i++)) do print ': 23456789012345678' done print : 123456789123 cat <<- \EOF eval "$( { cat ; } < $script chmod +x $script [[ $($SHELL $script) == hello ]] 2> /dev/null || err_exit 'heredoc embedded in command substitution fails at buffer boundary' got=$( cat << EOF \ abc EOF) [[ $got == abc ]] || err_exit 'line continuation at start of buffer not working' tmpfile1=$tmp/file1 tmpfile2=$tmp/file2 function gendata { typeset -RZ3 i for ((i=0; i < 500; i++)) do print -r -- "=====================This is line $i=============" done } cat > $tmpfile1 <<- +++ function foobar { cat << XXX $(gendata) XXX } cat > $tmpfile2 <<- EOF \$(foobar) $(gendata) EOF +++ chmod +x $tmpfile1 $SHELL $tmpfile1 set -- $(wc < $tmpfile2) (( $1 == 1000 )) || err_exit "heredoc $1 lines, should be 1000 lines" (( $2 == 4000 )) || err_exit "heredoc $2 words, should be 4000 words" # comment with here document loses line number count integer line=$((LINENO+5)) function tst { [[ $1 == $2 ]] || echo expected $1, got $2 } tst $line $LINENO <<"!" # this comment affects LINENO # 1 ! (( (line+=3) == LINENO )) || err_exit "line number=$LINENO should be $line" [[ $($SHELL -c 'wc -c <<< ""' 2> /dev/null) == *1 ]] || err_exit '<<< with empty string not working' mkdir $tmp/functions cat > $tmp/functions/t2 <<\!!! function t2 { cat < $f $SHELL $f > $g [[ $(grep meep $g | grep -v foobar) != '' ]] && err_exit 'here-doc losing $var expansions on boundaries in rare cases' print foo > $tmp/foofile x=$( $SHELL 2> /dev/null 'read <<< $(<'"$tmp"'/foofile) 2> /dev/null;print -r "$REPLY"') [[ $x == foo ]] || err_exit '<<< $(&1) || err_exit 'placing a command substitution and here-doc on the same line causes a syntax error' \ "(got $(printf %q "$got"))" # Another version of this regression from Red Hat bug 1036931 expect='gamma' actual=$("$SHELL" -c 'cat <&1) [[ $actual == "$expect" ]] || err_exit 'Syntax error on arith expansion on same line as here-doc' \ "(expected $(printf %q "$expect"), got $(printf %q "$actual"))" # A here-document in a command substitution should cause a syntax error if it isn't # completed inside of the command substitution. $SHELL -c '$(true << !) !' 2> /dev/null && err_exit "a here-doc that isn't completed before the closing ) in a command substitution doesn't cause an error" # ====== # Check that ${p}, where p is a special parameter, does not cause a syntax error in a here-document. # Bug for ${!} and ${$} reported at: https://github.com/ksh93/ksh/issues/127 for p in @ \* \# ! \$ - \? 0; do err=$(eval ': <&1) || err_exit "special parameter \${$p} throws syntax error in here-document (got \"$err\")" done # ====== exit $((Errors<125?Errors:125))