1*b30d1939SAndy Fiddaman########################################################################
2*b30d1939SAndy Fiddaman#                                                                      #
3*b30d1939SAndy Fiddaman#               This software is part of the ast package               #
4*b30d1939SAndy Fiddaman#          Copyright (c) 1994-2011 AT&T Intellectual Property          #
5*b30d1939SAndy Fiddaman#                      and is licensed under the                       #
6*b30d1939SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
7*b30d1939SAndy Fiddaman#                    by AT&T Intellectual Property                     #
8*b30d1939SAndy Fiddaman#                                                                      #
9*b30d1939SAndy Fiddaman#                A copy of the License is available at                 #
10*b30d1939SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
11*b30d1939SAndy Fiddaman#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
12*b30d1939SAndy Fiddaman#                                                                      #
13*b30d1939SAndy Fiddaman#              Information and Software Systems Research               #
14*b30d1939SAndy Fiddaman#                            AT&T Research                             #
15*b30d1939SAndy Fiddaman#                           Florham Park NJ                            #
16*b30d1939SAndy Fiddaman#                                                                      #
17*b30d1939SAndy Fiddaman#                 Glenn Fowler <gsf@research.att.com>                  #
18*b30d1939SAndy Fiddaman#                                                                      #
19*b30d1939SAndy Fiddaman########################################################################
20*b30d1939SAndy Fiddaman: mktest - generate regress or shell regression test scripts
21*b30d1939SAndy Fiddaman
22*b30d1939SAndy Fiddamancommand=mktest
23*b30d1939SAndy Fiddamanstdin=8
24*b30d1939SAndy Fiddamanstdout=9
25*b30d1939SAndy FiddamanPREFIX=test
26*b30d1939SAndy FiddamanSTYLE=regress
27*b30d1939SAndy FiddamanWIDTH=80
28*b30d1939SAndy Fiddaman
29*b30d1939SAndy Fiddamaneval "exec $stdout>&1"
30*b30d1939SAndy Fiddaman
31*b30d1939SAndy Fiddamancase $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in
32*b30d1939SAndy Fiddaman0123)	ARGV0="-a $command"
33*b30d1939SAndy Fiddaman	USAGE=$'
34*b30d1939SAndy Fiddaman[-?
35*b30d1939SAndy Fiddaman@(#)$Id: mktest (AT&T Labs Research) 2010-08-11 $
36*b30d1939SAndy Fiddaman]
37*b30d1939SAndy Fiddaman'$USAGE_LICENSE$'
38*b30d1939SAndy Fiddaman[+NAME?mktest - generate a regression test scripts]
39*b30d1939SAndy Fiddaman[+DESCRIPTION?\bmktest\b generates regression test scripts from test
40*b30d1939SAndy Fiddaman    template commands in the \aunit\a.\brt\b file. The generated test
41*b30d1939SAndy Fiddaman    script writes temporary output to '$PREFIX$'\aunit\a.tmp and compares
42*b30d1939SAndy Fiddaman    it to the expected output in '$PREFIX$'\aunit\a.out. Run the test
43*b30d1939SAndy Fiddaman    script with the \b--accept\b option to (re)generate the
44*b30d1939SAndy Fiddaman    '$PREFIX$'\aunit\a.out.]
45*b30d1939SAndy Fiddaman[s:style?The script style:]:[style:='$STYLE$']
46*b30d1939SAndy Fiddaman    {
47*b30d1939SAndy Fiddaman        [+regress?\bregress\b(1) command input.]
48*b30d1939SAndy Fiddaman        [+shell?Standalone test shell script.]
49*b30d1939SAndy Fiddaman    }
50*b30d1939SAndy Fiddaman[w:width?Set the output format width to approximately
51*b30d1939SAndy Fiddaman    \awidth\a.]:[width:='$WIDTH$']
52*b30d1939SAndy Fiddaman
53*b30d1939SAndy Fiddamanunit.rt [ unit [ arg ... ] ]
54*b30d1939SAndy Fiddaman
55*b30d1939SAndy Fiddaman[+INPUT FILES?The regression test command file \aunit\a\b.rt\b is a
56*b30d1939SAndy Fiddaman    \bksh\b(1) script that makes calls to the following functions:]
57*b30d1939SAndy Fiddaman    {
58*b30d1939SAndy Fiddaman        [+DATA \afile\a [ - | [ options ]] data]]?Create input data
59*b30d1939SAndy Fiddaman            \afile\a that is empty (-) or contains \adata\a subject to
60*b30d1939SAndy Fiddaman            \bprint\b(1) \aoptions\a or that is a copy of the DATA command
61*b30d1939SAndy Fiddaman            standard input. Set \afile\a to \b-\b to name the standard
62*b30d1939SAndy Fiddaman            input.]
63*b30d1939SAndy Fiddaman        [+DIAGNOSTICS?Diagnostic messages of unspecified format are
64*b30d1939SAndy Fiddaman	    expected.]
65*b30d1939SAndy Fiddaman        [+DO \acommand\a [ \aarg\a ... ]]?Execute \acommand\a if the
66*b30d1939SAndy Fiddaman	    current test is active.]
67*b30d1939SAndy Fiddaman        [+EXEC [ \aarg\a ... ]]?Run the command under test with
68*b30d1939SAndy Fiddaman            optional arguments. If the standard input is not specified then
69*b30d1939SAndy Fiddaman            the standard input of the previous EXEC is used. The standard
70*b30d1939SAndy Fiddaman            input of the first EXEC in a TEST group is an empty regular
71*b30d1939SAndy Fiddaman            file.]
72*b30d1939SAndy Fiddaman        [+EXPORT \aname\a=\avalue\a ...?Export list for subsequent
73*b30d1939SAndy Fiddaman            commands in the TEST group or for all TEST groups if before
74*b30d1939SAndy Fiddaman	    the first TEST group.]
75*b30d1939SAndy Fiddaman        [+IGNORESPACE [ 0 | 1 ]
76*b30d1939SAndy Fiddaman            ?Ignore space differences when comparing expected output.]
77*b30d1939SAndy Fiddaman        [+KEEP \apattern\a ...?File match patterns of files to retain
78*b30d1939SAndy Fiddaman            between TEST groups.]
79*b30d1939SAndy Fiddaman        [+NOTE \acomment\a?\acomment\a is added to the current test
80*b30d1939SAndy Fiddaman            script.]
81*b30d1939SAndy Fiddaman        [+PROG \acommand\a [ \aarg\a ... ]]?Run \acommand\a with
82*b30d1939SAndy Fiddaman            optional arguments.]
83*b30d1939SAndy Fiddaman        [+TEST [ \anumber\a ]] [ \adescription\a ... ]]?Define a new
84*b30d1939SAndy Fiddaman            test group with optional \anumber\a and \adescripion\a.]
85*b30d1939SAndy Fiddaman        [+TWD [ \adir\a ... ]]?Set the temporary test dir to \adir\a.
86*b30d1939SAndy Fiddaman            The default is \aunit\a\b.tmp\b, where \aunit\a is the test
87*b30d1939SAndy Fiddaman            input file sans directory and suffix. If \adir\a matches \b/*\b
88*b30d1939SAndy Fiddaman            then it is the directory name; if \adir\a is non-null then the
89*b30d1939SAndy Fiddaman            prefix \b${TMPDIR:-/tmp}\b is added; otherwise if \adir\a is
90*b30d1939SAndy Fiddaman            omitted then
91*b30d1939SAndy Fiddaman            \b${TMPDIR:-/tmp}/tst-\b\aunit\a-$$-$RANDOM.\b\aunit\a is
92*b30d1939SAndy Fiddaman            used.]
93*b30d1939SAndy Fiddaman        [+UMASK [ \amask\a ]]?Run subsequent tests with \bumask\b(1)
94*b30d1939SAndy Fiddaman            \amask\a. If \amask\a is omitted then the original \bumask\b is
95*b30d1939SAndy Fiddaman            used.]
96*b30d1939SAndy Fiddaman        [+UNIT \acommand\a [ \aarg\a ... ]]?Define the command and
97*b30d1939SAndy Fiddaman            optional default arguments to be tested. \bUNIT\b explicitly
98*b30d1939SAndy Fiddaman            overrides the default command name derived from the test script
99*b30d1939SAndy Fiddaman            file name.]
100*b30d1939SAndy Fiddaman        [+WIDTH \awidth\a?Set the output format width to approximately
101*b30d1939SAndy Fiddaman            \awidth\a.]
102*b30d1939SAndy Fiddaman    }
103*b30d1939SAndy Fiddaman[+SEE ALSO?\bregress\b(1), \bksh\b(1)]
104*b30d1939SAndy Fiddaman'
105*b30d1939SAndy Fiddaman	;;
106*b30d1939SAndy Fiddaman*)	ARGV0=""
107*b30d1939SAndy Fiddaman	USAGE='s: unit.rt [ arg ... ]'
108*b30d1939SAndy Fiddaman	;;
109*b30d1939SAndy Fiddamanesac
110*b30d1939SAndy Fiddaman
111*b30d1939SAndy Fiddamantypeset ARG SCRIPT UNIT TEMP=${TMPDIR:-/tmp}/$command.$$.tmp WORK
112*b30d1939SAndy Fiddamantypeset IO INPUT INPUT_N OUTPUT OUTPUT_N ERROR ERROR_N KEEP
113*b30d1939SAndy Fiddamantypeset -C STATE
114*b30d1939SAndy Fiddamantypeset -A DATA STATE.RESET REMOVE FORMAT
115*b30d1939SAndy Fiddamaninteger KEEP_UNIT=0 SCRIPT_UNIT=0 TEST=0 CODE=0 EXIT=0 ACCEPT=0 DIAGNOSTICS=0 code
116*b30d1939SAndy Fiddaman
117*b30d1939SAndy Fiddamanwhile	getopts $ARGV0 "$USAGE" OPT
118*b30d1939SAndy Fiddamando	case $OPT in
119*b30d1939SAndy Fiddaman	s)	case $OPTARG in
120*b30d1939SAndy Fiddaman		regress|shell)
121*b30d1939SAndy Fiddaman			STYLE=$OPTARG
122*b30d1939SAndy Fiddaman			;;
123*b30d1939SAndy Fiddaman		*)	print -u2 -r -- $command: --style=$OPTARG: regress or shell expected
124*b30d1939SAndy Fiddaman			exit 1
125*b30d1939SAndy Fiddaman			;;
126*b30d1939SAndy Fiddaman		esac
127*b30d1939SAndy Fiddaman		;;
128*b30d1939SAndy Fiddaman	w)	WIDTH=$OPTARG
129*b30d1939SAndy Fiddaman		;;
130*b30d1939SAndy Fiddaman	*)	OPTIND=0
131*b30d1939SAndy Fiddaman		getopts $ARGV0 "$USAGE" OPT '-?'
132*b30d1939SAndy Fiddaman		exit 2
133*b30d1939SAndy Fiddaman		;;
134*b30d1939SAndy Fiddaman	esac
135*b30d1939SAndy Fiddamandone
136*b30d1939SAndy Fiddamanshift $OPTIND-1
137*b30d1939SAndy Fiddaman
138*b30d1939SAndy Fiddamantypeset SINGLE= quote='%${SINGLE}..${WIDTH}q'
139*b30d1939SAndy Fiddaman
140*b30d1939SAndy Fiddamanif	[[ $1 == - ]]
141*b30d1939SAndy Fiddamanthen	shift
142*b30d1939SAndy Fiddamanfi
143*b30d1939SAndy Fiddamanif	(( ! $# ))
144*b30d1939SAndy Fiddamanthen
145*b30d1939SAndy Fiddaman	print -u2 -r -- $command: test command script path expected
146*b30d1939SAndy Fiddaman	exit 1
147*b30d1939SAndy Fiddamanfi
148*b30d1939SAndy FiddamanSCRIPT=$1
149*b30d1939SAndy Fiddamanshift
150*b30d1939SAndy Fiddamanif	[[ ! -r $SCRIPT ]]
151*b30d1939SAndy Fiddamanthen	print -u2 -r -- $command: $SCRIPT: cannot read
152*b30d1939SAndy Fiddaman	exit 1
153*b30d1939SAndy Fiddamanfi
154*b30d1939SAndy Fiddaman(ulimit -c 0) >/dev/null 2>&1 && ulimit -c 0
155*b30d1939SAndy Fiddamanif	(( $# ))
156*b30d1939SAndy Fiddamanthen	set -A UNIT -- "$@"
157*b30d1939SAndy Fiddaman	KEEP_UNIT=1
158*b30d1939SAndy Fiddamanelse	ARG=${SCRIPT##*/}
159*b30d1939SAndy Fiddaman	set -A UNIT -- "${ARG%.*}"
160*b30d1939SAndy Fiddamanfi
161*b30d1939SAndy FiddamanWORK=${UNIT[0]}.tmp
162*b30d1939SAndy Fiddamanrm -rf $WORK
163*b30d1939SAndy Fiddamanmkdir $WORK || exit
164*b30d1939SAndy Fiddamanexport PATH=$PWD:$PATH
165*b30d1939SAndy Fiddaman
166*b30d1939SAndy Fiddamanfunction LINE
167*b30d1939SAndy Fiddaman{
168*b30d1939SAndy Fiddaman	if	[[ $STYLE == regress ]]
169*b30d1939SAndy Fiddaman	then	print -u$stdout
170*b30d1939SAndy Fiddaman	fi
171*b30d1939SAndy Fiddaman}
172*b30d1939SAndy Fiddaman
173*b30d1939SAndy Fiddamanfunction NOTE
174*b30d1939SAndy Fiddaman{
175*b30d1939SAndy Fiddaman	case $STYLE in
176*b30d1939SAndy Fiddaman	regress)LINE
177*b30d1939SAndy Fiddaman		print -u$stdout -r -- '#' "$@"
178*b30d1939SAndy Fiddaman		;;
179*b30d1939SAndy Fiddaman	shell)	print -u$stdout -r -f ": $QUOTE"$'\n' -- "$*"
180*b30d1939SAndy Fiddaman		;;
181*b30d1939SAndy Fiddaman	esac
182*b30d1939SAndy Fiddaman}
183*b30d1939SAndy Fiddaman
184*b30d1939SAndy Fiddamanfunction UNIT
185*b30d1939SAndy Fiddaman{
186*b30d1939SAndy Fiddaman	(( KEEP_UNIT )) || set -A UNIT -- "$@"
187*b30d1939SAndy Fiddaman	case $STYLE in
188*b30d1939SAndy Fiddaman	regress)LINE
189*b30d1939SAndy Fiddaman		print -u$stdout -r -f $'UNIT'
190*b30d1939SAndy Fiddaman		for ARG in "$@"
191*b30d1939SAndy Fiddaman		do	print -u$stdout -r -f " $QUOTE" -- "$ARG"
192*b30d1939SAndy Fiddaman		done
193*b30d1939SAndy Fiddaman		print -u$stdout
194*b30d1939SAndy Fiddaman		;;
195*b30d1939SAndy Fiddaman	shell)	print -u$stdout -r -f $'set x'
196*b30d1939SAndy Fiddaman		for ARG in "$@"
197*b30d1939SAndy Fiddaman		do	print -u$stdout -r -f " $QUOTE" -- "$ARG"
198*b30d1939SAndy Fiddaman		done
199*b30d1939SAndy Fiddaman		print -u$stdout
200*b30d1939SAndy Fiddaman		print -u$stdout shift
201*b30d1939SAndy Fiddaman		;;
202*b30d1939SAndy Fiddaman	esac
203*b30d1939SAndy Fiddaman}
204*b30d1939SAndy Fiddaman
205*b30d1939SAndy Fiddamanfunction TEST
206*b30d1939SAndy Fiddaman{
207*b30d1939SAndy Fiddaman	typeset i
208*b30d1939SAndy Fiddaman	typeset -A REM
209*b30d1939SAndy Fiddaman	if	(( ${#STATE.RESET[@]} ))
210*b30d1939SAndy Fiddaman	then	unset ${!STATE.RESET[@]}
211*b30d1939SAndy Fiddaman		case $STYLE in
212*b30d1939SAndy Fiddaman		shell)	print -u$stdout -r -- unset ${!STATE.RESET[@]} ;;
213*b30d1939SAndy Fiddaman		esac
214*b30d1939SAndy Fiddaman		unset STATE.RESET
215*b30d1939SAndy Fiddaman		typeset -A STATE.RESET
216*b30d1939SAndy Fiddaman	fi
217*b30d1939SAndy Fiddaman	if	(( ${#REMOVE[@]} ))
218*b30d1939SAndy Fiddaman	then	rm -f -- "${!REMOVE[@]}"
219*b30d1939SAndy Fiddaman		case $STYLE in
220*b30d1939SAndy Fiddaman		shell)	print -u$stdout -r -f $'rm -f'
221*b30d1939SAndy Fiddaman			for i in ${!REMOVE[@]}
222*b30d1939SAndy Fiddaman			do	print -u$stdout -r -f " $QUOTE" "$i"
223*b30d1939SAndy Fiddaman			done
224*b30d1939SAndy Fiddaman			print -u$stdout
225*b30d1939SAndy Fiddaman			;;
226*b30d1939SAndy Fiddaman		esac
227*b30d1939SAndy Fiddaman		for i in ${!REMOVE[@]}
228*b30d1939SAndy Fiddaman		do	unset REMOVE[$i]
229*b30d1939SAndy Fiddaman		done
230*b30d1939SAndy Fiddaman	fi
231*b30d1939SAndy Fiddaman	rm -rf $WORK/*
232*b30d1939SAndy Fiddaman	if	[[ $1 == +([0-9]) ]]
233*b30d1939SAndy Fiddaman	then	TEST=${1##0}
234*b30d1939SAndy Fiddaman		shift
235*b30d1939SAndy Fiddaman	else	((TEST++))
236*b30d1939SAndy Fiddaman	fi
237*b30d1939SAndy Fiddaman	LINE
238*b30d1939SAndy Fiddaman	case $STYLE in
239*b30d1939SAndy Fiddaman	regress)print -u$stdout -r -f "TEST %02d $QUOTE"$'\n' -- $TEST "$*"
240*b30d1939SAndy Fiddaman		;;
241*b30d1939SAndy Fiddaman	shell)	print -u$stdout -r -f ": TEST %02d $QUOTE"$'\n' -- $TEST "$*"
242*b30d1939SAndy Fiddaman		;;
243*b30d1939SAndy Fiddaman	esac
244*b30d1939SAndy Fiddaman	: > $TEMP.INPUT > $TEMP.in
245*b30d1939SAndy Fiddaman	INPUT=
246*b30d1939SAndy Fiddaman	INPUT_N=
247*b30d1939SAndy Fiddaman	OUTPUT=
248*b30d1939SAndy Fiddaman	OUTPUT_N=
249*b30d1939SAndy Fiddaman	ERROR=
250*b30d1939SAndy Fiddaman	ERROR_N=
251*b30d1939SAndy Fiddaman	UMASK=$UMASK_ORIG
252*b30d1939SAndy Fiddaman	UMASK_DONE=$UMASK
253*b30d1939SAndy Fiddaman	CODE=0
254*b30d1939SAndy Fiddaman}
255*b30d1939SAndy Fiddaman
256*b30d1939SAndy Fiddamanfunction TWD
257*b30d1939SAndy Fiddaman{
258*b30d1939SAndy Fiddaman	case $STYLE in
259*b30d1939SAndy Fiddaman	regress)LINE
260*b30d1939SAndy Fiddaman		print -u$stdout -r -f $'TWD'
261*b30d1939SAndy Fiddaman		for ARG in "$@"
262*b30d1939SAndy Fiddaman		do	print -u$stdout -r -f " $QUOTE" -- "$ARG"
263*b30d1939SAndy Fiddaman		done
264*b30d1939SAndy Fiddaman		print -u$stdout
265*b30d1939SAndy Fiddaman		;;
266*b30d1939SAndy Fiddaman	esac
267*b30d1939SAndy Fiddaman}
268*b30d1939SAndy Fiddaman
269*b30d1939SAndy Fiddamanfunction RUN
270*b30d1939SAndy Fiddaman{
271*b30d1939SAndy Fiddaman	typeset i n p op unit sep output=1 error=1 exitcode=1
272*b30d1939SAndy Fiddaman	op=$1
273*b30d1939SAndy Fiddaman	shift
274*b30d1939SAndy Fiddaman	while	:
275*b30d1939SAndy Fiddaman	do	case $1 in
276*b30d1939SAndy Fiddaman		++NOOUTPUT)	output= ;;
277*b30d1939SAndy Fiddaman		++NOERROR)	error= ;;
278*b30d1939SAndy Fiddaman		++NOEXIT)	exitcode= ;;
279*b30d1939SAndy Fiddaman		++*)		print -u2 -r -- $command: $0: $1: unknown option; exit 1 ;;
280*b30d1939SAndy Fiddaman		*)		break ;;
281*b30d1939SAndy Fiddaman		esac
282*b30d1939SAndy Fiddaman		shift
283*b30d1939SAndy Fiddaman	done
284*b30d1939SAndy Fiddaman	if	[[ $op == PROG ]]
285*b30d1939SAndy Fiddaman	then	unit=$1
286*b30d1939SAndy Fiddaman		shift
287*b30d1939SAndy Fiddaman	elif	(( ! ${#UNIT[@]} ))
288*b30d1939SAndy Fiddaman	then	print -u2 -r -- $command: $SCRIPT: UNIT statement or operand expected
289*b30d1939SAndy Fiddaman		exit 1
290*b30d1939SAndy Fiddaman	fi
291*b30d1939SAndy Fiddaman	LINE
292*b30d1939SAndy Fiddaman	case $STYLE in
293*b30d1939SAndy Fiddaman	regress)if	[[ $op == PROG ]]
294*b30d1939SAndy Fiddaman		then	print -u$stdout -r -f $'\t'"$op"$'\t'"$unit"
295*b30d1939SAndy Fiddaman			sep=$' '
296*b30d1939SAndy Fiddaman		else	print -u$stdout -r -f $'\t'"$op"
297*b30d1939SAndy Fiddaman			sep=$'\t'
298*b30d1939SAndy Fiddaman		fi
299*b30d1939SAndy Fiddaman		for ARG in "$@"
300*b30d1939SAndy Fiddaman		do	LC_CTYPE=C print -u$stdout -r -f "$sep$QUOTE" -- "$ARG"
301*b30d1939SAndy Fiddaman			sep=$' '
302*b30d1939SAndy Fiddaman		done
303*b30d1939SAndy Fiddaman		print -u$stdout
304*b30d1939SAndy Fiddaman		[[ ${DATA[-]} || /dev/fd/0 -ef /dev/fd/$stdin ]] || cat > $TEMP.in
305*b30d1939SAndy Fiddaman		IO=$(cat $TEMP.in; print :)
306*b30d1939SAndy Fiddaman		if	[[ $IO == ?*$'\n:' ]]
307*b30d1939SAndy Fiddaman		then	IO=${IO%??}
308*b30d1939SAndy Fiddaman			n=
309*b30d1939SAndy Fiddaman		else	IO=${IO%?}
310*b30d1939SAndy Fiddaman			n=-n
311*b30d1939SAndy Fiddaman		fi
312*b30d1939SAndy Fiddaman		{
313*b30d1939SAndy Fiddaman			[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK
314*b30d1939SAndy Fiddaman			cd $WORK
315*b30d1939SAndy Fiddaman			if	[[ $op == PROG ]]
316*b30d1939SAndy Fiddaman			then	"$unit" "$@"
317*b30d1939SAndy Fiddaman				code=$?
318*b30d1939SAndy Fiddaman			else	"${UNIT[@]}" "$@"
319*b30d1939SAndy Fiddaman				code=$?
320*b30d1939SAndy Fiddaman			fi
321*b30d1939SAndy Fiddaman			cd ..
322*b30d1939SAndy Fiddaman			[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
323*b30d1939SAndy Fiddaman		} < $TEMP.in > $TEMP.out 2> $TEMP.err
324*b30d1939SAndy Fiddaman		if	[[ $IO != "$INPUT" || $n != "$INPUT_N" ]]
325*b30d1939SAndy Fiddaman		then	INPUT=$IO
326*b30d1939SAndy Fiddaman			INPUT_N=$n
327*b30d1939SAndy Fiddaman			if	[[ ${FORMAT[-]} ]]
328*b30d1939SAndy Fiddaman			then	print -u$stdout -n -r -- $'\t\tINPUT'
329*b30d1939SAndy Fiddaman				print -u$stdout -r -f " $QUOTE" -- "${FORMAT[-]}"
330*b30d1939SAndy Fiddaman				print -u$stdout -r -f " $QUOTE" -- -
331*b30d1939SAndy Fiddaman				unset FORMAT[-]
332*b30d1939SAndy Fiddaman			else	print -u$stdout -n -r -- $'\t\tINPUT' $n -
333*b30d1939SAndy Fiddaman				[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
334*b30d1939SAndy Fiddaman			fi
335*b30d1939SAndy Fiddaman			print -u$stdout
336*b30d1939SAndy Fiddaman			unset DATA[-]
337*b30d1939SAndy Fiddaman		fi
338*b30d1939SAndy Fiddaman		for i in ${!DATA[@]}
339*b30d1939SAndy Fiddaman		do	if	[[ ${FORMAT[$i]} ]]
340*b30d1939SAndy Fiddaman			then	print -u$stdout -n -r -- $'\t\tINPUT'
341*b30d1939SAndy Fiddaman				print -u$stdout -r -f " $QUOTE" -- "${FORMAT[$i]}"
342*b30d1939SAndy Fiddaman				print -u$stdout -r -f " $QUOTE" -- "$i"
343*b30d1939SAndy Fiddaman				unset FORMAT[$i]
344*b30d1939SAndy Fiddaman			else	case $i in
345*b30d1939SAndy Fiddaman				-)	p=$TEMP.in ;;
346*b30d1939SAndy Fiddaman				*)	p=$WORK/$i ;;
347*b30d1939SAndy Fiddaman				esac
348*b30d1939SAndy Fiddaman				IO=$(cat $p; print :)
349*b30d1939SAndy Fiddaman				if	[[ $IO == ?*$'\n:' ]]
350*b30d1939SAndy Fiddaman				then	IO=${IO%??}
351*b30d1939SAndy Fiddaman					n=
352*b30d1939SAndy Fiddaman				else	IO=${IO%?}
353*b30d1939SAndy Fiddaman					n=-n
354*b30d1939SAndy Fiddaman				fi
355*b30d1939SAndy Fiddaman				print -u$stdout -n -r -- $'\t\tINPUT' $n
356*b30d1939SAndy Fiddaman				print -u$stdout -r -f " $QUOTE" -- "$i"
357*b30d1939SAndy Fiddaman				[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
358*b30d1939SAndy Fiddaman			fi
359*b30d1939SAndy Fiddaman			print -u$stdout
360*b30d1939SAndy Fiddaman			unset DATA[$i]
361*b30d1939SAndy Fiddaman		done
362*b30d1939SAndy Fiddaman		IO=$(cat $TEMP.out; print :)
363*b30d1939SAndy Fiddaman		if	[[ $IO == ?*$'\n:' ]]
364*b30d1939SAndy Fiddaman		then	IO=${IO%??}
365*b30d1939SAndy Fiddaman			n=
366*b30d1939SAndy Fiddaman		else	IO=${IO%?}
367*b30d1939SAndy Fiddaman			n=-n
368*b30d1939SAndy Fiddaman		fi
369*b30d1939SAndy Fiddaman		if	[[ $IO != "$OUTPUT" || $n != "$OUTPUT_N" ]]
370*b30d1939SAndy Fiddaman		then	OUTPUT=$IO
371*b30d1939SAndy Fiddaman			OUTPUT_N=$n
372*b30d1939SAndy Fiddaman			if	[[ $output ]]
373*b30d1939SAndy Fiddaman			then	if	[[ ! -s $TEMP.out ]]
374*b30d1939SAndy Fiddaman				then	print -u$stdout -n -r -- $'\t\tOUTPUT' -
375*b30d1939SAndy Fiddaman				elif	cmp -s $TEMP.in $TEMP.out
376*b30d1939SAndy Fiddaman				then	OUTPUT=not-$OUTPUT
377*b30d1939SAndy Fiddaman					print -u$stdout -n -r -- $'\t\tSAME OUTPUT INPUT'
378*b30d1939SAndy Fiddaman				else	print -u$stdout -n -r -- $'\t\tOUTPUT' $n -
379*b30d1939SAndy Fiddaman					[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
380*b30d1939SAndy Fiddaman				fi
381*b30d1939SAndy Fiddaman				print -u$stdout
382*b30d1939SAndy Fiddaman			fi
383*b30d1939SAndy Fiddaman		fi
384*b30d1939SAndy Fiddaman		IO=$(cat $TEMP.err; print :)
385*b30d1939SAndy Fiddaman		IO=${IO//$command\[*([0-9])\]:\ .\[*([0-9])\]:\ @(EXEC|PROG)\[*([0-9])\]:\ /}
386*b30d1939SAndy Fiddaman		if	[[ $IO == ?*$'\n:' ]]
387*b30d1939SAndy Fiddaman		then	IO=${IO%??}
388*b30d1939SAndy Fiddaman			n=
389*b30d1939SAndy Fiddaman		else	IO=${IO%?}
390*b30d1939SAndy Fiddaman			n=-n
391*b30d1939SAndy Fiddaman		fi
392*b30d1939SAndy Fiddaman		if	[[ $IO != "$ERROR" || $n != "$ERROR_N" ]]
393*b30d1939SAndy Fiddaman		then	ERROR=$IO
394*b30d1939SAndy Fiddaman			ERROR_N=$n
395*b30d1939SAndy Fiddaman			if	[[ $error ]]
396*b30d1939SAndy Fiddaman			then	print -u$stdout -n -r -- $'\t\tERROR' $n -
397*b30d1939SAndy Fiddaman				[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
398*b30d1939SAndy Fiddaman				print -u$stdout
399*b30d1939SAndy Fiddaman			fi
400*b30d1939SAndy Fiddaman		fi
401*b30d1939SAndy Fiddaman		case $output:$error in
402*b30d1939SAndy Fiddaman		:)	OUTPUT=
403*b30d1939SAndy Fiddaman			OUTPUT_N=
404*b30d1939SAndy Fiddaman			ERROR=
405*b30d1939SAndy Fiddaman			ERROR_N=
406*b30d1939SAndy Fiddaman			print -u$stdout -r -- $'\t\tIGNORE OUTPUT ERROR'
407*b30d1939SAndy Fiddaman			;;
408*b30d1939SAndy Fiddaman		:1)	OUTPUT=
409*b30d1939SAndy Fiddaman			OUTPUT_N=
410*b30d1939SAndy Fiddaman			print -u$stdout -r -- $'\t\tIGNORE OUTPUT'
411*b30d1939SAndy Fiddaman			;;
412*b30d1939SAndy Fiddaman		1:)	ERROR=
413*b30d1939SAndy Fiddaman			ERROR_N=
414*b30d1939SAndy Fiddaman			print -u$stdout -r -- $'\t\tIGNORE ERROR'
415*b30d1939SAndy Fiddaman			;;
416*b30d1939SAndy Fiddaman		esac
417*b30d1939SAndy Fiddaman		if	[[ $UMASK_DONE != $UMASK ]]
418*b30d1939SAndy Fiddaman		then	UMASK_DONE=$UMASK
419*b30d1939SAndy Fiddaman			print -u$stdout -r -f $'\t\tUMASK %s\n' $UMASK
420*b30d1939SAndy Fiddaman		fi
421*b30d1939SAndy Fiddaman		if	(( code != CODE ))
422*b30d1939SAndy Fiddaman		then	(( CODE=code ))
423*b30d1939SAndy Fiddaman			if	[[ $exitcode ]]
424*b30d1939SAndy Fiddaman			then	print -u$stdout -r -f $'\t\tEXIT %d\n' $CODE
425*b30d1939SAndy Fiddaman			fi
426*b30d1939SAndy Fiddaman		fi
427*b30d1939SAndy Fiddaman		;;
428*b30d1939SAndy Fiddaman	shell)	[[ $UMASK != $UMASK_ORIG ]] && print -u$stdout -r -f "{ umask $UMASK; "
429*b30d1939SAndy Fiddaman		if	[[ $op == PROG ]]
430*b30d1939SAndy Fiddaman		then	print -u$stdout -r -f $'"'"$unit"$'"'
431*b30d1939SAndy Fiddaman		else	print -u$stdout -r -f $'"$@"'
432*b30d1939SAndy Fiddaman		fi
433*b30d1939SAndy Fiddaman		for ARG in "$@"
434*b30d1939SAndy Fiddaman		do	print -u$stdout -r -f " $QUOTE" -- "$ARG"
435*b30d1939SAndy Fiddaman		done
436*b30d1939SAndy Fiddaman		[[ $UMASK != $UMASK_ORIG ]] && print -u$stdout -r -f "umask $UMASK_ORIG; } "
437*b30d1939SAndy Fiddaman		if	[[ ! $output ]]
438*b30d1939SAndy Fiddaman		then	print -u$stdout -r -f " >/dev/null"
439*b30d1939SAndy Fiddaman		fi
440*b30d1939SAndy Fiddaman		if	[[ ! $error ]]
441*b30d1939SAndy Fiddaman		then	if	[[ ! $output ]]
442*b30d1939SAndy Fiddaman			then	print -u$stdout -r -f " 2>&1"
443*b30d1939SAndy Fiddaman			else	print -u$stdout -r -f " 2>/dev/null"
444*b30d1939SAndy Fiddaman			fi
445*b30d1939SAndy Fiddaman		fi
446*b30d1939SAndy Fiddaman		IO=$(cat)
447*b30d1939SAndy Fiddaman		if	[[ $IO ]]
448*b30d1939SAndy Fiddaman		then	print -u$stdout -r -- "<<'!TEST-INPUT!'"
449*b30d1939SAndy Fiddaman			print -u$stdout -r -- "$IO"
450*b30d1939SAndy Fiddaman			print -u$stdout -r -- !TEST-INPUT!
451*b30d1939SAndy Fiddaman		else	print -u$stdout
452*b30d1939SAndy Fiddaman		fi
453*b30d1939SAndy Fiddaman		if	[[ $exitcode ]]
454*b30d1939SAndy Fiddaman		then	print -u$stdout -r -- $'CODE=$?\ncase $CODE in\n0) ;;\n*) echo exit status $CODE ;;\nesac'
455*b30d1939SAndy Fiddaman		fi
456*b30d1939SAndy Fiddaman		;;
457*b30d1939SAndy Fiddaman	esac
458*b30d1939SAndy Fiddaman}
459*b30d1939SAndy Fiddaman
460*b30d1939SAndy Fiddamanfunction DO
461*b30d1939SAndy Fiddaman{
462*b30d1939SAndy Fiddaman	LINE
463*b30d1939SAndy Fiddaman	print -r $'\t'DO "$@"
464*b30d1939SAndy Fiddaman}
465*b30d1939SAndy Fiddaman
466*b30d1939SAndy Fiddamanfunction EXEC
467*b30d1939SAndy Fiddaman{
468*b30d1939SAndy Fiddaman	RUN EXEC "$@"
469*b30d1939SAndy Fiddaman}
470*b30d1939SAndy Fiddaman
471*b30d1939SAndy Fiddamanfunction DATA
472*b30d1939SAndy Fiddaman{
473*b30d1939SAndy Fiddaman	typeset f p o
474*b30d1939SAndy Fiddaman	f=$1
475*b30d1939SAndy Fiddaman	shift
476*b30d1939SAndy Fiddaman	case $f in
477*b30d1939SAndy Fiddaman	-)	p=$TEMP.in ;;
478*b30d1939SAndy Fiddaman	*)	p=$WORK/$f ;;
479*b30d1939SAndy Fiddaman	esac
480*b30d1939SAndy Fiddaman	case $1 in
481*b30d1939SAndy Fiddaman	'')	cat ;;
482*b30d1939SAndy Fiddaman	-)	;;
483*b30d1939SAndy Fiddaman	*)	print -r "$@" ;;
484*b30d1939SAndy Fiddaman	esac > $p
485*b30d1939SAndy Fiddaman	DATA[$f]=1
486*b30d1939SAndy Fiddaman	if	(( $# == 1 )) && [[ $1 == -?* ]]
487*b30d1939SAndy Fiddaman	then	FORMAT[$f]=$1
488*b30d1939SAndy Fiddaman	else	FORMAT[$f]=
489*b30d1939SAndy Fiddaman	fi
490*b30d1939SAndy Fiddaman	if	[[ $f != $KEEP ]]
491*b30d1939SAndy Fiddaman	then	REMOVE[$f]=1
492*b30d1939SAndy Fiddaman	fi
493*b30d1939SAndy Fiddaman	if	[[ $STYLE == shell ]]
494*b30d1939SAndy Fiddaman	then	{
495*b30d1939SAndy Fiddaman		print -r -f "cat > $QUOTE <<'!TEST-INPUT!'"$'\n' -- "$f"
496*b30d1939SAndy Fiddaman		cat "$p"
497*b30d1939SAndy Fiddaman		print -r -- !TEST-INPUT!
498*b30d1939SAndy Fiddaman		} >&$stdout
499*b30d1939SAndy Fiddaman	fi
500*b30d1939SAndy Fiddaman}
501*b30d1939SAndy Fiddaman
502*b30d1939SAndy Fiddamanfunction KEEP
503*b30d1939SAndy Fiddaman{
504*b30d1939SAndy Fiddaman	typeset p
505*b30d1939SAndy Fiddaman	for p
506*b30d1939SAndy Fiddaman	do	if	[[ $KEEP ]]
507*b30d1939SAndy Fiddaman		then	KEEP=$KEEP'|'
508*b30d1939SAndy Fiddaman		fi
509*b30d1939SAndy Fiddaman		KEEP=$KEEP$p
510*b30d1939SAndy Fiddaman	done
511*b30d1939SAndy Fiddaman}
512*b30d1939SAndy Fiddaman
513*b30d1939SAndy Fiddamanfunction DIAGNOSTICS
514*b30d1939SAndy Fiddaman{
515*b30d1939SAndy Fiddaman	LINE
516*b30d1939SAndy Fiddaman	case $STYLE in
517*b30d1939SAndy Fiddaman	regress)	print -u$stdout -r $'DIAGNOSTICS' ;;
518*b30d1939SAndy Fiddaman	shell)		DIAGNOSTICS=1 ;;
519*b30d1939SAndy Fiddaman	esac
520*b30d1939SAndy Fiddaman}
521*b30d1939SAndy Fiddaman
522*b30d1939SAndy Fiddamanfunction EXPORT
523*b30d1939SAndy Fiddaman{
524*b30d1939SAndy Fiddaman	typeset x n v
525*b30d1939SAndy Fiddaman	LINE
526*b30d1939SAndy Fiddaman	case $STYLE in
527*b30d1939SAndy Fiddaman	regress)	print -u$stdout -r -f $'EXPORT' ;;
528*b30d1939SAndy Fiddaman	shell)		print -u$stdout -r -f $'export' ;;
529*b30d1939SAndy Fiddaman	esac
530*b30d1939SAndy Fiddaman	for x
531*b30d1939SAndy Fiddaman	do	n=${x%%=*}
532*b30d1939SAndy Fiddaman		v=${x#*=}
533*b30d1939SAndy Fiddaman		export "$x"
534*b30d1939SAndy Fiddaman		print -u$stdout -r -f " %s=$QUOTE" "$n" "$v"
535*b30d1939SAndy Fiddaman		(( TEST )) && STATE.RESET["$n"]=1
536*b30d1939SAndy Fiddaman	done
537*b30d1939SAndy Fiddaman	print -u$stdout
538*b30d1939SAndy Fiddaman}
539*b30d1939SAndy Fiddaman
540*b30d1939SAndy Fiddamanfunction PROG
541*b30d1939SAndy Fiddaman{
542*b30d1939SAndy Fiddaman	RUN PROG "$@"
543*b30d1939SAndy Fiddaman}
544*b30d1939SAndy Fiddaman
545*b30d1939SAndy Fiddamanfunction WIDTH
546*b30d1939SAndy Fiddaman{
547*b30d1939SAndy Fiddaman	WIDTH=${1:-80}
548*b30d1939SAndy Fiddaman	eval QUOTE='"'$quote'"'
549*b30d1939SAndy Fiddaman}
550*b30d1939SAndy Fiddaman
551*b30d1939SAndy Fiddamanfunction IGNORESPACE
552*b30d1939SAndy Fiddaman{
553*b30d1939SAndy Fiddaman	IGNORESPACE=-b
554*b30d1939SAndy Fiddaman	LINE
555*b30d1939SAndy Fiddaman	print -u$stdout -r IGNORESPACE
556*b30d1939SAndy Fiddaman}
557*b30d1939SAndy Fiddaman
558*b30d1939SAndy Fiddamanfunction UMASK # [ mask ]
559*b30d1939SAndy Fiddaman{
560*b30d1939SAndy Fiddaman	[[ $UMASK_ORIG ]] || UMASK_ORIG=$(umask)
561*b30d1939SAndy Fiddaman	UMASK=$1
562*b30d1939SAndy Fiddaman	[[ $UMASK ]] || UMASK=$UMASK_ORIG
563*b30d1939SAndy Fiddaman}
564*b30d1939SAndy Fiddaman
565*b30d1939SAndy Fiddamantrap 'CODE=$?; rm -rf $TEMP.* $WORK; exit $CODE' 0 1 2 3 15
566*b30d1939SAndy Fiddaman
567*b30d1939SAndy Fiddamantypeset IGNORESPACE UMASK UMASK_ORIG UMASK_DONE
568*b30d1939SAndy FiddamanUMASK_ORIG=$(umask)
569*b30d1939SAndy FiddamanIFS=$IFS$'\n'
570*b30d1939SAndy Fiddaman
571*b30d1939SAndy Fiddamanprint -u$stdout -r "# : : generated from $SCRIPT by $command : : #"
572*b30d1939SAndy Fiddamancase $STYLE in
573*b30d1939SAndy Fiddamanshell)	cat <<!
574*b30d1939SAndy FiddamanACCEPT=0
575*b30d1939SAndy Fiddamanwhile	:
576*b30d1939SAndy Fiddamando	case \$1 in
577*b30d1939SAndy Fiddaman	-a|--accept)
578*b30d1939SAndy Fiddaman		ACCEPT=1
579*b30d1939SAndy Fiddaman		;;
580*b30d1939SAndy Fiddaman	--help|--man)
581*b30d1939SAndy Fiddaman		cat 1>&2 <<!!
582*b30d1939SAndy FiddamanUsage: \\\$SHELL $PREFIX${UNIT[0]}.sh [ --accept ] [ unit ... ]
583*b30d1939SAndy Fiddaman
584*b30d1939SAndy Fiddaman${UNIT[0]} regression test script.  Run this script to generate new
585*b30d1939SAndy Fiddamanresults in $PREFIX${UNIT[0]}.tmp and compare with expected results in
586*b30d1939SAndy Fiddaman$PREFIX${UNIT[0]}.out.  The --accept option generates $PREFIX${UNIT[0]}.tmp
587*b30d1939SAndy Fiddamanand moves it to $PREFIX${UNIT[0]}.out.
588*b30d1939SAndy Fiddaman!!
589*b30d1939SAndy Fiddaman		exit 2
590*b30d1939SAndy Fiddaman		;;
591*b30d1939SAndy Fiddaman	-*)	echo \$0: \$1: invalid option >&2
592*b30d1939SAndy Fiddaman		exit 1
593*b30d1939SAndy Fiddaman		;;
594*b30d1939SAndy Fiddaman	*)	break
595*b30d1939SAndy Fiddaman		;;
596*b30d1939SAndy Fiddaman	esac
597*b30d1939SAndy Fiddaman	shift
598*b30d1939SAndy Fiddamandone
599*b30d1939SAndy Fiddamanexport COLUMNS=80
600*b30d1939SAndy Fiddaman{
601*b30d1939SAndy Fiddaman!
602*b30d1939SAndy Fiddaman	;;
603*b30d1939SAndy Fiddamanesac
604*b30d1939SAndy Fiddaman
605*b30d1939SAndy Fiddamanexport COLUMNS=80
606*b30d1939SAndy Fiddaman
607*b30d1939SAndy Fiddamancase $STYLE in
608*b30d1939SAndy Fiddamanshell)	SINGLE='#'
609*b30d1939SAndy Fiddaman	eval QUOTE='"'$quote'"'
610*b30d1939SAndy Fiddaman	. $SCRIPT < /dev/null | sed -e $'s,\\\\n,\n,g' -e $'s,\\\\t,\t,g' -e $'s,\\$\',\',g'
611*b30d1939SAndy Fiddaman	;;
612*b30d1939SAndy Fiddaman*)	eval QUOTE='"'$quote'"'
613*b30d1939SAndy Fiddaman	: > $TEMP.INPUT > $TEMP.in
614*b30d1939SAndy Fiddaman	eval "exec $stdin<$TEMP.INPUT"
615*b30d1939SAndy Fiddaman	. $SCRIPT <&$stdin
616*b30d1939SAndy Fiddaman	;;
617*b30d1939SAndy Fiddamanesac
618*b30d1939SAndy Fiddaman
619*b30d1939SAndy Fiddamancase $STYLE in
620*b30d1939SAndy Fiddamanshell)	cat <<!
621*b30d1939SAndy Fiddaman} > $PREFIX${UNIT[0]}.tmp 2>&1 < /dev/null
622*b30d1939SAndy Fiddamancase \$ACCEPT in
623*b30d1939SAndy Fiddaman0)	if	grep '
624*b30d1939SAndy Fiddaman$' $PREFIX${UNIT[0]}.tmp >/dev/null
625*b30d1939SAndy Fiddaman	then	mv $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.junk
626*b30d1939SAndy Fiddaman		sed 's/
627*b30d1939SAndy Fiddaman$//' < $PREFIX${UNIT[0]}.junk > $PREFIX${UNIT[0]}.tmp
628*b30d1939SAndy Fiddaman		rm -f $PREFIX${UNIT[0]}.junk
629*b30d1939SAndy Fiddaman	fi
630*b30d1939SAndy Fiddaman	if	cmp -s $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out
631*b30d1939SAndy Fiddaman	then	echo ${UNIT[0]} tests PASSED
632*b30d1939SAndy Fiddaman		rm -f $PREFIX${UNIT[0]}.tmp
633*b30d1939SAndy Fiddaman	else	echo ${UNIT[0]} tests FAILED
634*b30d1939SAndy Fiddaman		diff $IGNORESPACE $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out
635*b30d1939SAndy Fiddaman	fi
636*b30d1939SAndy Fiddaman	;;
637*b30d1939SAndy Fiddaman
638*b30d1939SAndy Fiddaman*)	mv $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out
639*b30d1939SAndy Fiddaman	;;
640*b30d1939SAndy Fiddamanesac
641*b30d1939SAndy Fiddaman!
642	;;
643esac
644