1*b30d1939SAndy Fiddaman########################################################################
2*b30d1939SAndy Fiddaman#                                                                      #
3*b30d1939SAndy Fiddaman#               This software is part of the ast package               #
4*b30d1939SAndy Fiddaman#          Copyright (c) 1994-2012 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: regress - run regression tests in command.tst
21*b30d1939SAndy Fiddaman
22*b30d1939SAndy Fiddamancommand=regress
23*b30d1939SAndy Fiddamancase $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in
24*b30d1939SAndy Fiddaman0123)	USAGE=$'
25*b30d1939SAndy Fiddaman[-?
26*b30d1939SAndy Fiddaman@(#)$Id: regress (AT&T Research) 2012-02-02 $
27*b30d1939SAndy Fiddaman]
28*b30d1939SAndy Fiddaman'$USAGE_LICENSE$'
29*b30d1939SAndy Fiddaman[+NAME?regress - run regression tests]
30*b30d1939SAndy Fiddaman[+DESCRIPTION?\bregress\b runs the tests in \aunit\a, or
31*b30d1939SAndy Fiddaman    \aunit\a\b.tst\b if \aunit\a does not exist. If \acommand\a is omitted
32*b30d1939SAndy Fiddaman    then it is assumed to be the base name of \aunit\a. All testing is done
33*b30d1939SAndy Fiddaman    in the temporary directory \aunit\a\b.tmp\b.]
34*b30d1939SAndy Fiddaman[+?Default test output lists the \anumber\a and \adescription\a for
35*b30d1939SAndy Fiddaman    each active \bTEST\b group and the \anumber\a:\aline\a for each
36*b30d1939SAndy Fiddaman    individual \bEXEC\b test. Each test that fails results in a diagnostic
37*b30d1939SAndy Fiddaman    that contains the word \bFAILED\b; no other diagnostics contain this
38*b30d1939SAndy Fiddaman    word.]
39*b30d1939SAndy Fiddaman[b:ignore-space?Ignore space differences when comparing expected
40*b30d1939SAndy Fiddaman    output.]
41*b30d1939SAndy Fiddaman[i:pipe-input?Repeat each test with the standard input redirected through a
42*b30d1939SAndy Fiddaman    pipe.]
43*b30d1939SAndy Fiddaman[k:keep?Enable \bcore\b dumps, exit after the first test that fails,
44*b30d1939SAndy Fiddaman    and do not remove the temporary directory \aunit\a\b.tmp\b.]
45*b30d1939SAndy Fiddaman[l:local-fs?Force \aunit\a\b.tmp\b to be in a local filesystem.]
46*b30d1939SAndy Fiddaman[o:pipe-output?Repeat each test with the standard output redirected through
47*b30d1939SAndy Fiddaman    a pipe.]
48*b30d1939SAndy Fiddaman[p:pipe-io?Repeat each test with the standard input and standard output
49*b30d1939SAndy Fiddaman    redirected through pipes.]
50*b30d1939SAndy Fiddaman[q:quiet?Output information on \bFAILED\b tests only.]
51*b30d1939SAndy Fiddaman[r!:regular?Run each test with the standard input and standard output
52*b30d1939SAndy Fiddaman    redirected through regular files.]
53*b30d1939SAndy Fiddaman[t:test?Run only tests matching \apattern\a. Tests are numbered and
54*b30d1939SAndy Fiddaman    consist of at least two digits (0 filled if necessary.) Tests matching
55*b30d1939SAndy Fiddaman    \b+(0)\b are always run.]:[pattern]
56*b30d1939SAndy Fiddaman[x:trace?Enable debug tracing.]
57*b30d1939SAndy Fiddaman[v:verbose?List differences between actual (<) and expected (>) output,
58*b30d1939SAndy Fiddaman    errors and exit codes. Also disable long output line truncation.]
59*b30d1939SAndy Fiddaman
60*b30d1939SAndy Fiddamanunit [ command [ arg ... ] ]
61*b30d1939SAndy Fiddaman
62*b30d1939SAndy Fiddaman[+INPUT FILES?The regression test file \aunit\a\b.tst\b is a \bksh\b(1)
63*b30d1939SAndy Fiddaman    script that is executed in an environment with the following functions
64*b30d1939SAndy Fiddaman    defined:]
65*b30d1939SAndy Fiddaman    {
66*b30d1939SAndy Fiddaman        [+BODY \b{ ... }?Defines the test body; used for complex tests.]
67*b30d1939SAndy Fiddaman        [+CD \b\adirectory\a?Create and change to working directory for
68*b30d1939SAndy Fiddaman            one test.]
69*b30d1939SAndy Fiddaman        [+CLEANUP \b\astatus\a?Called at exit time to remove the
70*b30d1939SAndy Fiddaman            temporary directory \aunit\a\b.tmp\b, list the tests totals via
71*b30d1939SAndy Fiddaman            \bTALLY\b, and exit with status \astatus\a.]
72*b30d1939SAndy Fiddaman        [+COMMAND \b\aarg\a ...?Runs the current command under test with
73*b30d1939SAndy Fiddaman            \aarg\a ... appended to the default args.]
74*b30d1939SAndy Fiddaman        [+CONTINUE?The background job must be running.]
75*b30d1939SAndy Fiddaman        [+COPY \b\afrom to\a?Copy file \afrom\a to \ato\a. \afrom\a may
76*b30d1939SAndy Fiddaman            be a regular file or \bINPUT\b, \bOUTPUT\b or \bERROR\b. Post
77*b30d1939SAndy Fiddaman            test comparisons are still done for \afrom\a.]
78*b30d1939SAndy Fiddaman        [+DIAGNOSTICS \b[ \b1\b | \b0\b | \apattern\a ]]?No argument or an
79*b30d1939SAndy Fiddaman	    argument of \b1\b declares that diagnostics are to expected for
80*b30d1939SAndy Fiddaman	    the remainder of the current \bTEST\b; \b0\b reverts to the default
81*b30d1939SAndy Fiddaman            state that diagnostics are not expected; otherwise the argument
82*b30d1939SAndy Fiddaman	    is a \bksh\b(1) pattern that must match the non-empty contents
83*b30d1939SAndy Fiddaman	    of the standard error.]
84*b30d1939SAndy Fiddaman        [+DO \b\astatement\a?Defines additional statements to be executed
85*b30d1939SAndy Fiddaman            for the current test. \astatement\a may be a { ... } group.]
86*b30d1939SAndy Fiddaman        [+EMPTY \bINPUT|OUTPUT|ERROR|SAME?The corresponding file is
87*b30d1939SAndy Fiddaman            expected to be empty.]
88*b30d1939SAndy Fiddaman        [+ERROR \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The
89*b30d1939SAndy Fiddaman	    standard error is expected to match either the contents
90*b30d1939SAndy Fiddaman	    of \afile\a or the line \adata\a. \bERROR -n\b does not
91*b30d1939SAndy Fiddaman	    append a newline to \adata\a. \afilter\a is a shell command
92*b30d1939SAndy Fiddaman	    or pipeline that reads standard input and writes standard
93*b30d1939SAndy Fiddaman	    output that is applied to ERROR before comparison with the
94*b30d1939SAndy Fiddaman	    expected contents.]
95*b30d1939SAndy Fiddaman        [+EXEC \b[ \aarg\a ... ]]?Runs the command under test with
96*b30d1939SAndy Fiddaman            optional arguments. \bINPUT\b, \bOUTPUT\b, \bERROR\b, \bEXIT\b
97*b30d1939SAndy Fiddaman            and \bSAME\b calls following this \bEXEC\b up until the next
98*b30d1939SAndy Fiddaman            \bEXEC\b or the end of the script provide details for the
99*b30d1939SAndy Fiddaman            expected results. If no arguments are specified then the
100*b30d1939SAndy Fiddaman            arguments from the previious \bEXEC\b in the current \bTEST\b
101*b30d1939SAndy Fiddaman            group are used, or no arguments if this is the first \bEXEC\b
102*b30d1939SAndy Fiddaman            in the group.]
103*b30d1939SAndy Fiddaman        [+EXIT \b\astatus\a?The command exit status is expected to match
104*b30d1939SAndy Fiddaman            the pattern \astatus\a.]
105*b30d1939SAndy Fiddaman        [+EXITED?The background job must have exited.]
106*b30d1939SAndy Fiddaman        [+EXPORT \b[-]] \aname\a=\avalue\a ...?Export environment
107*b30d1939SAndy Fiddaman            variables for one test.]
108*b30d1939SAndy Fiddaman        [+FATAL \b\amessage\a ...?\amessage\a is printed on the standard
109*b30d1939SAndy Fiddaman            error and \bregress\b exits with status \b1\b.]
110*b30d1939SAndy Fiddaman        [+FIFO \bINPUT|OUTPUT|ERROR\b [ \b-n\b ]] \afile\a | - \adata\a ...?The
111*b30d1939SAndy Fiddaman	    \bIO\B file is a fifo.]
112*b30d1939SAndy Fiddaman        [+IF \b\acommand\a [\anote\a]]?If the \bsh\b(1) \acommand\a exits
113*b30d1939SAndy Fiddaman            0 then tests until the next \bELIF\b, \bELSE\b or \bFI\b are
114*b30d1939SAndy Fiddaman            enabled. Otherwise those tests are skipped. \bIF\b ... \bFI\b
115*b30d1939SAndy Fiddaman            may be nested, but must not cross \bTEST\b boundaries. \anote\a
116*b30d1939SAndy Fiddaman            is listed on the standard error if the correspoding test block
117*b30d1939SAndy Fiddaman            is enabled; \bIF\b, \bELIF\b, \bELSE\b may nave a \anote\a
118*b30d1939SAndy Fiddaman            operand.]
119*b30d1939SAndy Fiddaman        [+IGNORE \b\afile\a ...?\afile\a is ignored for subsequent result
120*b30d1939SAndy Fiddaman            comparisons. \afile\a may be \bOUTPUT\b or \bERROR\b.]
121*b30d1939SAndy Fiddaman        [+IGNORESPACE?Ignore space differences when comparing expected
122*b30d1939SAndy Fiddaman            output.]
123*b30d1939SAndy Fiddaman        [+INCLUDE \b\afile\a ...?One or more \afile\a operands are read
124*b30d1939SAndy Fiddaman            via the \bksh\b(1) \b.\b(1) command. \bVIEW\b is used to locate
125*b30d1939SAndy Fiddaman            the files.]
126*b30d1939SAndy Fiddaman        [+INFO \b\adescription\a?\adescription\a is printed on the
127*b30d1939SAndy Fiddaman            standard error.]
128*b30d1939SAndy Fiddaman        [+INITIALIZE?Called by \bregress\b to initialize a each
129*b30d1939SAndy Fiddaman            \bTEST\b group.]
130*b30d1939SAndy Fiddaman        [+INPUT \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The
131*b30d1939SAndy Fiddaman	    standard input is set to either the contents of \afile\a
132*b30d1939SAndy Fiddaman	    or the line \adata\a. \bINPUT -n\b does not append a newline
133*b30d1939SAndy Fiddaman	    to \adata\a. \afilter\a is a shell command or pipeline that
134*b30d1939SAndy Fiddaman	    reads standard input and writes standard output that is
135*b30d1939SAndy Fiddaman	    applied to OUTPUT before comparison with the expected contents.]
136*b30d1939SAndy Fiddaman        [+INTRO?Called by \bregress\b to introduce all \bTEST\b
137*b30d1939SAndy Fiddaman            groups.]
138*b30d1939SAndy Fiddaman        [+IO \b[ \bFIFO\b | \bPIPE\b ]] \bINPUT|OUTPUT|ERROR\b [ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?Internal
139*b30d1939SAndy Fiddaman            support for the \bINPUT\b, \bOUTPUT\b and \bERROR\b functions.]
140*b30d1939SAndy Fiddaman        [+JOB \b\aop\a [ ... ]]?Like \bEXEC\b except the command is run
141*b30d1939SAndy Fiddaman            as a background job for the duration of the group or until it
142*b30d1939SAndy Fiddaman            is killed via \bKILL\b.]
143*b30d1939SAndy Fiddaman        [+KEEP \b\apattern\a ...?The temporary directory is cleared for
144*b30d1939SAndy Fiddaman            each test. Files matching \apattern\a are retained between
145*b30d1939SAndy Fiddaman            tests.]
146*b30d1939SAndy Fiddaman        [+KILL \b[ \asignal\a ]]?Kill the background job with \asignal\a
147*b30d1939SAndy Fiddaman        [ \bSIGKILL\b ]].]
148*b30d1939SAndy Fiddaman        [+MOVE \b\afrom to\a?Rename file \afrom\a to \ato\a. \afrom\a may
149*b30d1939SAndy Fiddaman            be a regular file or \bINPUT\b, \bOUTPUT\b or \bERROR\b. Post
150*b30d1939SAndy Fiddaman            test comparisons are ignored for \afrom\a.]
151*b30d1939SAndy Fiddaman        [+NOTE \b\acomment\a?\acomment\a is added to the current test
152*b30d1939SAndy Fiddaman            trace output.]
153*b30d1939SAndy Fiddaman        [+OUTPUT \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The
154*b30d1939SAndy Fiddaman	    standard output is expected to match either the contents
155*b30d1939SAndy Fiddaman	    of \afile\a or the line \adata\a. \bOUTPUT -n\b does not
156*b30d1939SAndy Fiddaman	    append a newline to \adata\a. \afilter\a is a shell command
157*b30d1939SAndy Fiddaman	    or pipeline that reads standard input and writes standard
158*b30d1939SAndy Fiddaman	    output that is applied to ERROR before comparison with the
159*b30d1939SAndy Fiddaman	    expected contents.]
160*b30d1939SAndy Fiddaman        [+PIPE \bINPUT|OUTPUT|ERROR\b [ \b-n\b ]] \afile\a | - \adata\a ...?The
161*b30d1939SAndy Fiddaman	    \bIO\B file is a pipe.]
162*b30d1939SAndy Fiddaman        [+PROG \b\acommand\a [ \aarg\a ... ]]?\acommand\a is run with
163*b30d1939SAndy Fiddaman            optional arguments.]
164*b30d1939SAndy Fiddaman        [+REMOVE \b\afile\a ...?\afile\a ... are removed after the
165*b30d1939SAndy Fiddaman            current test is done.]
166*b30d1939SAndy Fiddaman        [+RUN?Called by \bregress\b to run the current test.]
167*b30d1939SAndy Fiddaman        [+SAME \b\anew old\a?\anew\a is expected to be the same as
168*b30d1939SAndy Fiddaman            \aold\a after the current test completes.]
169*b30d1939SAndy Fiddaman        [+SET \b[\bno\b]]\aname\a[=\avalue\a]]?Set the command line
170*b30d1939SAndy Fiddaman            option --\aname\a. The setting is in effect for all tests until
171*b30d1939SAndy Fiddaman            the next explicit \bSET\b.]
172*b30d1939SAndy Fiddaman        [+TALLY?Called by \bregress\b display the \bTEST\b results.]
173*b30d1939SAndy Fiddaman        [+TEST \b\anumber\a [ \adescription\a ... ]]?Define a new test
174*b30d1939SAndy Fiddaman            group labelled \anumber\a with optional \adescripion\a.]
175*b30d1939SAndy Fiddaman        [+TITLE \b[+]] \atext\a?Set the \bTEST\b output title to
176*b30d1939SAndy Fiddaman            \atext\a. If \b+\b is specified then \atext\a is appended to
177*b30d1939SAndy Fiddaman            the default title. The default title is the test file base
178*b30d1939SAndy Fiddaman            name, and, if different from the test file base name, the test
179*b30d1939SAndy Fiddaman            unit base name.]
180*b30d1939SAndy Fiddaman        [+TWD \b[ \adir\a ... ]]?Set the temporary test dir to \adir\a.
181*b30d1939SAndy Fiddaman            The default is \aunit\a\b.tmp\b, where \aunit\a is the test
182*b30d1939SAndy Fiddaman            input file sans directory and suffix. If \adir\a matches \b/*\b
183*b30d1939SAndy Fiddaman            then it is the directory name; if \adir\a is non-null then the
184*b30d1939SAndy Fiddaman            prefix \b${TMPDIR:-/tmp}\b is added; otherwise if \adir\a is
185*b30d1939SAndy Fiddaman            omitted then
186*b30d1939SAndy Fiddaman            \b${TMPDIR:-/tmp}/tst-\b\aunit\a-$$-$RANDOM.\b\aunit\a is
187*b30d1939SAndy Fiddaman            used.]
188*b30d1939SAndy Fiddaman        [+UMASK \b[ \amask\a ]]?Run subsequent tests with \bumask\b(1)
189*b30d1939SAndy Fiddaman            \amask\a. If \amask\a is omitted then the original \bumask\b is
190*b30d1939SAndy Fiddaman            used.]
191*b30d1939SAndy Fiddaman        [+UNIT \b\acommand\a [ \aarg\a ... ]]?Define the command and
192*b30d1939SAndy Fiddaman            optional default arguments to be tested. \bUNIT\b explicitly
193*b30d1939SAndy Fiddaman            overrides the default command name derived from the test script
194*b30d1939SAndy Fiddaman            file name. A \acommand\a operand with optional arguments
195*b30d1939SAndy Fiddaman            overrides the \bUNIT\b \acommand\a and arguments, with the
196*b30d1939SAndy Fiddaman            exception that if the \bUNIT\b \acommand\a is \b-\b or \b+\b
197*b30d1939SAndy Fiddaman            the \bUNIT\b arguments are appended to the operand or default
198*b30d1939SAndy Fiddaman            unit command and arguments.]
199*b30d1939SAndy Fiddaman        [+VIEW \b\avar\a [ \afile\a ]]?\avar\a is set to the full
200*b30d1939SAndy Fiddaman            pathname of \avar\a [ \afile\a ]] in the current \b$VPATH\b
201*b30d1939SAndy Fiddaman            view if defined.]
202*b30d1939SAndy Fiddaman    }
203*b30d1939SAndy Fiddaman[+SEE ALSO?\bnmake\b(1), \bksh\b(1)]
204*b30d1939SAndy Fiddaman'
205*b30d1939SAndy Fiddaman	;;
206*b30d1939SAndy Fiddaman*)	USAGE='ko:[[no]name[=value]]t:[test]v unit [path [arg ...]]'
207*b30d1939SAndy Fiddaman	;;
208*b30d1939SAndy Fiddamanesac
209*b30d1939SAndy Fiddaman
210*b30d1939SAndy Fiddamanfunction FATAL # message
211*b30d1939SAndy Fiddaman{
212*b30d1939SAndy Fiddaman	print -r -u2 "$command: $*"
213*b30d1939SAndy Fiddaman	GROUP=FINI
214*b30d1939SAndy Fiddaman	exit 1
215*b30d1939SAndy Fiddaman}
216*b30d1939SAndy Fiddaman
217*b30d1939SAndy Fiddamanfunction EMPTY
218*b30d1939SAndy Fiddaman{
219*b30d1939SAndy Fiddaman	typeset i
220*b30d1939SAndy Fiddaman	typeset -n ARRAY=$1
221*b30d1939SAndy Fiddaman	for i in ${!ARRAY[@]}
222*b30d1939SAndy Fiddaman	do	unset ARRAY[$i]
223*b30d1939SAndy Fiddaman	done
224*b30d1939SAndy Fiddaman}
225*b30d1939SAndy Fiddaman
226*b30d1939SAndy Fiddamanfunction INITIALIZE # void
227*b30d1939SAndy Fiddaman{
228*b30d1939SAndy Fiddaman	typeset i j
229*b30d1939SAndy Fiddaman	cd "$TWD"
230*b30d1939SAndy Fiddaman	case $KEEP in
231*b30d1939SAndy Fiddaman	"")	RM *
232*b30d1939SAndy Fiddaman		;;
233*b30d1939SAndy Fiddaman	*)	for i in *
234*b30d1939SAndy Fiddaman		do	case $i in
235*b30d1939SAndy Fiddaman			!($KEEP))	j="$j $i" ;;
236*b30d1939SAndy Fiddaman			esac
237*b30d1939SAndy Fiddaman		done
238*b30d1939SAndy Fiddaman		case $j in
239*b30d1939SAndy Fiddaman		?*)	RM $j ;;
240*b30d1939SAndy Fiddaman		esac
241*b30d1939SAndy Fiddaman		;;
242*b30d1939SAndy Fiddaman	esac
243*b30d1939SAndy Fiddaman	: >INPUT >OUTPUT.ex >ERROR.ex
244*b30d1939SAndy Fiddaman	BODY=""
245*b30d1939SAndy Fiddaman	COPY=""
246*b30d1939SAndy Fiddaman	DIAGNOSTICS=""
247*b30d1939SAndy Fiddaman	DONE=""
248*b30d1939SAndy Fiddaman	ERROR=""
249*b30d1939SAndy Fiddaman	EXIT=0
250*b30d1939SAndy Fiddaman	IGNORE=""
251*b30d1939SAndy Fiddaman	INIT=""
252*b30d1939SAndy Fiddaman	INPUT=""
253*b30d1939SAndy Fiddaman	MOVE=""
254*b30d1939SAndy Fiddaman	OUTPUT=""
255*b30d1939SAndy Fiddaman	EMPTY FILE
256*b30d1939SAndy Fiddaman	EMPTY FILTER
257*b30d1939SAndy Fiddaman	EMPTY SAME
258*b30d1939SAndy Fiddaman	EMPTY TYPE
259*b30d1939SAndy Fiddaman}
260*b30d1939SAndy Fiddaman
261*b30d1939SAndy Fiddamanfunction INTRO
262*b30d1939SAndy Fiddaman{
263*b30d1939SAndy Fiddaman	typeset base command
264*b30d1939SAndy Fiddaman
265*b30d1939SAndy Fiddaman	if	[[ ! $TEST_quiet ]]
266*b30d1939SAndy Fiddaman	then	base=${REGRESS##*/}
267*b30d1939SAndy Fiddaman		base=${base%.tst}
268*b30d1939SAndy Fiddaman		command=${COMMAND##*/}
269*b30d1939SAndy Fiddaman		command=${command%' '*}
270*b30d1939SAndy Fiddaman		set -- $TITLE
271*b30d1939SAndy Fiddaman		TITLE=
272*b30d1939SAndy Fiddaman		case $1 in
273*b30d1939SAndy Fiddaman		''|+)	if	[[ $command == $base ]]
274*b30d1939SAndy Fiddaman			then	TITLE=$COMMAND
275*b30d1939SAndy Fiddaman			else	TITLE="$COMMAND, $base"
276*b30d1939SAndy Fiddaman			fi
277*b30d1939SAndy Fiddaman			if	(( $# ))
278*b30d1939SAndy Fiddaman			then	shift
279*b30d1939SAndy Fiddaman			fi
280*b30d1939SAndy Fiddaman			;;
281*b30d1939SAndy Fiddaman		esac
282*b30d1939SAndy Fiddaman		while	(( $# ))
283*b30d1939SAndy Fiddaman		do	if	[[ $TITLE ]]
284*b30d1939SAndy Fiddaman			then	TITLE="$TITLE, $1"
285*b30d1939SAndy Fiddaman			else	TITLE="$1"
286*b30d1939SAndy Fiddaman			fi
287*b30d1939SAndy Fiddaman			shift
288*b30d1939SAndy Fiddaman		done
289*b30d1939SAndy Fiddaman		print -u2 "TEST	$TITLE"
290*b30d1939SAndy Fiddaman	fi
291*b30d1939SAndy Fiddaman}
292*b30d1939SAndy Fiddaman
293*b30d1939SAndy Fiddamanfunction TALLY # extra message text
294*b30d1939SAndy Fiddaman{
295*b30d1939SAndy Fiddaman	typeset msg
296*b30d1939SAndy Fiddaman	case $GROUP in
297*b30d1939SAndy Fiddaman	INIT)	;;
298*b30d1939SAndy Fiddaman	*)	msg="TEST	$TITLE, $TESTS test"
299*b30d1939SAndy Fiddaman		case $TESTS in
300*b30d1939SAndy Fiddaman		1)	;;
301*b30d1939SAndy Fiddaman		*)	msg=${msg}s ;;
302*b30d1939SAndy Fiddaman		esac
303*b30d1939SAndy Fiddaman		msg="$msg, $ERRORS error"
304*b30d1939SAndy Fiddaman		case $ERRORS in
305*b30d1939SAndy Fiddaman		1)	;;
306*b30d1939SAndy Fiddaman		*)	msg=${msg}s ;;
307*b30d1939SAndy Fiddaman		esac
308*b30d1939SAndy Fiddaman		if	(( $# ))
309*b30d1939SAndy Fiddaman		then	msg="$msg, $*"
310*b30d1939SAndy Fiddaman		fi
311*b30d1939SAndy Fiddaman		print -u2 "$msg"
312*b30d1939SAndy Fiddaman		GROUP=INIT
313*b30d1939SAndy Fiddaman		TESTS=0
314*b30d1939SAndy Fiddaman		ERRORS=0
315*b30d1939SAndy Fiddaman		;;
316*b30d1939SAndy Fiddaman	esac
317*b30d1939SAndy Fiddaman}
318*b30d1939SAndy Fiddaman
319*b30d1939SAndy Fiddamanfunction TITLE # text
320*b30d1939SAndy Fiddaman{
321*b30d1939SAndy Fiddaman	TITLE=$@
322*b30d1939SAndy Fiddaman}
323*b30d1939SAndy Fiddaman
324*b30d1939SAndy Fiddamanfunction UNWIND
325*b30d1939SAndy Fiddaman{
326*b30d1939SAndy Fiddaman	while	(( COND > 1 ))
327*b30d1939SAndy Fiddaman	do	print -r -u2 "$command: line $LINE: no matching FI for IF on line ${COND_LINE[COND]}"
328*b30d1939SAndy Fiddaman		(( COND-- ))
329*b30d1939SAndy Fiddaman	done
330*b30d1939SAndy Fiddaman	if	(( COND > 0 ))
331*b30d1939SAndy Fiddaman	then	(( COND = 0 ))
332*b30d1939SAndy Fiddaman		FATAL "line $LINE: no matching FI for IF on line ${COND_LINE[COND+1]}"
333*b30d1939SAndy Fiddaman	fi
334*b30d1939SAndy Fiddaman	if	[[ $JOBPID ]]
335*b30d1939SAndy Fiddaman	then	if	[[ $JOBPID != 0 ]]
336*b30d1939SAndy Fiddaman		then	kill -KILL $JOBPID 2>/dev/null
337*b30d1939SAndy Fiddaman			wait
338*b30d1939SAndy Fiddaman		fi
339*b30d1939SAndy Fiddaman		JOBPID=
340*b30d1939SAndy Fiddaman	fi
341*b30d1939SAndy Fiddaman	JOBSTATUS=
342*b30d1939SAndy Fiddaman	JOBOP=
343*b30d1939SAndy Fiddaman	wait
344*b30d1939SAndy Fiddaman}
345*b30d1939SAndy Fiddaman
346*b30d1939SAndy Fiddamanfunction CLEANUP # status
347*b30d1939SAndy Fiddaman{
348*b30d1939SAndy Fiddaman	typeset note
349*b30d1939SAndy Fiddaman
350*b30d1939SAndy Fiddaman	if	[[ $GROUP != INIT ]]
351*b30d1939SAndy Fiddaman	then	if	[[ ! $TEST_keep ]]
352*b30d1939SAndy Fiddaman		then	cd $SOURCE
353*b30d1939SAndy Fiddaman			if	[[ $TEST_local ]]
354*b30d1939SAndy Fiddaman			then	RM ${TEST_local}
355*b30d1939SAndy Fiddaman			fi
356*b30d1939SAndy Fiddaman			RM "$TWD"
357*b30d1939SAndy Fiddaman		fi
358*b30d1939SAndy Fiddaman		if	(( $1 )) && [[ $GROUP != FINI ]]
359*b30d1939SAndy Fiddaman		then	note=terminated
360*b30d1939SAndy Fiddaman		fi
361*b30d1939SAndy Fiddaman	fi
362*b30d1939SAndy Fiddaman	TALLY $note
363*b30d1939SAndy Fiddaman	[[ $TEST_keep ]] || UNWIND
364*b30d1939SAndy Fiddaman	exit $1
365*b30d1939SAndy Fiddaman}
366*b30d1939SAndy Fiddaman
367*b30d1939SAndy Fiddamanfunction RUN # [ op ]
368*b30d1939SAndy Fiddaman{
369*b30d1939SAndy Fiddaman	typeset i r=1
370*b30d1939SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
372*b30d1939SAndy Fiddaman	case $GROUP in
373*b30d1939SAndy Fiddaman	INIT)	RM "$TWD"
374*b30d1939SAndy Fiddaman		if	[[ $TEST_local ]]
375*b30d1939SAndy Fiddaman		then	TEST_local=${TMPDIR:-/tmp}/rt-$$/${TWD##*/}
376*b30d1939SAndy Fiddaman			mkdir -p "$TEST_local" && ln -s "$TEST_local" "$TWD" || FATAL "$TWD": cannot create directory
377*b30d1939SAndy Fiddaman			TEST_local=${TEST_local%/*}
378*b30d1939SAndy Fiddaman		else	mkdir "$TWD" || FATAL "$TWD": cannot create directory
379*b30d1939SAndy Fiddaman		fi
380*b30d1939SAndy Fiddaman		cd "$TWD"
381*b30d1939SAndy Fiddaman		TWD=$PWD
382*b30d1939SAndy Fiddaman		: > rmu
383*b30d1939SAndy Fiddaman		if	rm -u rmu >/dev/null 2>&1
384*b30d1939SAndy Fiddaman		then	TEST_rmu=-u
385*b30d1939SAndy Fiddaman		else	rm rmu
386*b30d1939SAndy Fiddaman		fi
387*b30d1939SAndy Fiddaman		if	[[ $UNIT ]]
388*b30d1939SAndy Fiddaman		then	set -- "${ARGV[@]}"
389*b30d1939SAndy Fiddaman			case $1 in
390*b30d1939SAndy Fiddaman			""|[-+]*)
391*b30d1939SAndy Fiddaman				UNIT $UNIT "${ARGV[@]}"
392*b30d1939SAndy Fiddaman				;;
393*b30d1939SAndy Fiddaman			*)	UNIT "${ARGV[@]}"
394*b30d1939SAndy Fiddaman				;;
395*b30d1939SAndy Fiddaman			esac
396*b30d1939SAndy Fiddaman		fi
397*b30d1939SAndy Fiddaman		INTRO
398*b30d1939SAndy Fiddaman		;;
399*b30d1939SAndy Fiddaman	FINI)	;;
400*b30d1939SAndy Fiddaman	$TEST_select)
401*b30d1939SAndy Fiddaman		if	[[ $ITEM == $FLUSHED ]]
402*b30d1939SAndy Fiddaman		then	return 0
403*b30d1939SAndy Fiddaman		fi
404*b30d1939SAndy Fiddaman		FLUSHED=$ITEM
405*b30d1939SAndy Fiddaman		if	(( COND_SKIP[COND] ))
406*b30d1939SAndy Fiddaman		then	return 1
407*b30d1939SAndy Fiddaman		fi