if [ $# != 1 ] ; then
    echo "Usage: ksh-prog Bugs ksh-prog" 1>&2
    exit 1
fi
THIS_KSH=$1
shift

echo 'The following tests are known to fail:
	39'

tbase=bug-t$$
tfile=/tmp/$tbase
sfile=/tmp/bug-s$$

#   1. Everywhere
#   	lex array code has problems....
#   		$ echo blah[
#   		missing ]
#   		$
#   	Different view of same bug:
#   		$ n=blah echo "hi[ $n ]"
#   		hi[ $n ]
#   		$
n=blah
x=$(echo hi[ $n ]=1)
if [ "$x" = 'hi[ $n ]=1' ] ; then
	echo 'Bug 1 present (echo "hi[ $n ] " prints hi[ $n ]).'
fi
unset n x

#
#   2. Everywhere
#   	When PATH is set before running a command, the new path is not used
#   	in doing the path search
#   		$ echo echo hi > /tmp/q ; chmod a+rx /tmp/q
#   		$ PATH=/tmp q
#   		q: not found
#   		$
#   	in comexec() the two lines
#   		while (*vp != NULL)
#   			(void) typeset(*vp++, xxx, 0);
#   	need to be moved out of the switch to before findcom() is called - I
#   	don't know what this will break.
cat > $tfile << 'EOF'
#!/bin/sh
echo hi
exit 0
EOF
chmod a+rx $tfile
PATH=/tmp $tbase > /dev/null 2>&1
if [ $? != 0 ] ; then
	echo "Bug 2 present: local assignments to PATH don't effect PATH search"
fi
rm -f $tfile

#
#   3. Sun OS 4.0.x (This seems to be a problem with sun's PENDIN not being done
#      properly)
#   	sleep 5^J ls^J ls^J ls		[only first ls runs]
#   	vi ... ZZ (while waiting type)	[some of the input gets eaten]
#      [not present in SunOS 4.1.x]
echo "  [No automatic test for bug 3 - interactive]"

#
#   4. (fixed)
#
echo "  [Don't know what bug 4 was]"

#
#   5. Everywhere
#   	File name completion (^X,*) does not mesh well with cd and
#   	symbolic links.  cd does path simplification wrt $PWD before
#   	doing the actual chdir(), while file name completion does
#   	not do the simplification. E.g., you are in directory A
#   	which has a symbolic link to directory B, you create a file
#   	called foobar and you then cd to the symlink to B, and type
#   		$ echo ../foo^X
#   	and the shell beeps at you.  Would be more consistent to
#   	do the completion after simplifing the `$PWD/..'.
echo "  [No automatic test for bug 5 - interactive]"

#
#   6. Everywhere
#   	Parsing of $(..) expressions is non-optimal.  It is
#   	impossible to have any parentheses inside the expression.
#   	I.e.,
#   		$ ksh -c 'echo $(echo \( )'
#   		no closing quote
#   		$ ksh -c 'echo $(echo "(" )'
#   		no closing quote
#   		$
#   	The solution is to hack the parsing clode in lex.c, the
#   	question is how to hack it: should any parentheses be
#   	escaped by a backslash, or should recursive parsing be done
#   	(so quotes could also be used to hide hem).  The former is
#   	easier, the later better...
cat > $tfile << 'EOF'
    echo $(echo \()
EOF
out=`$THIS_KSH $tfile 2>&1`
if [ "X$out" != 'X(' ] ; then
	echo 'Bug 6 present: can'\''t quote ( inside $(..) escapes'
fi
rm -f $tfile

#
#   7. (fixed)
#
echo "  [Don't know what bug 7 was]"

#
#   8. Everywhere - NOT A BUG - this is what at&t ksh does
#   	Strange typset -x behaviour in functions.  The following function
#   	does not set the environment variable BLAH outside the function:
#   		function blah
#   		{
#   			typeset -x BLAH=foobar
#   		}
#   	This function does work:
#   		function blah
#   		{ BLAH=foobar; export BLAH
#   		}
echo '  [Bug 8 was bogus]'

#
#   9. (fixed)  Fix is to make sure Volatile is not defined to nothing
#   	       (see defines in sh.h)
#   	Continue in a for loop does not work right:
#   		for i in a b c ; do
#   			if [ $i = b ] ; then
#   				continue
#   			fi
#   			echo $i
#   		done
#   	Prints a forever...
first=yes
for i in a b c ; do
	if [ $i = b ] ; then
		if [ $first = no ] ; then
			echo 'Bug 9 present: continue in for loop broken'
			break	# hope break isn't broken too :-)
		fi
		first=no
		continue
	fi
done

#
#   10. Everywhere
#   	The following:
#   		set -- `false`
#   		echo $?
#   	shoud not print 0. (according to /bin/sh, at&t ksh, and the
#   	getopt(1) man page - not according to POSIX)
set -- `false`
if [ $? != 1 ] ; then
	echo 'Bug 10 present: set exit code overrides exit code of command subst'
fi

#
#   11. Some places (sun4s but not mips)
#   	The following:
#   		x=/foo/bar/blah
#   		echo ${x##*/}
#   	should echo blah but on some machines echos /foo/bar/blah.
x=/foo/bar/blah
if [ ${x##*/} != blah ] ; then
	echo 'Bug 11 present: ${x##*/} doesn'\''t work'
fi
unset x

#
#   12. Everywhere:
#	Both of the following echos produce the same output under sh/ksh.att:
#   		#!/bin/sh
#   		x="foo	bar"
#   		echo "`echo \"$x\"`"
#   		echo "`echo "$x"`"
#	pdksh produces different output for the former (foo instead of foo\tbar)
x="foo	bar"
if [ "X`echo \"$x\"`" != "Xfoo	bar" ] ; then
	echo 'Bug 12 present: quotes inside `` sequences different from sh'
fi
unset x

#
#   13. Everywhere
#   	The following command hangs forever:
#   		$ (: ; cat /etc/termcap) | sleep 2
#   	This is because the shell forks a shell to run the (..) command
#   	and this shell has the pipe open.  When the sleep dies, the cat
#   	doesn't get a SIGPIPE 'cause a process (ie, the second shell)
#   	still has the pipe open.
trap 'echo "Bug 13 present: pipes not closed properly"; trap 2' 2
echo "  [If this hangs for more than a second, hit ^C]"
(: ; cat /etc/termcap) | sleep 1
trap 2
echo "  [relax, no bug 13]"


#
#   14. Everywhere
#   	The command
#   		$ (foobar) 2> /dev/null
#   	generates no output under /bin/sh, but pdksh produces the error
#   		foobar: not found
#   	Also, the command
#   		$ foobar 2> /dev/null
#   	generates an error under /bin/sh and pdksh, but at&t ksh produces
#   	no error (redirected to /dev/null).
cat > $tfile << 'EOF'
    (you/should/not/see/this/error/1) 2> /dev/null
    you/should/not/see/this/error/2 2> /dev/null
EOF
if $THIS_KSH $tfile 2>&1 | grep you/should > /dev/null; then
    echo "Bug 14 present: shell 'command not found' error not redirected"
fi
rm -f $tfile

#
#   15. Everywhere
#   	The command
#   		$ whence foobar
#   	generates a blank line under pdksh and sets the exit status to 0.
#   	at&t ksh generates no output and sets the exit status to 1.  Also,
#   	the command
#   		$ whence foobar cat
#   	generates no output under at&t ksh (pdksh generates a blank line
#   	and /bin/cat).
echo "  [Note that there are three bug 15 tests: 15a, 15b, 15c]"
cat > $tfile << 'EOF'
    whence does/not/exist > /dev/null
    echo $?
EOF
out=`$THIS_KSH $tfile 2> /dev/null`
if [ "$out" != 1 ] ; then
	echo 'Bug 15a present: exit status of whence wrong'
fi
rm -f $tfile
x=$(whence does/not/exist | wc -l)
case $x in
*0*) ;;
*)	echo 'Bug 15b present: whence produces blank lines'
esac
x=$(whence does/not/exist cat | wc -l)
case $x in
*2*) 	echo 'Bug 15c present: whence continues after error'
esac
unset x

#
#   16. Everywhere
#   	${var%%expr} seems to be broken in many places.  On the mips
#   	the commands
#   		$ read line < /etc/passwd
#   		$ echo $line
#   		root:0:1:...
#   		$ echo ${line%%:*}
#   		root
#   		$ echo $line
#   		root
#   		$
#   	change the value of line.  On sun4s & pas, the echo ${line%%:*} doesn't
#   	work.  Haven't checked elsewhere...
read x < /etc/passwd
y=$x
echo ${x%%:*} > /dev/null
if [ "$x" != "$y" ] ; then
	echo 'Bug 16 present: ${..%%..} trashes variables'
fi
unset x y

#
#   17. Everywhere
#   	The command
#   		. /foo/bar
#   	should set the exit status to non-zero (sh and at&t ksh do).
#	XXX doting a non existant file is a fatal error for a script
cat > $tfile << 'EOF'
    (. does/not/exist)
    echo $?
EOF
out=`$THIS_KSH $tfile 2> /dev/null`
if [ "$out" != 1 ] ; then
	echo 'Bug 17 present: exit status of . wrong'
fi
rm -f $tfile

#
#   18. Everywhere
#   	In vi mode ^X (and *) can dump core:
#   		$ ab[cd^XMemory fault (core dumped)
echo "  [No automatic test for bug 18 - interactive]"

#
#   19. Everywhere
#   	Both of the following echos should produce the same thing, but don't:
#   		$ x=foo/bar
#   		$ echo ${x%/*}
#   		foo
#   		$ echo "${x%/*}"
#   		foo/bar
x=foo/bar
if [ "${x%/*}" != foo ] ; then
	echo 'Bug 19 present: ${..%..} in double quotes broken'
fi
unset x

#
#   20. (same as 18)
#

#
#   21. Everywhere
#   	backslash does not work as expected in case labels:
#   	$ x='-x'
#   	$ case $x in
#   	-\?) echo hi
#   	esac
#   	hi
#   	$ x='-?'
#   	$ case $x in
#   	-\\?) echo hi
#   	esac
#   	hi
#   	$
case -x in
-\?)	echo 'Bug 21 present: backslashes do not work in case patterns'
esac

#
#   22. Quoting backquotes inside backquotes doesn't work:
#   	$ echo `echo hi \`echo there\` folks`
#       asks for more info.  sh and at&t ksh both echo
#   	hi there folks
cat > $tfile << 'EOF'
    echo `echo hi \`echo there\` folks`
EOF
out=`$THIS_KSH $tfile 2>&1`
if [ "$out" != 'hi there folks' ] ; then
	echo 'Bug 22 present: quoting backquotes inside backquotes broken'
fi
rm -f $tfile

#
#   23. )) is not treated `correctly':
#   	$ (echo hi ; (echo there ; echo folks))
#   	missing ((
#   	$
#       instead of (as sh and ksh.att)
#   	$ (echo hi ; (echo there ; echo folks))
#   	hi
#   	there
#   	folks
#   	$
cat > $tfile << 'EOF'
    ( : ; ( : ; echo hi))
EOF
out=`$THIS_KSH $tfile 2>&1`
if [ "$out" != 'hi' ] ; then
	echo 'Bug 23 present: )) always assumed to be end of (( )) expr'
fi
rm -f $tfile


#
#   24. strangeness with file name completion involving symlinks to nowhere
#   	$ mkdir foo foo/bar
#   	$ ln -s /stuff/junk foo/bar/xx
#   	$ echo foo/*/xx 
#	(beep)
#   	$
echo "  [No automatic test for bug 24 - interactive]"

#
#   25. Check reading stdin in a while loop.  The read should only read
#	a single line, not a whole stdio buffer; the cat should get
#	the rest.
#
(echo a; echo b) | while read x ; do
	    [ "$x" = b ] && echo 'Bug 25 present (read reads too much from pipe).'
	    cat > /dev/null
	done

#
#   26a. Check reading stdin in a while loop.  The read should read both
#	lines, not just the first.
#
cat > $tfile << 'EOF'
    a
    b
EOF
cat > $sfile << 'EOF'
    a=
    while [ "$a" != xxx ] ; do
	last=$x
	read x
	cat /dev/null | sed 's/x/y/'
	a=x$a
    done
    if [ "$last" != b ] ; then
	echo 'Bug 26 present (reading in a while loop broken).'
    fi
EOF
$THIS_KSH $sfile < $tfile
rm -f $tfile $sfile

#
#   26b Check reading stdin in a while loop.  The read should read both
#	lines, not just the first.  This differs from 26 in that lines
#	are placed against the margin.
#
cat > $tfile << 'EOF'
ab
cd
EOF
cat > $sfile << 'EOF'
    a=
    while [ "$a" != xxx ] ; do
	last=$x
	read x
	cat /dev/null | sed 's/x/y/'
	a=x$a
    done
    if [ "$last" != cd ] ; then
	echo "Bug 26b present (last line should be cd was $last.)"
    fi
EOF
$THIS_KSH $sfile < $tfile
rm -f $tfile $sfile

#
#   27. Everywhere
#   	The command
#   		. /does/not/exist
#	should cause a script to exit.
cat > $tfile << 'EOF'
    . does/not/exist
    echo hi
EOF
out=`$THIS_KSH $tfile 2> /dev/null`
if [ "$out" = hi ] ; then
	echo "Bug 27 present: .'ing a non-existant file doesn't kill script"
fi
rm -f $tfile


#
#   28. Everywhere
#   	variable assignements not detected well
#
cat > $tfile << 'EOF'
    a.x=1 echo hi
EOF
out=`$THIS_KSH $tfile 2> /dev/null`
if [ "$out" = hi ] ; then
	echo "Bug 28 present: strange chars allowed in variables"
fi
rm -f $tfile

#
#   29. Everywhere
#   	alias expansion different from real ksh
#
cat > $tfile << 'EOF'
    alias a='for ' b='i in'
    a b hi ; do echo $i ; done
EOF
out=`$THIS_KSH $tfile 2> /dev/null`
if [ "$out" != hi ] ; then
	echo "Bug 29 present: keyword in alias with trailing space doesn't work"
fi
rm -f $tfile


#
#   30. Everywhere
#   	strange characters allowed inside ${...}
#
cat > $tfile << 'EOF'
    echo ${a{b}}
EOF
out=`$THIS_KSH $tfile 2> /dev/null`
if [ $? = 0 ] ; then
	echo 'Bug 30 present: strange chars allowed inside ${..}'
fi
rm -f $tfile


#
#   31. Everywhere
#   	Does read handle partial lines correctly
#
cat > $tfile << 'EOF'
a A Aa
b B Bb
EOF
print -n 'c' >> $tfile
cat > $sfile << 'EOF'
    a=
    ret=
    while [ "$a" != xxx ] ; do
	read x y z
	ret=$?
	a=x$a
    done
    if [ "$x" != c ] ; then
	    echo 'Bug 31a present: read throws away partial lines'
    fi
    if [ "$ret" != 1 ] ; then
	    echo 'Bug 31b present: read does not return eof for partial lines'
    fi
EOF
$THIS_KSH $sfile < $tfile 2> /dev/null
rm -f $sfile $tfile


#
#   32. Everywhere
#   	Does read set variables to null at eof?
#
cat > $tfile << 'EOF'
a A Aa
b B Bb
EOF
cat > $sfile << 'EOF'
    a=
    while [ "$a" != xxx ] ; do
	read x y z
	a=x$a
    done
    if [ -n "$x$y$z" ] ; then
	echo "Bug 32 present: read does not set variables to null at eof"
    fi
EOF
$THIS_KSH $sfile < $tfile
rm -f $sfile $tfile


#
#   33. Everywhere
#   	Does umask print a leading 0 when umask is 3 digits?
#
cat > $sfile << 'EOF'
umask 222
umask
EOF
out=`$THIS_KSH $sfile`
if [ X"$out" = X222 ] ; then
	echo "Bug 33 present: umask doesn't always start with 0"
fi
rm -f $sfile 


#
#   34. Everywhere
#   	Does umask print a umask of 0 sanely?
#
cat > $sfile << 'EOF'
umask 0
umask
EOF
out=`$THIS_KSH $sfile`
if [ X"$out" = X00 ] ; then
	echo "Bug 34 present: umask prints 0 as \`$out'"
fi
rm -f $sfile 

#
#   35. Everywhere
#	  Tempory files used for here-docs in functions get trashed after
#	  the function is parsed (before it is executed)
#
cat > $sfile << 'EOF'
	f1() {
		cat <<- EOF
			F1
		EOF
		f2() {
			cat <<- EOF
				F2
			EOF
		}
	}
	f1
	f2
	unset -f f1
	f2
EOF
out=`$THIS_KSH $sfile 2>&1`
expected='F1
F2
F2'
if [ X"$out" != X"$expected" ] ; then
	echo "Bug 35 present: here documents in functions don't work"
fi
rm -f $sfile 

#
#   36. Everywhere (test from <sjg@void.zen.oz.au>)
#	  Command substitution breaks reading in while loop
#
cat > $sfile << 'EOF'
    (echo abcdef; echo; echo 123) | 
    while read line
    do
      # the following line breaks it
      c=`echo $line | wc -c`
      echo $c
    done
      
EOF
out=`$THIS_KSH $sfile 2>&1`
expect='7
1
4'
if [ X"$out" != X"$expect" ] ; then
	echo "Bug 36 present: reading broken by command substitution in while loops"
fi
rm -f $sfile 

#
#   37. Machines with broken times() (reported by <sjg@void.zen.oz.au>)
#	  time does not report correct real time
#
out=`$THIS_KSH -c 'time sleep 1' 2>&1 | awk '
	     /^[ 	]*0*\.0*s?[ 	][ 	]*real/ { print "bad" }
	     /^[	 ]*real[	 ][	 ]*0*\.0*s?([ 	]|$)/ { print "bad" }'`
if [ -n "$out" ] ; then
	echo "Bug 37 present: time does not report real-time correctly"
fi

#
#   38. set -e doesn't ignore exit codes for if/while/until/&&/||/!.
#
out=`$THIS_KSH -e -c '
		    if false; then echo hi ; fi
		    false || true
		    false && true
		    while false; do echo hi; done 
		    echo ok' 2>&1`
if [ X"$out" != Xok ] ; then
	echo "Bug 38 present: set -e exits when it shouldn't"
fi

#
#   39. set -e: errors in command substitutions aren't ignored
#
out=`$THIS_KSH -e -c 'if test X\`false; echo hi\` = Xhi; then echo ok ; fi' 2>&1`
if [ X"$out" != Xok ] ; then
	echo "Bug 39 present: set -e: errors in command substitutions not ignored"
fi
