######################################################################## # # # This software is part of the ast package # # Copyright (c) 1982-2012 AT&T Intellectual Property # # 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 # # # ######################################################################## function err_exit { print -u2 -n "\t" print -u2 -r ${Command}[$1]: "${@:2}" let Errors+=1 } alias err_exit='err_exit $LINENO' Command=${0##*/} integer Errors=0 tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } trap "cd /; rm -rf $tmp" EXIT 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=$(/bin/cat < /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 descritor was closed' fi cat > "$f" <<- '!!!!' exec 0<&- foobar() { /bin/cat <<- ! 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 [[ $($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 embeded 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 looses 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 loosing $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 '<<< $(