xref: /titanic_51/usr/src/contrib/ast/src/cmd/INIT/regress.sh (revision b4dd7d09880f14016feece03929a224eca1cf39a)
1*b4dd7d09SAndy Fiddaman########################################################################
2*b4dd7d09SAndy Fiddaman#                                                                      #
3*b4dd7d09SAndy Fiddaman#               This software is part of the ast package               #
4*b4dd7d09SAndy Fiddaman#          Copyright (c) 1994-2012 AT&T Intellectual Property          #
5*b4dd7d09SAndy Fiddaman#                      and is licensed under the                       #
6*b4dd7d09SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
7*b4dd7d09SAndy Fiddaman#                    by AT&T Intellectual Property                     #
8*b4dd7d09SAndy Fiddaman#                                                                      #
9*b4dd7d09SAndy Fiddaman#                A copy of the License is available at                 #
10*b4dd7d09SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
11*b4dd7d09SAndy Fiddaman#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
12*b4dd7d09SAndy Fiddaman#                                                                      #
13*b4dd7d09SAndy Fiddaman#              Information and Software Systems Research               #
14*b4dd7d09SAndy Fiddaman#                            AT&T Research                             #
15*b4dd7d09SAndy Fiddaman#                           Florham Park NJ                            #
16*b4dd7d09SAndy Fiddaman#                                                                      #
17*b4dd7d09SAndy Fiddaman#                 Glenn Fowler <gsf@research.att.com>                  #
18*b4dd7d09SAndy Fiddaman#                                                                      #
19*b4dd7d09SAndy Fiddaman########################################################################
20*b4dd7d09SAndy Fiddaman: regress - run regression tests in command.tst
21*b4dd7d09SAndy Fiddaman
22*b4dd7d09SAndy Fiddamancommand=regress
23*b4dd7d09SAndy Fiddamancase $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in
24*b4dd7d09SAndy Fiddaman0123)	USAGE=$'
25*b4dd7d09SAndy Fiddaman[-?
26*b4dd7d09SAndy Fiddaman@(#)$Id: regress (AT&T Research) 2012-02-02 $
27*b4dd7d09SAndy Fiddaman]
28*b4dd7d09SAndy Fiddaman'$USAGE_LICENSE$'
29*b4dd7d09SAndy Fiddaman[+NAME?regress - run regression tests]
30*b4dd7d09SAndy Fiddaman[+DESCRIPTION?\bregress\b runs the tests in \aunit\a, or
31*b4dd7d09SAndy Fiddaman    \aunit\a\b.tst\b if \aunit\a does not exist. If \acommand\a is omitted
32*b4dd7d09SAndy Fiddaman    then it is assumed to be the base name of \aunit\a. All testing is done
33*b4dd7d09SAndy Fiddaman    in the temporary directory \aunit\a\b.tmp\b.]
34*b4dd7d09SAndy Fiddaman[+?Default test output lists the \anumber\a and \adescription\a for
35*b4dd7d09SAndy Fiddaman    each active \bTEST\b group and the \anumber\a:\aline\a for each
36*b4dd7d09SAndy Fiddaman    individual \bEXEC\b test. Each test that fails results in a diagnostic
37*b4dd7d09SAndy Fiddaman    that contains the word \bFAILED\b; no other diagnostics contain this
38*b4dd7d09SAndy Fiddaman    word.]
39*b4dd7d09SAndy Fiddaman[b:ignore-space?Ignore space differences when comparing expected
40*b4dd7d09SAndy Fiddaman    output.]
41*b4dd7d09SAndy Fiddaman[i:pipe-input?Repeat each test with the standard input redirected through a
42*b4dd7d09SAndy Fiddaman    pipe.]
43*b4dd7d09SAndy Fiddaman[k:keep?Enable \bcore\b dumps, exit after the first test that fails,
44*b4dd7d09SAndy Fiddaman    and do not remove the temporary directory \aunit\a\b.tmp\b.]
45*b4dd7d09SAndy Fiddaman[l:local-fs?Force \aunit\a\b.tmp\b to be in a local filesystem.]
46*b4dd7d09SAndy Fiddaman[o:pipe-output?Repeat each test with the standard output redirected through
47*b4dd7d09SAndy Fiddaman    a pipe.]
48*b4dd7d09SAndy Fiddaman[p:pipe-io?Repeat each test with the standard input and standard output
49*b4dd7d09SAndy Fiddaman    redirected through pipes.]
50*b4dd7d09SAndy Fiddaman[q:quiet?Output information on \bFAILED\b tests only.]
51*b4dd7d09SAndy Fiddaman[r!:regular?Run each test with the standard input and standard output
52*b4dd7d09SAndy Fiddaman    redirected through regular files.]
53*b4dd7d09SAndy Fiddaman[t:test?Run only tests matching \apattern\a. Tests are numbered and
54*b4dd7d09SAndy Fiddaman    consist of at least two digits (0 filled if necessary.) Tests matching
55*b4dd7d09SAndy Fiddaman    \b+(0)\b are always run.]:[pattern]
56*b4dd7d09SAndy Fiddaman[x:trace?Enable debug tracing.]
57*b4dd7d09SAndy Fiddaman[v:verbose?List differences between actual (<) and expected (>) output,
58*b4dd7d09SAndy Fiddaman    errors and exit codes. Also disable long output line truncation.]
59*b4dd7d09SAndy Fiddaman
60*b4dd7d09SAndy Fiddamanunit [ command [ arg ... ] ]
61*b4dd7d09SAndy Fiddaman
62*b4dd7d09SAndy Fiddaman[+INPUT FILES?The regression test file \aunit\a\b.tst\b is a \bksh\b(1)
63*b4dd7d09SAndy Fiddaman    script that is executed in an environment with the following functions
64*b4dd7d09SAndy Fiddaman    defined:]
65*b4dd7d09SAndy Fiddaman    {
66*b4dd7d09SAndy Fiddaman        [+BODY \b{ ... }?Defines the test body; used for complex tests.]
67*b4dd7d09SAndy Fiddaman        [+CD \b\adirectory\a?Create and change to working directory for
68*b4dd7d09SAndy Fiddaman            one test.]
69*b4dd7d09SAndy Fiddaman        [+CLEANUP \b\astatus\a?Called at exit time to remove the
70*b4dd7d09SAndy Fiddaman            temporary directory \aunit\a\b.tmp\b, list the tests totals via
71*b4dd7d09SAndy Fiddaman            \bTALLY\b, and exit with status \astatus\a.]
72*b4dd7d09SAndy Fiddaman        [+COMMAND \b\aarg\a ...?Runs the current command under test with
73*b4dd7d09SAndy Fiddaman            \aarg\a ... appended to the default args.]
74*b4dd7d09SAndy Fiddaman        [+CONTINUE?The background job must be running.]
75*b4dd7d09SAndy Fiddaman        [+COPY \b\afrom to\a?Copy file \afrom\a to \ato\a. \afrom\a may
76*b4dd7d09SAndy Fiddaman            be a regular file or \bINPUT\b, \bOUTPUT\b or \bERROR\b. Post
77*b4dd7d09SAndy Fiddaman            test comparisons are still done for \afrom\a.]
78*b4dd7d09SAndy Fiddaman        [+DIAGNOSTICS \b[ \b1\b | \b0\b | \apattern\a ]]?No argument or an
79*b4dd7d09SAndy Fiddaman	    argument of \b1\b declares that diagnostics are to expected for
80*b4dd7d09SAndy Fiddaman	    the remainder of the current \bTEST\b; \b0\b reverts to the default
81*b4dd7d09SAndy Fiddaman            state that diagnostics are not expected; otherwise the argument
82*b4dd7d09SAndy Fiddaman	    is a \bksh\b(1) pattern that must match the non-empty contents
83*b4dd7d09SAndy Fiddaman	    of the standard error.]
84*b4dd7d09SAndy Fiddaman        [+DO \b\astatement\a?Defines additional statements to be executed
85*b4dd7d09SAndy Fiddaman            for the current test. \astatement\a may be a { ... } group.]
86*b4dd7d09SAndy Fiddaman        [+EMPTY \bINPUT|OUTPUT|ERROR|SAME?The corresponding file is
87*b4dd7d09SAndy Fiddaman            expected to be empty.]
88*b4dd7d09SAndy Fiddaman        [+ERROR \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The
89*b4dd7d09SAndy Fiddaman	    standard error is expected to match either the contents
90*b4dd7d09SAndy Fiddaman	    of \afile\a or the line \adata\a. \bERROR -n\b does not
91*b4dd7d09SAndy Fiddaman	    append a newline to \adata\a. \afilter\a is a shell command
92*b4dd7d09SAndy Fiddaman	    or pipeline that reads standard input and writes standard
93*b4dd7d09SAndy Fiddaman	    output that is applied to ERROR before comparison with the
94*b4dd7d09SAndy Fiddaman	    expected contents.]
95*b4dd7d09SAndy Fiddaman        [+EXEC \b[ \aarg\a ... ]]?Runs the command under test with
96*b4dd7d09SAndy Fiddaman            optional arguments. \bINPUT\b, \bOUTPUT\b, \bERROR\b, \bEXIT\b
97*b4dd7d09SAndy Fiddaman            and \bSAME\b calls following this \bEXEC\b up until the next
98*b4dd7d09SAndy Fiddaman            \bEXEC\b or the end of the script provide details for the
99*b4dd7d09SAndy Fiddaman            expected results. If no arguments are specified then the
100*b4dd7d09SAndy Fiddaman            arguments from the previious \bEXEC\b in the current \bTEST\b
101*b4dd7d09SAndy Fiddaman            group are used, or no arguments if this is the first \bEXEC\b
102*b4dd7d09SAndy Fiddaman            in the group.]
103*b4dd7d09SAndy Fiddaman        [+EXIT \b\astatus\a?The command exit status is expected to match
104*b4dd7d09SAndy Fiddaman            the pattern \astatus\a.]
105*b4dd7d09SAndy Fiddaman        [+EXITED?The background job must have exited.]
106*b4dd7d09SAndy Fiddaman        [+EXPORT \b[-]] \aname\a=\avalue\a ...?Export environment
107*b4dd7d09SAndy Fiddaman            variables for one test.]
108*b4dd7d09SAndy Fiddaman        [+FATAL \b\amessage\a ...?\amessage\a is printed on the standard
109*b4dd7d09SAndy Fiddaman            error and \bregress\b exits with status \b1\b.]
110*b4dd7d09SAndy Fiddaman        [+FIFO \bINPUT|OUTPUT|ERROR\b [ \b-n\b ]] \afile\a | - \adata\a ...?The
111*b4dd7d09SAndy Fiddaman	    \bIO\B file is a fifo.]
112*b4dd7d09SAndy Fiddaman        [+IF \b\acommand\a [\anote\a]]?If the \bsh\b(1) \acommand\a exits
113*b4dd7d09SAndy Fiddaman            0 then tests until the next \bELIF\b, \bELSE\b or \bFI\b are
114*b4dd7d09SAndy Fiddaman            enabled. Otherwise those tests are skipped. \bIF\b ... \bFI\b
115*b4dd7d09SAndy Fiddaman            may be nested, but must not cross \bTEST\b boundaries. \anote\a
116*b4dd7d09SAndy Fiddaman            is listed on the standard error if the correspoding test block
117*b4dd7d09SAndy Fiddaman            is enabled; \bIF\b, \bELIF\b, \bELSE\b may nave a \anote\a
118*b4dd7d09SAndy Fiddaman            operand.]
119*b4dd7d09SAndy Fiddaman        [+IGNORE \b\afile\a ...?\afile\a is ignored for subsequent result
120*b4dd7d09SAndy Fiddaman            comparisons. \afile\a may be \bOUTPUT\b or \bERROR\b.]
121*b4dd7d09SAndy Fiddaman        [+IGNORESPACE?Ignore space differences when comparing expected
122*b4dd7d09SAndy Fiddaman            output.]
123*b4dd7d09SAndy Fiddaman        [+INCLUDE \b\afile\a ...?One or more \afile\a operands are read
124*b4dd7d09SAndy Fiddaman            via the \bksh\b(1) \b.\b(1) command. \bVIEW\b is used to locate
125*b4dd7d09SAndy Fiddaman            the files.]
126*b4dd7d09SAndy Fiddaman        [+INFO \b\adescription\a?\adescription\a is printed on the
127*b4dd7d09SAndy Fiddaman            standard error.]
128*b4dd7d09SAndy Fiddaman        [+INITIALIZE?Called by \bregress\b to initialize a each
129*b4dd7d09SAndy Fiddaman            \bTEST\b group.]
130*b4dd7d09SAndy Fiddaman        [+INPUT \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The
131*b4dd7d09SAndy Fiddaman	    standard input is set to either the contents of \afile\a
132*b4dd7d09SAndy Fiddaman	    or the line \adata\a. \bINPUT -n\b does not append a newline
133*b4dd7d09SAndy Fiddaman	    to \adata\a. \afilter\a is a shell command or pipeline that
134*b4dd7d09SAndy Fiddaman	    reads standard input and writes standard output that is
135*b4dd7d09SAndy Fiddaman	    applied to OUTPUT before comparison with the expected contents.]
136*b4dd7d09SAndy Fiddaman        [+INTRO?Called by \bregress\b to introduce all \bTEST\b
137*b4dd7d09SAndy Fiddaman            groups.]
138*b4dd7d09SAndy 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*b4dd7d09SAndy Fiddaman            support for the \bINPUT\b, \bOUTPUT\b and \bERROR\b functions.]
140*b4dd7d09SAndy Fiddaman        [+JOB \b\aop\a [ ... ]]?Like \bEXEC\b except the command is run
141*b4dd7d09SAndy Fiddaman            as a background job for the duration of the group or until it
142*b4dd7d09SAndy Fiddaman            is killed via \bKILL\b.]
143*b4dd7d09SAndy Fiddaman        [+KEEP \b\apattern\a ...?The temporary directory is cleared for
144*b4dd7d09SAndy Fiddaman            each test. Files matching \apattern\a are retained between
145*b4dd7d09SAndy Fiddaman            tests.]
146*b4dd7d09SAndy Fiddaman        [+KILL \b[ \asignal\a ]]?Kill the background job with \asignal\a
147*b4dd7d09SAndy Fiddaman        [ \bSIGKILL\b ]].]
148*b4dd7d09SAndy Fiddaman        [+MOVE \b\afrom to\a?Rename file \afrom\a to \ato\a. \afrom\a may
149*b4dd7d09SAndy Fiddaman            be a regular file or \bINPUT\b, \bOUTPUT\b or \bERROR\b. Post
150*b4dd7d09SAndy Fiddaman            test comparisons are ignored for \afrom\a.]
151*b4dd7d09SAndy Fiddaman        [+NOTE \b\acomment\a?\acomment\a is added to the current test
152*b4dd7d09SAndy Fiddaman            trace output.]
153*b4dd7d09SAndy Fiddaman        [+OUTPUT \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The
154*b4dd7d09SAndy Fiddaman	    standard output is expected to match either the contents
155*b4dd7d09SAndy Fiddaman	    of \afile\a or the line \adata\a. \bOUTPUT -n\b does not
156*b4dd7d09SAndy Fiddaman	    append a newline to \adata\a. \afilter\a is a shell command
157*b4dd7d09SAndy Fiddaman	    or pipeline that reads standard input and writes standard
158*b4dd7d09SAndy Fiddaman	    output that is applied to ERROR before comparison with the
159*b4dd7d09SAndy Fiddaman	    expected contents.]
160*b4dd7d09SAndy Fiddaman        [+PIPE \bINPUT|OUTPUT|ERROR\b [ \b-n\b ]] \afile\a | - \adata\a ...?The
161*b4dd7d09SAndy Fiddaman	    \bIO\B file is a pipe.]
162*b4dd7d09SAndy Fiddaman        [+PROG \b\acommand\a [ \aarg\a ... ]]?\acommand\a is run with
163*b4dd7d09SAndy Fiddaman            optional arguments.]
164*b4dd7d09SAndy Fiddaman        [+REMOVE \b\afile\a ...?\afile\a ... are removed after the
165*b4dd7d09SAndy Fiddaman            current test is done.]
166*b4dd7d09SAndy Fiddaman        [+RUN?Called by \bregress\b to run the current test.]
167*b4dd7d09SAndy Fiddaman        [+SAME \b\anew old\a?\anew\a is expected to be the same as
168*b4dd7d09SAndy Fiddaman            \aold\a after the current test completes.]
169*b4dd7d09SAndy Fiddaman        [+SET \b[\bno\b]]\aname\a[=\avalue\a]]?Set the command line
170*b4dd7d09SAndy Fiddaman            option --\aname\a. The setting is in effect for all tests until
171*b4dd7d09SAndy Fiddaman            the next explicit \bSET\b.]
172*b4dd7d09SAndy Fiddaman        [+TALLY?Called by \bregress\b display the \bTEST\b results.]
173*b4dd7d09SAndy Fiddaman        [+TEST \b\anumber\a [ \adescription\a ... ]]?Define a new test
174*b4dd7d09SAndy Fiddaman            group labelled \anumber\a with optional \adescripion\a.]
175*b4dd7d09SAndy Fiddaman        [+TITLE \b[+]] \atext\a?Set the \bTEST\b output title to
176*b4dd7d09SAndy Fiddaman            \atext\a. If \b+\b is specified then \atext\a is appended to
177*b4dd7d09SAndy Fiddaman            the default title. The default title is the test file base
178*b4dd7d09SAndy Fiddaman            name, and, if different from the test file base name, the test
179*b4dd7d09SAndy Fiddaman            unit base name.]
180*b4dd7d09SAndy Fiddaman        [+TWD \b[ \adir\a ... ]]?Set the temporary test dir to \adir\a.
181*b4dd7d09SAndy Fiddaman            The default is \aunit\a\b.tmp\b, where \aunit\a is the test
182*b4dd7d09SAndy Fiddaman            input file sans directory and suffix. If \adir\a matches \b/*\b
183*b4dd7d09SAndy Fiddaman            then it is the directory name; if \adir\a is non-null then the
184*b4dd7d09SAndy Fiddaman            prefix \b${TMPDIR:-/tmp}\b is added; otherwise if \adir\a is
185*b4dd7d09SAndy Fiddaman            omitted then
186*b4dd7d09SAndy Fiddaman            \b${TMPDIR:-/tmp}/tst-\b\aunit\a-$$-$RANDOM.\b\aunit\a is
187*b4dd7d09SAndy Fiddaman            used.]
188*b4dd7d09SAndy Fiddaman        [+UMASK \b[ \amask\a ]]?Run subsequent tests with \bumask\b(1)
189*b4dd7d09SAndy Fiddaman            \amask\a. If \amask\a is omitted then the original \bumask\b is
190*b4dd7d09SAndy Fiddaman            used.]
191*b4dd7d09SAndy Fiddaman        [+UNIT \b\acommand\a [ \aarg\a ... ]]?Define the command and
192*b4dd7d09SAndy Fiddaman            optional default arguments to be tested. \bUNIT\b explicitly
193*b4dd7d09SAndy Fiddaman            overrides the default command name derived from the test script
194*b4dd7d09SAndy Fiddaman            file name. A \acommand\a operand with optional arguments
195*b4dd7d09SAndy Fiddaman            overrides the \bUNIT\b \acommand\a and arguments, with the
196*b4dd7d09SAndy Fiddaman            exception that if the \bUNIT\b \acommand\a is \b-\b or \b+\b
197*b4dd7d09SAndy Fiddaman            the \bUNIT\b arguments are appended to the operand or default
198*b4dd7d09SAndy Fiddaman            unit command and arguments.]
199*b4dd7d09SAndy Fiddaman        [+VIEW \b\avar\a [ \afile\a ]]?\avar\a is set to the full
200*b4dd7d09SAndy Fiddaman            pathname of \avar\a [ \afile\a ]] in the current \b$VPATH\b
201*b4dd7d09SAndy Fiddaman            view if defined.]
202*b4dd7d09SAndy Fiddaman    }
203*b4dd7d09SAndy Fiddaman[+SEE ALSO?\bnmake\b(1), \bksh\b(1)]
204*b4dd7d09SAndy Fiddaman'
205*b4dd7d09SAndy Fiddaman	;;
206*b4dd7d09SAndy Fiddaman*)	USAGE='ko:[[no]name[=value]]t:[test]v unit [path [arg ...]]'
207*b4dd7d09SAndy Fiddaman	;;
208*b4dd7d09SAndy Fiddamanesac
209*b4dd7d09SAndy Fiddaman
210*b4dd7d09SAndy Fiddamanfunction FATAL # message
211*b4dd7d09SAndy Fiddaman{
212*b4dd7d09SAndy Fiddaman	print -r -u2 "$command: $*"
213*b4dd7d09SAndy Fiddaman	GROUP=FINI
214*b4dd7d09SAndy Fiddaman	exit 1
215*b4dd7d09SAndy Fiddaman}
216*b4dd7d09SAndy Fiddaman
217*b4dd7d09SAndy Fiddamanfunction EMPTY
218*b4dd7d09SAndy Fiddaman{
219*b4dd7d09SAndy Fiddaman	typeset i
220*b4dd7d09SAndy Fiddaman	typeset -n ARRAY=$1
221*b4dd7d09SAndy Fiddaman	for i in ${!ARRAY[@]}
222*b4dd7d09SAndy Fiddaman	do	unset ARRAY[$i]
223*b4dd7d09SAndy Fiddaman	done
224*b4dd7d09SAndy Fiddaman}
225*b4dd7d09SAndy Fiddaman
226*b4dd7d09SAndy Fiddamanfunction INITIALIZE # void
227*b4dd7d09SAndy Fiddaman{
228*b4dd7d09SAndy Fiddaman	typeset i j
229*b4dd7d09SAndy Fiddaman	cd "$TWD"
230*b4dd7d09SAndy Fiddaman	case $KEEP in
231*b4dd7d09SAndy Fiddaman	"")	RM *
232*b4dd7d09SAndy Fiddaman		;;
233*b4dd7d09SAndy Fiddaman	*)	for i in *
234*b4dd7d09SAndy Fiddaman		do	case $i in
235*b4dd7d09SAndy Fiddaman			!($KEEP))	j="$j $i" ;;
236*b4dd7d09SAndy Fiddaman			esac
237*b4dd7d09SAndy Fiddaman		done
238*b4dd7d09SAndy Fiddaman		case $j in
239*b4dd7d09SAndy Fiddaman		?*)	RM $j ;;
240*b4dd7d09SAndy Fiddaman		esac
241*b4dd7d09SAndy Fiddaman		;;
242*b4dd7d09SAndy Fiddaman	esac
243*b4dd7d09SAndy Fiddaman	: >INPUT >OUTPUT.ex >ERROR.ex
244*b4dd7d09SAndy Fiddaman	BODY=""
245*b4dd7d09SAndy Fiddaman	COPY=""
246*b4dd7d09SAndy Fiddaman	DIAGNOSTICS=""
247*b4dd7d09SAndy Fiddaman	DONE=""
248*b4dd7d09SAndy Fiddaman	ERROR=""
249*b4dd7d09SAndy Fiddaman	EXIT=0
250*b4dd7d09SAndy Fiddaman	IGNORE=""
251*b4dd7d09SAndy Fiddaman	INIT=""
252*b4dd7d09SAndy Fiddaman	INPUT=""
253*b4dd7d09SAndy Fiddaman	MOVE=""
254*b4dd7d09SAndy Fiddaman	OUTPUT=""
255*b4dd7d09SAndy Fiddaman	EMPTY FILE
256*b4dd7d09SAndy Fiddaman	EMPTY FILTER
257*b4dd7d09SAndy Fiddaman	EMPTY SAME
258*b4dd7d09SAndy Fiddaman	EMPTY TYPE
259*b4dd7d09SAndy Fiddaman}
260*b4dd7d09SAndy Fiddaman
261*b4dd7d09SAndy Fiddamanfunction INTRO
262*b4dd7d09SAndy Fiddaman{
263*b4dd7d09SAndy Fiddaman	typeset base command
264*b4dd7d09SAndy Fiddaman
265*b4dd7d09SAndy Fiddaman	if	[[ ! $TEST_quiet ]]
266*b4dd7d09SAndy Fiddaman	then	base=${REGRESS##*/}
267*b4dd7d09SAndy Fiddaman		base=${base%.tst}
268*b4dd7d09SAndy Fiddaman		command=${COMMAND##*/}
269*b4dd7d09SAndy Fiddaman		command=${command%' '*}
270*b4dd7d09SAndy Fiddaman		set -- $TITLE
271*b4dd7d09SAndy Fiddaman		TITLE=
272*b4dd7d09SAndy Fiddaman		case $1 in
273*b4dd7d09SAndy Fiddaman		''|+)	if	[[ $command == $base ]]
274*b4dd7d09SAndy Fiddaman			then	TITLE=$COMMAND
275*b4dd7d09SAndy Fiddaman			else	TITLE="$COMMAND, $base"
276*b4dd7d09SAndy Fiddaman			fi
277*b4dd7d09SAndy Fiddaman			if	(( $# ))
278*b4dd7d09SAndy Fiddaman			then	shift
279*b4dd7d09SAndy Fiddaman			fi
280*b4dd7d09SAndy Fiddaman			;;
281*b4dd7d09SAndy Fiddaman		esac
282*b4dd7d09SAndy Fiddaman		while	(( $# ))
283*b4dd7d09SAndy Fiddaman		do	if	[[ $TITLE ]]
284*b4dd7d09SAndy Fiddaman			then	TITLE="$TITLE, $1"
285*b4dd7d09SAndy Fiddaman			else	TITLE="$1"
286*b4dd7d09SAndy Fiddaman			fi
287*b4dd7d09SAndy Fiddaman			shift
288*b4dd7d09SAndy Fiddaman		done
289*b4dd7d09SAndy Fiddaman		print -u2 "TEST	$TITLE"
290*b4dd7d09SAndy Fiddaman	fi
291*b4dd7d09SAndy Fiddaman}
292*b4dd7d09SAndy Fiddaman
293*b4dd7d09SAndy Fiddamanfunction TALLY # extra message text
294*b4dd7d09SAndy Fiddaman{
295*b4dd7d09SAndy Fiddaman	typeset msg
296*b4dd7d09SAndy Fiddaman	case $GROUP in
297*b4dd7d09SAndy Fiddaman	INIT)	;;
298*b4dd7d09SAndy Fiddaman	*)	msg="TEST	$TITLE, $TESTS test"
299*b4dd7d09SAndy Fiddaman		case $TESTS in
300*b4dd7d09SAndy Fiddaman		1)	;;
301*b4dd7d09SAndy Fiddaman		*)	msg=${msg}s ;;
302*b4dd7d09SAndy Fiddaman		esac
303*b4dd7d09SAndy Fiddaman		msg="$msg, $ERRORS error"
304*b4dd7d09SAndy Fiddaman		case $ERRORS in
305*b4dd7d09SAndy Fiddaman		1)	;;
306*b4dd7d09SAndy Fiddaman		*)	msg=${msg}s ;;
307*b4dd7d09SAndy Fiddaman		esac
308*b4dd7d09SAndy Fiddaman		if	(( $# ))
309*b4dd7d09SAndy Fiddaman		then	msg="$msg, $*"
310*b4dd7d09SAndy Fiddaman		fi
311*b4dd7d09SAndy Fiddaman		print -u2 "$msg"
312*b4dd7d09SAndy Fiddaman		GROUP=INIT
313*b4dd7d09SAndy Fiddaman		TESTS=0
314*b4dd7d09SAndy Fiddaman		ERRORS=0
315*b4dd7d09SAndy Fiddaman		;;
316*b4dd7d09SAndy Fiddaman	esac
317*b4dd7d09SAndy Fiddaman}
318*b4dd7d09SAndy Fiddaman
319*b4dd7d09SAndy Fiddamanfunction TITLE # text
320*b4dd7d09SAndy Fiddaman{
321*b4dd7d09SAndy Fiddaman	TITLE=$@
322*b4dd7d09SAndy Fiddaman}
323*b4dd7d09SAndy Fiddaman
324*b4dd7d09SAndy Fiddamanfunction UNWIND
325*b4dd7d09SAndy Fiddaman{
326*b4dd7d09SAndy Fiddaman	while	(( COND > 1 ))
327*b4dd7d09SAndy Fiddaman	do	print -r -u2 "$command: line $LINE: no matching FI for IF on line ${COND_LINE[COND]}"
328*b4dd7d09SAndy Fiddaman		(( COND-- ))
329*b4dd7d09SAndy Fiddaman	done
330*b4dd7d09SAndy Fiddaman	if	(( COND > 0 ))
331*b4dd7d09SAndy Fiddaman	then	(( COND = 0 ))
332*b4dd7d09SAndy Fiddaman		FATAL "line $LINE: no matching FI for IF on line ${COND_LINE[COND+1]}"
333*b4dd7d09SAndy Fiddaman	fi
334*b4dd7d09SAndy Fiddaman	if	[[ $JOBPID ]]
335*b4dd7d09SAndy Fiddaman	then	if	[[ $JOBPID != 0 ]]
336*b4dd7d09SAndy Fiddaman		then	kill -KILL $JOBPID 2>/dev/null
337*b4dd7d09SAndy Fiddaman			wait
338*b4dd7d09SAndy Fiddaman		fi
339*b4dd7d09SAndy Fiddaman		JOBPID=
340*b4dd7d09SAndy Fiddaman	fi
341*b4dd7d09SAndy Fiddaman	JOBSTATUS=
342*b4dd7d09SAndy Fiddaman	JOBOP=
343*b4dd7d09SAndy Fiddaman	wait
344*b4dd7d09SAndy Fiddaman}
345*b4dd7d09SAndy Fiddaman
346*b4dd7d09SAndy Fiddamanfunction CLEANUP # status
347*b4dd7d09SAndy Fiddaman{
348*b4dd7d09SAndy Fiddaman	typeset note
349*b4dd7d09SAndy Fiddaman
350*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != INIT ]]
351*b4dd7d09SAndy Fiddaman	then	if	[[ ! $TEST_keep ]]
352*b4dd7d09SAndy Fiddaman		then	cd $SOURCE
353*b4dd7d09SAndy Fiddaman			if	[[ $TEST_local ]]
354*b4dd7d09SAndy Fiddaman			then	RM ${TEST_local}
355*b4dd7d09SAndy Fiddaman			fi
356*b4dd7d09SAndy Fiddaman			RM "$TWD"
357*b4dd7d09SAndy Fiddaman		fi
358*b4dd7d09SAndy Fiddaman		if	(( $1 )) && [[ $GROUP != FINI ]]
359*b4dd7d09SAndy Fiddaman		then	note=terminated
360*b4dd7d09SAndy Fiddaman		fi
361*b4dd7d09SAndy Fiddaman	fi
362*b4dd7d09SAndy Fiddaman	TALLY $note
363*b4dd7d09SAndy Fiddaman	[[ $TEST_keep ]] || UNWIND
364*b4dd7d09SAndy Fiddaman	exit $1
365*b4dd7d09SAndy Fiddaman}
366*b4dd7d09SAndy Fiddaman
367*b4dd7d09SAndy Fiddamanfunction RUN # [ op ]
368*b4dd7d09SAndy Fiddaman{
369*b4dd7d09SAndy Fiddaman	typeset i r=1
370*b4dd7d09SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
371*b4dd7d09SAndy Fiddaman#print -u2 AHA#$LINENO $0 GROUP=$GROUP ITEM=$ITEM FLUSHED=$FLUSHED JOBOP=$JOBOP
372*b4dd7d09SAndy Fiddaman	case $GROUP in
373*b4dd7d09SAndy Fiddaman	INIT)	RM "$TWD"
374*b4dd7d09SAndy Fiddaman		if	[[ $TEST_local ]]
375*b4dd7d09SAndy Fiddaman		then	TEST_local=${TMPDIR:-/tmp}/rt-$$/${TWD##*/}
376*b4dd7d09SAndy Fiddaman			mkdir -p "$TEST_local" && ln -s "$TEST_local" "$TWD" || FATAL "$TWD": cannot create directory
377*b4dd7d09SAndy Fiddaman			TEST_local=${TEST_local%/*}
378*b4dd7d09SAndy Fiddaman		else	mkdir "$TWD" || FATAL "$TWD": cannot create directory
379*b4dd7d09SAndy Fiddaman		fi
380*b4dd7d09SAndy Fiddaman		cd "$TWD"
381*b4dd7d09SAndy Fiddaman		TWD=$PWD
382*b4dd7d09SAndy Fiddaman		: > rmu
383*b4dd7d09SAndy Fiddaman		if	rm -u rmu >/dev/null 2>&1
384*b4dd7d09SAndy Fiddaman		then	TEST_rmu=-u
385*b4dd7d09SAndy Fiddaman		else	rm rmu
386*b4dd7d09SAndy Fiddaman		fi
387*b4dd7d09SAndy Fiddaman		if	[[ $UNIT ]]
388*b4dd7d09SAndy Fiddaman		then	set -- "${ARGV[@]}"
389*b4dd7d09SAndy Fiddaman			case $1 in
390*b4dd7d09SAndy Fiddaman			""|[-+]*)
391*b4dd7d09SAndy Fiddaman				UNIT $UNIT "${ARGV[@]}"
392*b4dd7d09SAndy Fiddaman				;;
393*b4dd7d09SAndy Fiddaman			*)	UNIT "${ARGV[@]}"
394*b4dd7d09SAndy Fiddaman				;;
395*b4dd7d09SAndy Fiddaman			esac
396*b4dd7d09SAndy Fiddaman		fi
397*b4dd7d09SAndy Fiddaman		INTRO
398*b4dd7d09SAndy Fiddaman		;;
399*b4dd7d09SAndy Fiddaman	FINI)	;;
400*b4dd7d09SAndy Fiddaman	$TEST_select)
401*b4dd7d09SAndy Fiddaman		if	[[ $ITEM == $FLUSHED ]]
402*b4dd7d09SAndy Fiddaman		then	return 0
403*b4dd7d09SAndy Fiddaman		fi
404*b4dd7d09SAndy Fiddaman		FLUSHED=$ITEM
405*b4dd7d09SAndy Fiddaman		if	(( COND_SKIP[COND] ))
406*b4dd7d09SAndy Fiddaman		then	return 1
407*b4dd7d09SAndy Fiddaman		fi
408*b4dd7d09SAndy Fiddaman		((COUNT++))
409*b4dd7d09SAndy Fiddaman		if	(( $ITEM <= $LASTITEM ))
410*b4dd7d09SAndy Fiddaman		then	LABEL=$TEST#$COUNT
411*b4dd7d09SAndy Fiddaman		else	LASTITEM=$ITEM
412*b4dd7d09SAndy Fiddaman			LABEL=$TEST:$ITEM
413*b4dd7d09SAndy Fiddaman		fi
414*b4dd7d09SAndy Fiddaman		TEST_file=""
415*b4dd7d09SAndy Fiddaman		exec >/dev/null
416*b4dd7d09SAndy Fiddaman		for i in $INPUT
417*b4dd7d09SAndy Fiddaman		do	case " $OUTPUT " in
418*b4dd7d09SAndy Fiddaman			*" $i "*)
419*b4dd7d09SAndy Fiddaman				if	[[ -f $i.sav ]]
420*b4dd7d09SAndy Fiddaman				then	cp $i.sav $i
421*b4dd7d09SAndy Fiddaman					COMPARE="$COMPARE $i"
422*b4dd7d09SAndy Fiddaman				elif	[[ -f $i ]]
423*b4dd7d09SAndy Fiddaman				then	cp $i $i.sav
424*b4dd7d09SAndy Fiddaman					COMPARE="$COMPARE $i"
425*b4dd7d09SAndy Fiddaman				fi
426*b4dd7d09SAndy Fiddaman				;;
427*b4dd7d09SAndy Fiddaman			esac
428*b4dd7d09SAndy Fiddaman		done
429*b4dd7d09SAndy Fiddaman		for i in $OUTPUT
430*b4dd7d09SAndy Fiddaman		do	case " $COMPARE " in
431*b4dd7d09SAndy Fiddaman			*" $i "*)
432*b4dd7d09SAndy Fiddaman				;;
433*b4dd7d09SAndy Fiddaman			*)	COMPARE="$COMPARE $i"
434*b4dd7d09SAndy Fiddaman				;;
435*b4dd7d09SAndy Fiddaman			esac
436*b4dd7d09SAndy Fiddaman		done
437*b4dd7d09SAndy Fiddaman		for i in $INIT
438*b4dd7d09SAndy Fiddaman		do	$i $TEST INIT
439*b4dd7d09SAndy Fiddaman		done
440*b4dd7d09SAndy Fiddaman#print -u2 AHA#$LINENO $0 GROUP=$GROUP ITEM=$ITEM JOBOP=$JOBOP JOBPID=$JOBPID JOBSTATUS=$JOBSTATUS
441*b4dd7d09SAndy Fiddaman		if	[[ $JOBPID != 0 && ( $JOBPID || $JOBSTATUS ) ]]
442*b4dd7d09SAndy Fiddaman		then	if	[[ ! $TEST_quiet ]]
443*b4dd7d09SAndy Fiddaman			then	print -nu2 "$LABEL"
444*b4dd7d09SAndy Fiddaman			fi
445*b4dd7d09SAndy Fiddaman			RESULTS
446*b4dd7d09SAndy Fiddaman		elif	[[ $BODY ]]
447*b4dd7d09SAndy Fiddaman		then	SHOW=$NOTE
448*b4dd7d09SAndy Fiddaman			if	[[ ! $TEST_quiet ]]
449*b4dd7d09SAndy Fiddaman			then	print -r -u2 "	$SHOW"
450*b4dd7d09SAndy Fiddaman			fi
451*b4dd7d09SAndy Fiddaman			for i in $BODY
452*b4dd7d09SAndy Fiddaman			do	$i $TEST BODY
453*b4dd7d09SAndy Fiddaman			done
454*b4dd7d09SAndy Fiddaman		else	SHOW=
455*b4dd7d09SAndy Fiddaman			if	[[ ${TYPE[INPUT]} == PIPE ]]
456*b4dd7d09SAndy Fiddaman			then	if	[[ ${TYPE[OUTPUT]} == PIPE ]]
457*b4dd7d09SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
458*b4dd7d09SAndy Fiddaman					then	print -nu2 "$LABEL"
459*b4dd7d09SAndy Fiddaman					fi
460*b4dd7d09SAndy Fiddaman					cat <$TWD/INPUT | COMMAND "${ARGS[@]}" | cat >$TWD/OUTPUT
461*b4dd7d09SAndy Fiddaman					RESULTS 'pipe input'
462*b4dd7d09SAndy Fiddaman				else	if	[[ ! $TEST_quiet ]]
463*b4dd7d09SAndy Fiddaman					then	print -nu2 "$LABEL"
464*b4dd7d09SAndy Fiddaman					fi
465*b4dd7d09SAndy Fiddaman					cat <$TWD/INPUT | COMMAND "${ARGS[@]}" >$TWD/OUTPUT
466*b4dd7d09SAndy Fiddaman					RESULTS 'pipe io'
467*b4dd7d09SAndy Fiddaman				fi
468*b4dd7d09SAndy Fiddaman			elif	[[ ${TYPE[OUTPUT]} == PIPE ]]
469*b4dd7d09SAndy Fiddaman			then	if	[[ ! $TEST_quiet ]]
470*b4dd7d09SAndy Fiddaman				then	print -nu2 "$LABEL"
471*b4dd7d09SAndy Fiddaman				fi
472*b4dd7d09SAndy Fiddaman				COMMAND "${ARGS[@]}" <$TWD/INPUT | cat >$TWD/OUTPUT
473*b4dd7d09SAndy Fiddaman				RESULTS 'pipe output'
474*b4dd7d09SAndy Fiddaman			else	if	[[ $TEST_regular ]]
475*b4dd7d09SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
476*b4dd7d09SAndy Fiddaman					then	print -nu2 "$LABEL"
477*b4dd7d09SAndy Fiddaman					fi
478*b4dd7d09SAndy Fiddaman					if	[[ ${TYPE[INPUT]} == FIFO ]]
479*b4dd7d09SAndy Fiddaman					then	COMMAND "${ARGS[@]}" >$TWD/OUTPUT
480*b4dd7d09SAndy Fiddaman					else	COMMAND "${ARGS[@]}" <$TWD/INPUT >$TWD/OUTPUT
481*b4dd7d09SAndy Fiddaman					fi
482*b4dd7d09SAndy Fiddaman					RESULTS
483*b4dd7d09SAndy Fiddaman				fi
484*b4dd7d09SAndy Fiddaman				if	[[ $TEST_pipe_input ]]
485*b4dd7d09SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
486*b4dd7d09SAndy Fiddaman					then	print -nu2 "$LABEL"
487*b4dd7d09SAndy Fiddaman					fi
488*b4dd7d09SAndy Fiddaman					(trap '' PIPE; cat <$TWD/INPUT 2>/dev/null; exit 0) | COMMAND "${ARGS[@]}" >$TWD/OUTPUT
489*b4dd7d09SAndy Fiddaman					STATUS=$?
490*b4dd7d09SAndy Fiddaman					RESULTS 'pipe input'
491*b4dd7d09SAndy Fiddaman				fi
492*b4dd7d09SAndy Fiddaman				if	[[ $TEST_pipe_output ]]
493*b4dd7d09SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
494*b4dd7d09SAndy Fiddaman					then	print -nu2 "$LABEL"
495*b4dd7d09SAndy Fiddaman					fi
496*b4dd7d09SAndy Fiddaman					COMMAND "${ARGS[@]}" <$TWD/INPUT | cat >$TWD/OUTPUT
497*b4dd7d09SAndy Fiddaman					STATUS=$?
498*b4dd7d09SAndy Fiddaman					RESULTS 'pipe output'
499*b4dd7d09SAndy Fiddaman				fi
500*b4dd7d09SAndy Fiddaman				if	[[ $TEST_pipe_io ]]
501*b4dd7d09SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
502*b4dd7d09SAndy Fiddaman					then	print -nu2 "$LABEL"
503*b4dd7d09SAndy Fiddaman					fi
504*b4dd7d09SAndy Fiddaman					(trap '' PIPE; cat <$TWD/INPUT 2>/dev/null; exit 0) | COMMAND "${ARGS[@]}" | cat >$TWD/OUTPUT
505*b4dd7d09SAndy Fiddaman					STATUS=$?
506*b4dd7d09SAndy Fiddaman					RESULTS 'pipe io'
507*b4dd7d09SAndy Fiddaman				fi
508*b4dd7d09SAndy Fiddaman			fi
509*b4dd7d09SAndy Fiddaman			set -- $COPY
510*b4dd7d09SAndy Fiddaman			COPY=""
511*b4dd7d09SAndy Fiddaman			while	:
512*b4dd7d09SAndy Fiddaman			do	case $# in
513*b4dd7d09SAndy Fiddaman				0|1)	break ;;
514*b4dd7d09SAndy Fiddaman				*)	cp $1 $2 ;;
515*b4dd7d09SAndy Fiddaman				esac
516*b4dd7d09SAndy Fiddaman				shift 2
517*b4dd7d09SAndy Fiddaman			done
518*b4dd7d09SAndy Fiddaman			set -- $MOVE
519*b4dd7d09SAndy Fiddaman			MOVE=""
520*b4dd7d09SAndy Fiddaman			while	(( $# > 1 ))
521*b4dd7d09SAndy Fiddaman			do	mv $1 $2
522*b4dd7d09SAndy Fiddaman				shift 2
523*b4dd7d09SAndy Fiddaman			done
524*b4dd7d09SAndy Fiddaman		fi
525*b4dd7d09SAndy Fiddaman		for i in $DONE
526*b4dd7d09SAndy Fiddaman		do	$i $TEST DONE $STATUS
527*b4dd7d09SAndy Fiddaman		done
528*b4dd7d09SAndy Fiddaman		COMPARE=""
529*b4dd7d09SAndy Fiddaman		r=0
530*b4dd7d09SAndy Fiddaman		;;
531*b4dd7d09SAndy Fiddaman	esac
532*b4dd7d09SAndy Fiddaman	if	[[ $COMMAND_ORIG ]]
533*b4dd7d09SAndy Fiddaman	then	COMMAND=$COMMAND_ORIG
534*b4dd7d09SAndy Fiddaman		COMMAND_ORIG=
535*b4dd7d09SAndy Fiddaman		ARGS=(${ARGS_ORIG[@]})
536*b4dd7d09SAndy Fiddaman	fi
537*b4dd7d09SAndy Fiddaman	return $r
538*b4dd7d09SAndy Fiddaman}
539*b4dd7d09SAndy Fiddaman
540*b4dd7d09SAndy Fiddamanfunction DO # cmd ...
541*b4dd7d09SAndy Fiddaman{
542*b4dd7d09SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return 1
543*b4dd7d09SAndy Fiddaman	(( COND_SKIP[COND] )) && return 1
544*b4dd7d09SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK
545*b4dd7d09SAndy Fiddaman	return 0
546*b4dd7d09SAndy Fiddaman}
547*b4dd7d09SAndy Fiddaman
548*b4dd7d09SAndy Fiddamanfunction UNIT # cmd arg ...
549*b4dd7d09SAndy Fiddaman{
550*b4dd7d09SAndy Fiddaman	typeset cmd=$1
551*b4dd7d09SAndy Fiddaman	case $cmd in
552*b4dd7d09SAndy Fiddaman	[-+])	shift
553*b4dd7d09SAndy Fiddaman		if	(( UNIT_READONLY ))
554*b4dd7d09SAndy Fiddaman		then	COMMAND="$COMMAND $*"
555*b4dd7d09SAndy Fiddaman		else	#BUG# ARGV=("${ARGV[@]}" "$@")
556*b4dd7d09SAndy Fiddaman			set -- "${ARGV[@]}" "$@"
557*b4dd7d09SAndy Fiddaman			ARGV=("$@")
558*b4dd7d09SAndy Fiddaman		fi
559*b4dd7d09SAndy Fiddaman		return
560*b4dd7d09SAndy Fiddaman		;;
561*b4dd7d09SAndy Fiddaman	esac
562*b4dd7d09SAndy Fiddaman	(( UNIT_READONLY )) && return
563*b4dd7d09SAndy Fiddaman	if	[[ $UNIT ]] && (( $# <= 1 ))
564*b4dd7d09SAndy Fiddaman	then	set -- "${ARGV[@]}"
565*b4dd7d09SAndy Fiddaman		case $1 in
566*b4dd7d09SAndy Fiddaman		"")	set -- "$cmd" ;;
567*b4dd7d09SAndy Fiddaman		[-+]*)	set -- "$cmd" "${ARGV[@]}" ;;
568*b4dd7d09SAndy Fiddaman		*)	cmd=$1 ;;
569*b4dd7d09SAndy Fiddaman		esac
570*b4dd7d09SAndy Fiddaman	fi
571*b4dd7d09SAndy Fiddaman	UNIT=
572*b4dd7d09SAndy Fiddaman	COMMAND=$cmd
573*b4dd7d09SAndy Fiddaman	shift
574*b4dd7d09SAndy Fiddaman	typeset cmd=$(whence $COMMAND)
575*b4dd7d09SAndy Fiddaman	if	[[ ! $cmd ]]
576*b4dd7d09SAndy Fiddaman	then	FATAL $COMMAND: not found
577*b4dd7d09SAndy Fiddaman	elif	[[ ! $cmd ]]
578*b4dd7d09SAndy Fiddaman	then	FATAL $cmd: not found
579*b4dd7d09SAndy Fiddaman	fi
580*b4dd7d09SAndy Fiddaman	case $# in
581*b4dd7d09SAndy Fiddaman	0)	;;
582*b4dd7d09SAndy Fiddaman	*)	COMMAND="$COMMAND $*" ;;
583*b4dd7d09SAndy Fiddaman	esac
584*b4dd7d09SAndy Fiddaman}
585*b4dd7d09SAndy Fiddaman
586*b4dd7d09SAndy Fiddamanfunction TWD # [ dir ]
587*b4dd7d09SAndy Fiddaman{
588*b4dd7d09SAndy Fiddaman	case $1 in
589*b4dd7d09SAndy Fiddaman	'')	TWD=${TWD##*/}; TWD=${TMPDIR:-/tmp}/tst-${TWD%.*}-$$-$RANDOM ;;
590*b4dd7d09SAndy Fiddaman	/*)	TWD=$1 ;;
591*b4dd7d09SAndy Fiddaman	*)	TWD=${TMPDIR:-/tmp}/$1 ;;
592*b4dd7d09SAndy Fiddaman	esac
593*b4dd7d09SAndy Fiddaman}
594*b4dd7d09SAndy Fiddaman
595*b4dd7d09SAndy Fiddamanfunction TEST # number description arg ...
596*b4dd7d09SAndy Fiddaman{
597*b4dd7d09SAndy Fiddaman	RUN
598*b4dd7d09SAndy Fiddaman	LINE=$TESTLINE
599*b4dd7d09SAndy Fiddaman	UNWIND
600*b4dd7d09SAndy Fiddaman	COUNT=0
601*b4dd7d09SAndy Fiddaman	LASTITEM=0
602*b4dd7d09SAndy Fiddaman	case $1 in
603*b4dd7d09SAndy Fiddaman	-)		((LAST++)); TEST=$LAST ;;
604*b4dd7d09SAndy Fiddaman	+([0123456789]))	LAST=$1 TEST=$1 ;;
605*b4dd7d09SAndy Fiddaman	*)		LAST=0${1/[!0123456789]/} TEST=$1 ;;
606*b4dd7d09SAndy Fiddaman	esac
607*b4dd7d09SAndy Fiddaman	NOTE=
608*b4dd7d09SAndy Fiddaman	if	[[ ! $TEST_quiet && $TEST == $TEST_select ]] && (( ! COND_SKIP[COND] ))
609*b4dd7d09SAndy Fiddaman	then	print -r -u2 "$TEST	$2"
610*b4dd7d09SAndy Fiddaman	fi
611*b4dd7d09SAndy Fiddaman	unset ARGS
612*b4dd7d09SAndy Fiddaman	unset EXPORT
613*b4dd7d09SAndy Fiddaman	EXPORTS=0
614*b4dd7d09SAndy Fiddaman	TEST_file=""
615*b4dd7d09SAndy Fiddaman	if	[[ $TEST != ${GROUP}* ]]
616*b4dd7d09SAndy Fiddaman	then	GROUP=${TEST%%+([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ])}
617*b4dd7d09SAndy Fiddaman		if	[[ $GROUP == $TEST_select ]] && (( ! COND_SKIP[COND] ))
618*b4dd7d09SAndy Fiddaman		then	INITIALIZE
619*b4dd7d09SAndy Fiddaman		fi
620*b4dd7d09SAndy Fiddaman	fi
621*b4dd7d09SAndy Fiddaman	((SUBTESTS=0))
622*b4dd7d09SAndy Fiddaman	[[ $TEST == $TEST_select ]] && (( ! COND_SKIP[COND] ))
623*b4dd7d09SAndy Fiddaman}
624*b4dd7d09SAndy Fiddaman
625*b4dd7d09SAndy Fiddamanfunction EXEC # arg ...
626*b4dd7d09SAndy Fiddaman{
627*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
628*b4dd7d09SAndy Fiddaman	then	return
629*b4dd7d09SAndy Fiddaman	fi
630*b4dd7d09SAndy Fiddaman	if	((SUBTESTS++))
631*b4dd7d09SAndy Fiddaman	then	RUN
632*b4dd7d09SAndy Fiddaman	fi
633*b4dd7d09SAndy Fiddaman	case $# in
634*b4dd7d09SAndy Fiddaman	0)	set -- "${ARGS[@]}" ;;
635*b4dd7d09SAndy Fiddaman	esac
636*b4dd7d09SAndy Fiddaman	ITEM=$LINE
637*b4dd7d09SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $COMMAND_ORIG "$@")${JOBPID:+&}"
638*b4dd7d09SAndy Fiddaman	ARGS=("$@")
639*b4dd7d09SAndy Fiddaman}
640*b4dd7d09SAndy Fiddaman
641*b4dd7d09SAndy Fiddamanfunction JOB # arg ...
642*b4dd7d09SAndy Fiddaman{
643*b4dd7d09SAndy Fiddaman	JOBPID=0
644*b4dd7d09SAndy Fiddaman	EXEC "$@"
645*b4dd7d09SAndy Fiddaman}
646*b4dd7d09SAndy Fiddaman
647*b4dd7d09SAndy Fiddamanfunction CONTINUE
648*b4dd7d09SAndy Fiddaman{
649*b4dd7d09SAndy Fiddaman	RUN || return
650*b4dd7d09SAndy Fiddaman	JOBOP=CONTINUE
651*b4dd7d09SAndy Fiddaman	ITEM=$LINE
652*b4dd7d09SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $JOBOP)"
653*b4dd7d09SAndy Fiddaman#print -u2 AHA#$LINENO JOBOP=$JOBOP ITEM=$ITEM NOTE=$NOTE
654*b4dd7d09SAndy Fiddaman}
655*b4dd7d09SAndy Fiddaman
656*b4dd7d09SAndy Fiddamanfunction EXITED
657*b4dd7d09SAndy Fiddaman{
658*b4dd7d09SAndy Fiddaman	RUN || return
659*b4dd7d09SAndy Fiddaman	JOBOP=EXITED
660*b4dd7d09SAndy Fiddaman	ITEM=$LINE
661*b4dd7d09SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $JOBOP)"
662*b4dd7d09SAndy Fiddaman#print -u2 AHA#$LINENO JOBOP=$JOBOP ITEM=$ITEM NOTE=$NOTE
663*b4dd7d09SAndy Fiddaman}
664*b4dd7d09SAndy Fiddaman
665*b4dd7d09SAndy Fiddamanfunction KILL # [ signal ]
666*b4dd7d09SAndy Fiddaman{
667*b4dd7d09SAndy Fiddaman	RUN || return
668*b4dd7d09SAndy Fiddaman	JOBOP=$2
669*b4dd7d09SAndy Fiddaman	[[ $JOBOP ]] || JOBOP=KILL
670*b4dd7d09SAndy Fiddaman	ITEM=$LINE
671*b4dd7d09SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $JOBOP)"
672*b4dd7d09SAndy Fiddaman}
673*b4dd7d09SAndy Fiddaman
674*b4dd7d09SAndy Fiddamanfunction CD
675*b4dd7d09SAndy Fiddaman{
676*b4dd7d09SAndy Fiddaman	RUN
677*b4dd7d09SAndy Fiddaman	if	[[ $GROUP == $TEST_select ]] && (( ! COND_SKIP[COND] ))
678*b4dd7d09SAndy Fiddaman	then	mkdir -p "$@" && cd "$@" || FATAL cannot initialize working directory "$@"
679*b4dd7d09SAndy Fiddaman	fi
680*b4dd7d09SAndy Fiddaman}
681*b4dd7d09SAndy Fiddaman
682*b4dd7d09SAndy Fiddamanfunction EXPORT
683*b4dd7d09SAndy Fiddaman{
684*b4dd7d09SAndy Fiddaman	typeset x n v
685*b4dd7d09SAndy Fiddaman	if	[[ $GROUP == INIT ]]
686*b4dd7d09SAndy Fiddaman	then	for x
687*b4dd7d09SAndy Fiddaman		do	n=${x%%=*}
688*b4dd7d09SAndy Fiddaman			v=${x#*=}
689*b4dd7d09SAndy Fiddaman			ENVIRON[ENVIRONS++]=$n="'$v'"
690*b4dd7d09SAndy Fiddaman		done
691*b4dd7d09SAndy Fiddaman	else	RUN
692*b4dd7d09SAndy Fiddaman		if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
693*b4dd7d09SAndy Fiddaman		then	return
694*b4dd7d09SAndy Fiddaman		fi
695*b4dd7d09SAndy Fiddaman		for x
696*b4dd7d09SAndy Fiddaman		do	n=${x%%=*}
697*b4dd7d09SAndy Fiddaman			v=${x#*=}
698*b4dd7d09SAndy Fiddaman			EXPORT[EXPORTS++]=$n="'$v'"
699*b4dd7d09SAndy Fiddaman		done
700*b4dd7d09SAndy Fiddaman	fi
701*b4dd7d09SAndy Fiddaman}
702*b4dd7d09SAndy Fiddaman
703*b4dd7d09SAndy Fiddamanfunction FLUSH
704*b4dd7d09SAndy Fiddaman{
705*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
706*b4dd7d09SAndy Fiddaman	then	return
707*b4dd7d09SAndy Fiddaman	fi
708*b4dd7d09SAndy Fiddaman	if	((SUBTESTS++))
709*b4dd7d09SAndy Fiddaman	then	RUN
710*b4dd7d09SAndy Fiddaman	fi
711*b4dd7d09SAndy Fiddaman}
712*b4dd7d09SAndy Fiddaman
713*b4dd7d09SAndy Fiddamanfunction PROG # cmd arg ...
714*b4dd7d09SAndy Fiddaman{
715*b4dd7d09SAndy Fiddaman	typeset command args
716*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
717*b4dd7d09SAndy Fiddaman	then	return
718*b4dd7d09SAndy Fiddaman	fi
719*b4dd7d09SAndy Fiddaman	ITEM=$LINE
720*b4dd7d09SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- "$@")"
721*b4dd7d09SAndy Fiddaman	COMMAND_ORIG=$COMMAND
722*b4dd7d09SAndy Fiddaman	COMMAND=$1
723*b4dd7d09SAndy Fiddaman	shift
724*b4dd7d09SAndy Fiddaman	ARGS_ORIG=(${ARGS[@]})
725*b4dd7d09SAndy Fiddaman	ARGS=("$@")
726*b4dd7d09SAndy Fiddaman}
727*b4dd7d09SAndy Fiddaman
728*b4dd7d09SAndy Fiddamanfunction NOTE # description
729*b4dd7d09SAndy Fiddaman{
730*b4dd7d09SAndy Fiddaman	NOTE=$*
731*b4dd7d09SAndy Fiddaman}
732*b4dd7d09SAndy Fiddaman
733*b4dd7d09SAndy Fiddamanfunction IO # [ PIPE ] INPUT|OUTPUT|ERROR [-f*|-n] file|- data ...
734*b4dd7d09SAndy Fiddaman{
735*b4dd7d09SAndy Fiddaman	typeset op i v f file type x
736*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
737*b4dd7d09SAndy Fiddaman	then	return
738*b4dd7d09SAndy Fiddaman	fi
739*b4dd7d09SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
740*b4dd7d09SAndy Fiddaman	while	:
741*b4dd7d09SAndy Fiddaman	do	case $1 in
742*b4dd7d09SAndy Fiddaman		FIFO|PIPE)	type=$1; shift ;;
743*b4dd7d09SAndy Fiddaman		*)		break ;;
744*b4dd7d09SAndy Fiddaman		esac
745*b4dd7d09SAndy Fiddaman	done
746*b4dd7d09SAndy Fiddaman	op=$1
747*b4dd7d09SAndy Fiddaman	shift
748*b4dd7d09SAndy Fiddaman	[[ $type ]] && TYPE[$op]=$type
749*b4dd7d09SAndy Fiddaman	FILTER[$op]=
750*b4dd7d09SAndy Fiddaman	file=$TWD/$op
751*b4dd7d09SAndy Fiddaman	while	:
752*b4dd7d09SAndy Fiddaman	do	case $1 in
753*b4dd7d09SAndy Fiddaman		-x)	x=1
754*b4dd7d09SAndy Fiddaman			shift
755*b4dd7d09SAndy Fiddaman			;;
756*b4dd7d09SAndy Fiddaman		-e)	(( $# > 1 )) && shift
757*b4dd7d09SAndy Fiddaman			FILTER[$op]=$1
758*b4dd7d09SAndy Fiddaman			shift
759*b4dd7d09SAndy Fiddaman			;;
760*b4dd7d09SAndy Fiddaman		-e*)	FILTER[$op]=${1#-e}
761*b4dd7d09SAndy Fiddaman			shift
762*b4dd7d09SAndy Fiddaman			;;
763*b4dd7d09SAndy Fiddaman		-f*|-n)	f=$1
764*b4dd7d09SAndy Fiddaman			shift
765*b4dd7d09SAndy Fiddaman			;;
766*b4dd7d09SAndy Fiddaman		*)	break
767*b4dd7d09SAndy Fiddaman			;;
768*b4dd7d09SAndy Fiddaman		esac
769*b4dd7d09SAndy Fiddaman	done
770*b4dd7d09SAndy Fiddaman	case $# in
771*b4dd7d09SAndy Fiddaman	0)	;;
772*b4dd7d09SAndy Fiddaman	*)	case $1 in
773*b4dd7d09SAndy Fiddaman		-)	;;
774*b4dd7d09SAndy Fiddaman		*)	file=$1
775*b4dd7d09SAndy Fiddaman			eval i='$'$op
776*b4dd7d09SAndy Fiddaman			case " $i " in
777*b4dd7d09SAndy Fiddaman			*" $file "*)
778*b4dd7d09SAndy Fiddaman				;;
779*b4dd7d09SAndy Fiddaman			*)	eval $op='"$'$op' $file"'
780*b4dd7d09SAndy Fiddaman				;;
781*b4dd7d09SAndy Fiddaman			esac
782*b4dd7d09SAndy Fiddaman			;;
783*b4dd7d09SAndy Fiddaman		esac
784*b4dd7d09SAndy Fiddaman		shift
785*b4dd7d09SAndy Fiddaman		;;
786*b4dd7d09SAndy Fiddaman	esac
787*b4dd7d09SAndy Fiddaman	case " $IGNORE " in
788*b4dd7d09SAndy Fiddaman	*" $file "*)
789*b4dd7d09SAndy Fiddaman		for i in $IGNORE
790*b4dd7d09SAndy Fiddaman		do	case $i in
791*b4dd7d09SAndy Fiddaman			$file)	;;
792*b4dd7d09SAndy Fiddaman			*)	v="$v $i" ;;
793*b4dd7d09SAndy Fiddaman			esac
794*b4dd7d09SAndy Fiddaman		done
795*b4dd7d09SAndy Fiddaman		IGNORE=$v
796*b4dd7d09SAndy Fiddaman		;;
797*b4dd7d09SAndy Fiddaman	esac
798*b4dd7d09SAndy Fiddaman	FILE[$op]=$file
799*b4dd7d09SAndy Fiddaman	case $op in
800*b4dd7d09SAndy Fiddaman	OUTPUT|ERROR)
801*b4dd7d09SAndy Fiddaman		file=$file.ex
802*b4dd7d09SAndy Fiddaman		if	[[ $file != /* ]]
803*b4dd7d09SAndy Fiddaman		then	file=$TWD/$file
804*b4dd7d09SAndy Fiddaman		fi
805*b4dd7d09SAndy Fiddaman		;;
806*b4dd7d09SAndy Fiddaman	esac
807*b4dd7d09SAndy Fiddaman	#unset SAME[$op]
808*b4dd7d09SAndy Fiddaman	SAME[$op]=
809*b4dd7d09SAndy Fiddaman	if	[[ $file == /* ]]
810*b4dd7d09SAndy Fiddaman	then	RM $file.sav
811*b4dd7d09SAndy Fiddaman	else	RM $TWD/$file.sav
812*b4dd7d09SAndy Fiddaman	fi
813*b4dd7d09SAndy Fiddaman	if	[[ $file == */* ]]
814*b4dd7d09SAndy Fiddaman	then	mkdir -p ${file%/*}
815*b4dd7d09SAndy Fiddaman	fi
816*b4dd7d09SAndy Fiddaman	if	[[ $file != */ ]]
817*b4dd7d09SAndy Fiddaman	then	if	[[ $type == FIFO ]]
818*b4dd7d09SAndy Fiddaman		then	rm -f $file
819*b4dd7d09SAndy Fiddaman			mkfifo $file
820*b4dd7d09SAndy Fiddaman		fi
821*b4dd7d09SAndy Fiddaman		if	[[ ${TYPE[$op]} != FIFO ]]
822*b4dd7d09SAndy Fiddaman		then	if	[[ $JOBOP ]]
823*b4dd7d09SAndy Fiddaman			then	case $#:$f in
824*b4dd7d09SAndy Fiddaman				0:)	;;
825*b4dd7d09SAndy Fiddaman				*:-f)	printf -- "$@" ;;
826*b4dd7d09SAndy Fiddaman				*:-f*)	printf -- "${f#-f}""$@" ;;
827*b4dd7d09SAndy Fiddaman				*)	print $f -r -- "$@" ;;
828*b4dd7d09SAndy Fiddaman				esac >> $file
829*b4dd7d09SAndy Fiddaman			else	case $#:$f in
830*b4dd7d09SAndy Fiddaman				0:)	;;
831*b4dd7d09SAndy Fiddaman				*:-f)	printf -- "$@" ;;
832*b4dd7d09SAndy Fiddaman				*:-f*)	printf -- "${f#-f}""$@" ;;
833*b4dd7d09SAndy Fiddaman				*)	print $f -r -- "$@" ;;
834*b4dd7d09SAndy Fiddaman				esac > $file
835*b4dd7d09SAndy Fiddaman			fi
836*b4dd7d09SAndy Fiddaman		elif	[[ $#:$f != 0: ]]
837*b4dd7d09SAndy Fiddaman		then	case $#:$f in
838*b4dd7d09SAndy Fiddaman			*:-f)	printf -- "$@" ;;
839*b4dd7d09SAndy Fiddaman			*:-f*)	printf -- "${f#-f}""$@" ;;
840*b4dd7d09SAndy Fiddaman			*)	print $f -r -- "$@" ;;
841*b4dd7d09SAndy Fiddaman			esac >> $file &
842*b4dd7d09SAndy Fiddaman		fi
843*b4dd7d09SAndy Fiddaman		if	[[ $x ]]
844*b4dd7d09SAndy Fiddaman		then	chmod +x $file
845*b4dd7d09SAndy Fiddaman		fi
846*b4dd7d09SAndy Fiddaman	fi
847*b4dd7d09SAndy Fiddaman}
848*b4dd7d09SAndy Fiddaman
849*b4dd7d09SAndy Fiddamanfunction INPUT # file|- data ...
850*b4dd7d09SAndy Fiddaman{
851*b4dd7d09SAndy Fiddaman	IO $0 "$@"
852*b4dd7d09SAndy Fiddaman}
853*b4dd7d09SAndy Fiddaman
854*b4dd7d09SAndy Fiddamanfunction COPY # from to
855*b4dd7d09SAndy Fiddaman{
856*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
857*b4dd7d09SAndy Fiddaman	then	return
858*b4dd7d09SAndy Fiddaman	fi
859*b4dd7d09SAndy Fiddaman	COPY="$COPY $@"
860*b4dd7d09SAndy Fiddaman}
861*b4dd7d09SAndy Fiddaman
862*b4dd7d09SAndy Fiddamanfunction MOVE # from to
863*b4dd7d09SAndy Fiddaman{
864*b4dd7d09SAndy Fiddaman	typeset f
865*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
866*b4dd7d09SAndy Fiddaman	then	return
867*b4dd7d09SAndy Fiddaman	fi
868*b4dd7d09SAndy Fiddaman	for f
869*b4dd7d09SAndy Fiddaman	do	case $f in
870*b4dd7d09SAndy Fiddaman		INPUT|OUTPUT|ERROR)
871*b4dd7d09SAndy Fiddaman			f=$TWD/$f
872*b4dd7d09SAndy Fiddaman			;;
873*b4dd7d09SAndy Fiddaman		/*)	;;
874*b4dd7d09SAndy Fiddaman		*)	f=$PWD/$f
875*b4dd7d09SAndy Fiddaman			;;
876*b4dd7d09SAndy Fiddaman		esac
877*b4dd7d09SAndy Fiddaman		MOVE="$MOVE $f"
878*b4dd7d09SAndy Fiddaman	done
879*b4dd7d09SAndy Fiddaman}
880*b4dd7d09SAndy Fiddaman
881*b4dd7d09SAndy Fiddamanfunction SAME # new old
882*b4dd7d09SAndy Fiddaman{
883*b4dd7d09SAndy Fiddaman	typeset i file v
884*b4dd7d09SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
885*b4dd7d09SAndy Fiddaman	then	return
886*b4dd7d09SAndy Fiddaman	fi
887*b4dd7d09SAndy Fiddaman	case $# in
888*b4dd7d09SAndy Fiddaman	2)	case $1 in
889*b4dd7d09SAndy Fiddaman		INPUT)	cat $2 > $1; return ;;
890*b4dd7d09SAndy Fiddaman		esac
891*b4dd7d09SAndy Fiddaman		SAME[$1]=$2
892*b4dd7d09SAndy Fiddaman		file=$1
893*b4dd7d09SAndy Fiddaman		COMPARE="$COMPARE $1"
894*b4dd7d09SAndy Fiddaman		;;
895*b4dd7d09SAndy Fiddaman	3)	SAME[$2]=$3
896*b4dd7d09SAndy Fiddaman		file=$2
897*b4dd7d09SAndy Fiddaman		eval i='$'$1
898*b4dd7d09SAndy Fiddaman		case " $i " in
899*b4dd7d09SAndy Fiddaman		*" $2 "*)
900*b4dd7d09SAndy Fiddaman			;;
901*b4dd7d09SAndy Fiddaman		*)	eval $1='"$'$1' $2"'
902*b4dd7d09SAndy Fiddaman			;;
903*b4dd7d09SAndy Fiddaman		esac
904*b4dd7d09SAndy Fiddaman		COMPARE="$COMPARE $2"
905*b4dd7d09SAndy Fiddaman		;;
906*b4dd7d09SAndy Fiddaman	esac
907*b4dd7d09SAndy Fiddaman	case " $IGNORE " in
908*b4dd7d09SAndy Fiddaman	*" $file "*)
909*b4dd7d09SAndy Fiddaman		for i in $IGNORE
910*b4dd7d09SAndy Fiddaman		do	case $i in
911*b4dd7d09SAndy Fiddaman			$file)	;;
912*b4dd7d09SAndy Fiddaman			*)	v="$v $i" ;;
913*b4dd7d09SAndy Fiddaman			esac
914*b4dd7d09SAndy Fiddaman		done
915*b4dd7d09SAndy Fiddaman		IGNORE=$v
916*b4dd7d09SAndy Fiddaman		;;
917*b4dd7d09SAndy Fiddaman	esac
918*b4dd7d09SAndy Fiddaman}
919*b4dd7d09SAndy Fiddaman
920*b4dd7d09SAndy Fiddamanfunction OUTPUT # file|- data ...
921*b4dd7d09SAndy Fiddaman{
922*b4dd7d09SAndy Fiddaman	IO $0 "$@"
923*b4dd7d09SAndy Fiddaman}
924*b4dd7d09SAndy Fiddaman
925*b4dd7d09SAndy Fiddamanfunction ERROR # file|- data ...
926*b4dd7d09SAndy Fiddaman{
927*b4dd7d09SAndy Fiddaman	IO $0 "$@"
928*b4dd7d09SAndy Fiddaman}
929*b4dd7d09SAndy Fiddaman
930*b4dd7d09SAndy Fiddamanfunction RM # rm(1) args
931*b4dd7d09SAndy Fiddaman{
932*b4dd7d09SAndy Fiddaman	if	[[ ! $TEST_rmu ]]
933*b4dd7d09SAndy Fiddaman	then	chmod -R u+rwx "$@" >/dev/null 2>&1
934*b4dd7d09SAndy Fiddaman	fi
935*b4dd7d09SAndy Fiddaman	rm $TEST_rmu $TEST_rmflags "$@"
936*b4dd7d09SAndy Fiddaman}
937*b4dd7d09SAndy Fiddaman
938*b4dd7d09SAndy Fiddamanfunction REMOVE # file ...
939*b4dd7d09SAndy Fiddaman{
940*b4dd7d09SAndy Fiddaman	typeset i
941*b4dd7d09SAndy Fiddaman	for i
942*b4dd7d09SAndy Fiddaman	do	RM $i $i.sav
943*b4dd7d09SAndy Fiddaman	done
944*b4dd7d09SAndy Fiddaman}
945*b4dd7d09SAndy Fiddaman
946*b4dd7d09SAndy Fiddamanfunction IGNORE # file ...
947*b4dd7d09SAndy Fiddaman{
948*b4dd7d09SAndy Fiddaman	typeset i
949*b4dd7d09SAndy Fiddaman	for i
950*b4dd7d09SAndy Fiddaman	do	case $i in
951*b4dd7d09SAndy Fiddaman		INPUT|OUTPUT|ERROR)
952*b4dd7d09SAndy Fiddaman			i=$TWD/$i
953*b4dd7d09SAndy Fiddaman			;;
954*b4dd7d09SAndy Fiddaman		esac
955*b4dd7d09SAndy Fiddaman		case " $IGNORE " in
956*b4dd7d09SAndy Fiddaman		*" $i "*)
957*b4dd7d09SAndy Fiddaman			;;
958*b4dd7d09SAndy Fiddaman		*)	IGNORE="$IGNORE $i"
959*b4dd7d09SAndy Fiddaman			;;
960*b4dd7d09SAndy Fiddaman		esac
961*b4dd7d09SAndy Fiddaman	done
962*b4dd7d09SAndy Fiddaman}
963*b4dd7d09SAndy Fiddaman
964*b4dd7d09SAndy Fiddamanfunction KEEP # pattern ...
965*b4dd7d09SAndy Fiddaman{
966*b4dd7d09SAndy Fiddaman	typeset i
967*b4dd7d09SAndy Fiddaman	for i
968*b4dd7d09SAndy Fiddaman	do	case $KEEP in
969*b4dd7d09SAndy Fiddaman		"")	KEEP="$i" ;;
970*b4dd7d09SAndy Fiddaman		*)	KEEP="$KEEP|$i" ;;
971*b4dd7d09SAndy Fiddaman		esac
972*b4dd7d09SAndy Fiddaman	done
973*b4dd7d09SAndy Fiddaman}
974*b4dd7d09SAndy Fiddaman
975*b4dd7d09SAndy Fiddamanfunction DIAGNOSTICS # [ 1 | 0 ]
976*b4dd7d09SAndy Fiddaman{
977*b4dd7d09SAndy Fiddaman	case $#:$1 in
978*b4dd7d09SAndy Fiddaman	0:|1:1)	DIAGNOSTICS=1
979*b4dd7d09SAndy Fiddaman		EXIT='*'
980*b4dd7d09SAndy Fiddaman		;;
981*b4dd7d09SAndy Fiddaman	1:|1:0)	DIAGNOSTICS=""
982*b4dd7d09SAndy Fiddaman		EXIT=0
983*b4dd7d09SAndy Fiddaman		;;
984*b4dd7d09SAndy Fiddaman	*)	DIAGNOSTICS=$1
985*b4dd7d09SAndy Fiddaman		EXIT='*'
986*b4dd7d09SAndy Fiddaman		;;
987*b4dd7d09SAndy Fiddaman	esac
988*b4dd7d09SAndy Fiddaman}
989*b4dd7d09SAndy Fiddaman
990*b4dd7d09SAndy Fiddamanfunction IGNORESPACE
991*b4dd7d09SAndy Fiddaman{
992*b4dd7d09SAndy Fiddaman	: ${IGNORESPACE=-b}
993*b4dd7d09SAndy Fiddaman}
994*b4dd7d09SAndy Fiddaman
995*b4dd7d09SAndy Fiddamanfunction EXIT # status
996*b4dd7d09SAndy Fiddaman{
997*b4dd7d09SAndy Fiddaman	EXIT=$1
998*b4dd7d09SAndy Fiddaman}
999*b4dd7d09SAndy Fiddaman
1000*b4dd7d09SAndy Fiddamanfunction INFO # info description
1001*b4dd7d09SAndy Fiddaman{
1002*b4dd7d09SAndy Fiddaman	typeset -R15 info=$1
1003*b4dd7d09SAndy Fiddaman	if	[[ ! $1 ]]
1004*b4dd7d09SAndy Fiddaman	then	info=no
1005*b4dd7d09SAndy Fiddaman	fi
1006*b4dd7d09SAndy Fiddaman	shift
1007*b4dd7d09SAndy Fiddaman	if	[[ ! $TEST_quiet ]]
1008*b4dd7d09SAndy Fiddaman	then	print -r -u2 "$info " "$@"
1009*b4dd7d09SAndy Fiddaman	fi
1010*b4dd7d09SAndy Fiddaman}
1011*b4dd7d09SAndy Fiddaman
1012*b4dd7d09SAndy Fiddamanfunction COMMAND # arg ...
1013*b4dd7d09SAndy Fiddaman{
1014*b4dd7d09SAndy Fiddaman	typeset input
1015*b4dd7d09SAndy Fiddaman	((TESTS++))
1016*b4dd7d09SAndy Fiddaman	case " ${ENVIRON[*]} ${EXPORT[*]}" in
1017*b4dd7d09SAndy Fiddaman	*' 'LC_ALL=*)
1018*b4dd7d09SAndy Fiddaman		;;
1019*b4dd7d09SAndy Fiddaman	*' 'LC_+([A-Z])=*)
1020*b4dd7d09SAndy Fiddaman		EXPORT[EXPORTS++]="LC_ALL="
1021*b4dd7d09SAndy Fiddaman		;;
1022*b4dd7d09SAndy Fiddaman	esac
1023*b4dd7d09SAndy Fiddaman	if	[[ $TEST_keep ]]
1024*b4dd7d09SAndy Fiddaman	then	(
1025*b4dd7d09SAndy Fiddaman		PS4=''
1026*b4dd7d09SAndy Fiddaman		set -x
1027*b4dd7d09SAndy Fiddaman		print -r -- "${ENVIRON[@]}" "${EXPORT[@]}" "PATH=$PATH" $COMMAND "$@"
1028*b4dd7d09SAndy Fiddaman		) 2>&1 >/dev/null |
1029*b4dd7d09SAndy Fiddaman		sed -e 's,^print -r -- ,,' -e 's,$, "$@",' >$TWD/COMMAND
1030*b4dd7d09SAndy Fiddaman		chmod +x $TWD/COMMAND
1031*b4dd7d09SAndy Fiddaman	fi
1032*b4dd7d09SAndy Fiddaman	if	[[ $UMASK != $UMASK_ORIG ]]
1033*b4dd7d09SAndy Fiddaman	then	: >$TWD/ERROR
1034*b4dd7d09SAndy Fiddaman		umask $UMASK
1035*b4dd7d09SAndy Fiddaman	fi
1036*b4dd7d09SAndy Fiddaman	if	[[ ${TYPE[INPUT]} == FIFO && ${FILE[INPUT]} == */INPUT ]]
1037*b4dd7d09SAndy Fiddaman	then	input="< ${FILE[INPUT]}"
1038*b4dd7d09SAndy Fiddaman	fi
1039*b4dd7d09SAndy Fiddaman	if	[[ $TEST_trace ]]
1040*b4dd7d09SAndy Fiddaman	then	set +x
1041*b4dd7d09SAndy Fiddaman		eval print -u2 "$PS4" "${ENVIRON[@]}" "${EXPORT[@]}" PATH='$PATH' '$'COMMAND '"$@"' '$input' '"2>$TWD/ERROR"' '"${JOBPID:+&}"'
1042*b4dd7d09SAndy Fiddaman	fi
1043*b4dd7d09SAndy Fiddaman	eval "${ENVIRON[@]}" "${EXPORT[@]}" PATH='$PATH' '$'COMMAND '"$@"' $input "2>$TWD/ERROR" "${JOBPID:+&}"
1044*b4dd7d09SAndy Fiddaman	STATUS=$?
1045*b4dd7d09SAndy Fiddaman	[[ $TEST_trace ]] && set -x
1046*b4dd7d09SAndy Fiddaman	if	[[ $JOBPID ]]
1047*b4dd7d09SAndy Fiddaman	then	JOBPID=$!
1048*b4dd7d09SAndy Fiddaman	fi
1049*b4dd7d09SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
1050*b4dd7d09SAndy Fiddaman	return $STATUS
1051*b4dd7d09SAndy Fiddaman}
1052*b4dd7d09SAndy Fiddaman
1053*b4dd7d09SAndy Fiddamanfunction RESULTS # pipe*
1054*b4dd7d09SAndy Fiddaman{
1055*b4dd7d09SAndy Fiddaman	typeset i j k s failed ignore io op
1056*b4dd7d09SAndy Fiddaman	if	[[ $1 ]]
1057*b4dd7d09SAndy Fiddaman	then	io="$1 "
1058*b4dd7d09SAndy Fiddaman	fi
1059*b4dd7d09SAndy Fiddaman	[[ $JOBOP || $JOBPID || $JOBSTATUS ]] && sleep 1
1060*b4dd7d09SAndy Fiddaman	for i in $COMPARE $TWD/OUTPUT $TWD/ERROR
1061*b4dd7d09SAndy Fiddaman	do	case " $IGNORE $ignore $MOVE " in
1062*b4dd7d09SAndy Fiddaman		*" $i "*)	continue ;;
1063*b4dd7d09SAndy Fiddaman		esac
1064*b4dd7d09SAndy Fiddaman		ignore="$ignore $i"
1065*b4dd7d09SAndy Fiddaman		op=${i##*/}
1066*b4dd7d09SAndy Fiddaman		if	[[ ${FILTER[$op]} ]]
1067*b4dd7d09SAndy Fiddaman		then	eval "{ ${FILTER[$op]} ;} < $i > $i.fi"
1068*b4dd7d09SAndy Fiddaman			mv $i.fi $i
1069*b4dd7d09SAndy Fiddaman		fi
1070*b4dd7d09SAndy Fiddaman		j=${SAME[$op]}
1071*b4dd7d09SAndy Fiddaman		if	[[ ! $j ]]
1072*b4dd7d09SAndy Fiddaman		then	if	[[ $i == /* ]]
1073*b4dd7d09SAndy Fiddaman			then	k=$i
1074*b4dd7d09SAndy Fiddaman			else	k=$TWD/$i
1075*b4dd7d09SAndy Fiddaman			fi
1076*b4dd7d09SAndy Fiddaman			for s in ex sav err
1077*b4dd7d09SAndy Fiddaman			do	[[ -f $k.$s ]] && break
1078*b4dd7d09SAndy Fiddaman			done
1079*b4dd7d09SAndy Fiddaman			j=$k.$s
1080*b4dd7d09SAndy Fiddaman		fi
1081*b4dd7d09SAndy Fiddaman		if	[[ "$DIAGNOSTICS" && $i == */ERROR ]]
1082*b4dd7d09SAndy Fiddaman		then	if	[[ $STATUS == 0 && ! -s $TWD/ERROR || $DIAGNOSTICS != 1 && $(<$i) != $DIAGNOSTICS ]]
1083*b4dd7d09SAndy Fiddaman			then	failed=$failed${failed:+,}DIAGNOSTICS
1084*b4dd7d09SAndy Fiddaman				if	[[ $TEST_verbose && $DIAGNOSTICS != 1 ]]
1085*b4dd7d09SAndy Fiddaman				then	print -u2 "	===" "diagnostic pattern '$DIAGNOSTICS' did not match" ${i#$TWD/} "==="
1086*b4dd7d09SAndy Fiddaman					cat $i >&2
1087*b4dd7d09SAndy Fiddaman				fi
1088*b4dd7d09SAndy Fiddaman			fi
1089*b4dd7d09SAndy Fiddaman			continue
1090*b4dd7d09SAndy Fiddaman		fi
1091*b4dd7d09SAndy Fiddaman		diff $IGNORESPACE $i $j >$i.diff 2>&1
1092*b4dd7d09SAndy Fiddaman		if	[[ -s $i.diff ]]
1093*b4dd7d09SAndy Fiddaman		then	failed=$failed${failed:+,}${i#$TWD/}
1094*b4dd7d09SAndy Fiddaman			if	[[ $TEST_verbose ]]
1095*b4dd7d09SAndy Fiddaman			then	print -u2 "	===" diff $IGNORESPACE ${i#$TWD/} "<actual >expected ==="
1096*b4dd7d09SAndy Fiddaman				cat $i.diff >&2
1097*b4dd7d09SAndy Fiddaman			fi
1098*b4dd7d09SAndy Fiddaman		fi
1099*b4dd7d09SAndy Fiddaman	done
1100*b4dd7d09SAndy Fiddaman	if	[[ $JOBOP ]]
1101*b4dd7d09SAndy Fiddaman	then	if	[[ $JOBPID ]] && ! kill -0 $JOBPID 2>/dev/null
1102*b4dd7d09SAndy Fiddaman		then	wait $JOBPID
1103*b4dd7d09SAndy Fiddaman			JOBSTATUS=$?
1104*b4dd7d09SAndy Fiddaman			JOBPID=
1105*b4dd7d09SAndy Fiddaman		fi
1106*b4dd7d09SAndy Fiddaman#print -u2 AHA#$LINENO JOBOP=$JOBOP JOBPID=$JOBPID JOBSTATUS=$JOBSTATUS
1107*b4dd7d09SAndy Fiddaman		case $JOBOP in
1108*b4dd7d09SAndy Fiddaman		CONTINUE)
1109*b4dd7d09SAndy Fiddaman			if	[[ ! $JOBPID ]]
1110*b4dd7d09SAndy Fiddaman			then	failed=$failed${failed:+,}EXITED
1111*b4dd7d09SAndy Fiddaman			fi
1112*b4dd7d09SAndy Fiddaman			;;
1113*b4dd7d09SAndy Fiddaman		EXITED) if	[[ $JOBPID ]]
1114*b4dd7d09SAndy Fiddaman			then	failed=$failed${failed:+,}RUNNING
1115*b4dd7d09SAndy Fiddaman			fi
1116*b4dd7d09SAndy Fiddaman			;;
1117*b4dd7d09SAndy Fiddaman		*)	if	[[ ! $JOBPID ]]
1118*b4dd7d09SAndy Fiddaman			then	failed=$failed${failed:+,}EXITED
1119*b4dd7d09SAndy Fiddaman			fi
1120*b4dd7d09SAndy Fiddaman			if	! kill -$JOBOP $JOBPID 2>/dev/null
1121*b4dd7d09SAndy Fiddaman			then	failed=$failed${failed:+,}KILL-$JOBOP
1122*b4dd7d09SAndy Fiddaman			fi
1123*b4dd7d09SAndy Fiddaman			;;
1124*b4dd7d09SAndy Fiddaman		esac
1125*b4dd7d09SAndy Fiddaman		JOBOP=
1126*b4dd7d09SAndy Fiddaman	fi
1127*b4dd7d09SAndy Fiddaman	if	[[ ! $failed && $STATUS != $EXIT ]]
1128*b4dd7d09SAndy Fiddaman	then	failed="exit code $EXIT expected -- got $STATUS"
1129*b4dd7d09SAndy Fiddaman	fi
1130*b4dd7d09SAndy Fiddaman	if	[[ $failed ]]
1131*b4dd7d09SAndy Fiddaman	then	((ERRORS++))
1132*b4dd7d09SAndy Fiddaman		if	[[ ! $TEST_quiet ]]
1133*b4dd7d09SAndy Fiddaman		then	SHOW="FAILED ${io}[ $failed ] $NOTE"
1134*b4dd7d09SAndy Fiddaman			print -r -u2 "	$SHOW"
1135*b4dd7d09SAndy Fiddaman		fi
1136*b4dd7d09SAndy Fiddaman		if	[[ $TEST_keep ]]
1137*b4dd7d09SAndy Fiddaman		then	GROUP=FINI
1138*b4dd7d09SAndy Fiddaman			exit
1139*b4dd7d09SAndy Fiddaman		fi
1140*b4dd7d09SAndy Fiddaman	elif	[[ ! $TEST_quiet ]]
1141*b4dd7d09SAndy Fiddaman	then	SHOW=$NOTE
1142*b4dd7d09SAndy Fiddaman		print -r -u2 "	$SHOW"
1143*b4dd7d09SAndy Fiddaman	fi
1144*b4dd7d09SAndy Fiddaman}
1145*b4dd7d09SAndy Fiddaman
1146*b4dd7d09SAndy Fiddamanfunction SET # [no]name[=value]
1147*b4dd7d09SAndy Fiddaman{
1148*b4dd7d09SAndy Fiddaman	typeset i r
1149*b4dd7d09SAndy Fiddaman	if	[[ $TEST ]]
1150*b4dd7d09SAndy Fiddaman	then	RUN
1151*b4dd7d09SAndy Fiddaman	fi
1152*b4dd7d09SAndy Fiddaman	for i
1153*b4dd7d09SAndy Fiddaman	do	if	[[ $i == - ]]
1154*b4dd7d09SAndy Fiddaman		then	r=1
1155*b4dd7d09SAndy Fiddaman		elif	[[ $i == + ]]
1156*b4dd7d09SAndy Fiddaman		then	r=
1157*b4dd7d09SAndy Fiddaman		else	if	[[ $i == no?* ]]
1158*b4dd7d09SAndy Fiddaman			then	i=${i#no}
1159*b4dd7d09SAndy Fiddaman				v=
1160*b4dd7d09SAndy Fiddaman			elif	[[ $i == *=* ]]
1161*b4dd7d09SAndy Fiddaman			then	v=${i#*=}
1162*b4dd7d09SAndy Fiddaman				if	[[ $v == 0 ]]
1163*b4dd7d09SAndy Fiddaman				then	v=
1164*b4dd7d09SAndy Fiddaman				fi
1165*b4dd7d09SAndy Fiddaman				i=${i%%=*}
1166*b4dd7d09SAndy Fiddaman			else	v=1
1167*b4dd7d09SAndy Fiddaman			fi
1168*b4dd7d09SAndy Fiddaman			i=${i//-/_}
1169*b4dd7d09SAndy Fiddaman			if	[[ $r ]]
1170*b4dd7d09SAndy Fiddaman			then	READONLY[$i]=1
1171*b4dd7d09SAndy Fiddaman			elif	[[ ${READONLY[$i]} ]]
1172*b4dd7d09SAndy Fiddaman			then	continue
1173*b4dd7d09SAndy Fiddaman			fi
1174*b4dd7d09SAndy Fiddaman			eval TEST_$i=$v
1175*b4dd7d09SAndy Fiddaman		fi
1176*b4dd7d09SAndy Fiddaman	done
1177*b4dd7d09SAndy Fiddaman}
1178*b4dd7d09SAndy Fiddaman
1179*b4dd7d09SAndy Fiddamanfunction VIEW # var [ file ]
1180*b4dd7d09SAndy Fiddaman{
1181*b4dd7d09SAndy Fiddaman	nameref var=$1
1182*b4dd7d09SAndy Fiddaman	typeset i bwd file pwd view root offset
1183*b4dd7d09SAndy Fiddaman	if	[[ $var ]]
1184*b4dd7d09SAndy Fiddaman	then	return 0
1185*b4dd7d09SAndy Fiddaman	fi
1186*b4dd7d09SAndy Fiddaman	case $# in
1187*b4dd7d09SAndy Fiddaman	1)	file=$1 ;;
1188*b4dd7d09SAndy Fiddaman	*)	file=$2 ;;
1189*b4dd7d09SAndy Fiddaman	esac
1190*b4dd7d09SAndy Fiddaman	pwd=${TWD%/*}
1191*b4dd7d09SAndy Fiddaman	bwd=${PMP%/*}
1192*b4dd7d09SAndy Fiddaman	if	[[ -r $file ]]
1193*b4dd7d09SAndy Fiddaman	then	if	[[ ! -d $file ]]
1194*b4dd7d09SAndy Fiddaman		then	var=$PWD/$file
1195*b4dd7d09SAndy Fiddaman			return 0
1196*b4dd7d09SAndy Fiddaman		fi
1197*b4dd7d09SAndy Fiddaman		for i in $file/*
1198*b4dd7d09SAndy Fiddaman		do	if	[[ -r $i ]]
1199*b4dd7d09SAndy Fiddaman			then	var=$PWD/$file
1200*b4dd7d09SAndy Fiddaman				return 0
1201*b4dd7d09SAndy Fiddaman			fi
1202*b4dd7d09SAndy Fiddaman			break
1203*b4dd7d09SAndy Fiddaman		done
1204*b4dd7d09SAndy Fiddaman	fi
1205*b4dd7d09SAndy Fiddaman	for view in ${VIEWS[@]}
1206*b4dd7d09SAndy Fiddaman	do	case $view in
1207*b4dd7d09SAndy Fiddaman		/*)	;;
1208*b4dd7d09SAndy Fiddaman		*)	view=$pwd/$view ;;
1209*b4dd7d09SAndy Fiddaman		esac
1210*b4dd7d09SAndy Fiddaman		case $offset in
1211*b4dd7d09SAndy Fiddaman		'')	case $pwd in
1212*b4dd7d09SAndy Fiddaman			$view/*)	offset=${pwd#$view} ;;
1213*b4dd7d09SAndy Fiddaman			*)		offset=${bwd#$view} ;;
1214*b4dd7d09SAndy Fiddaman			esac
1215*b4dd7d09SAndy Fiddaman			;;
1216*b4dd7d09SAndy Fiddaman		esac
1217*b4dd7d09SAndy Fiddaman		if	[[ -r $view$offset/$file ]]
1218*b4dd7d09SAndy Fiddaman		then	if	[[ ! -d $view$offset/$file ]]
1219*b4dd7d09SAndy Fiddaman			then	var=$view$offset/$file
1220*b4dd7d09SAndy Fiddaman				return 0
1221*b4dd7d09SAndy Fiddaman			fi
1222*b4dd7d09SAndy Fiddaman			for i in $view$offset/$file/*
1223*b4dd7d09SAndy Fiddaman			do	if	[[ -f $i ]]
1224*b4dd7d09SAndy Fiddaman				then	var=$view$offset/$file
1225*b4dd7d09SAndy Fiddaman					return 0
1226*b4dd7d09SAndy Fiddaman				fi
1227*b4dd7d09SAndy Fiddaman				break
1228*b4dd7d09SAndy Fiddaman			done
1229*b4dd7d09SAndy Fiddaman		fi
1230*b4dd7d09SAndy Fiddaman	done
1231*b4dd7d09SAndy Fiddaman	var=
1232*b4dd7d09SAndy Fiddaman	return 1
1233*b4dd7d09SAndy Fiddaman}
1234*b4dd7d09SAndy Fiddaman
1235*b4dd7d09SAndy Fiddamanfunction INCLUDE # file ...
1236*b4dd7d09SAndy Fiddaman{
1237*b4dd7d09SAndy Fiddaman	typeset f v x
1238*b4dd7d09SAndy Fiddaman	for f
1239*b4dd7d09SAndy Fiddaman	do	if	VIEW v $f || [[ $PREFIX && $f != /* ]] && VIEW v $PREFIX$f
1240*b4dd7d09SAndy Fiddaman		then	x=$x$'\n'". $v"
1241*b4dd7d09SAndy Fiddaman		else	FATAL $f: not found
1242*b4dd7d09SAndy Fiddaman		fi
1243*b4dd7d09SAndy Fiddaman	done
1244*b4dd7d09SAndy Fiddaman	[[ $x ]] && trap "$x" 0
1245*b4dd7d09SAndy Fiddaman}
1246*b4dd7d09SAndy Fiddaman
1247*b4dd7d09SAndy Fiddamanfunction UMASK # [ mask ]
1248*b4dd7d09SAndy Fiddaman{
1249*b4dd7d09SAndy Fiddaman	if	(( $# ))
1250*b4dd7d09SAndy Fiddaman	then	UMASK=$1
1251*b4dd7d09SAndy Fiddaman	else	UMASK=$UMASK_ORIG
1252*b4dd7d09SAndy Fiddaman	fi
1253*b4dd7d09SAndy Fiddaman}
1254*b4dd7d09SAndy Fiddaman
1255*b4dd7d09SAndy Fiddamanfunction PIPE # INPUT|OUTPUT|ERROR file|- data ...
1256*b4dd7d09SAndy Fiddaman{
1257*b4dd7d09SAndy Fiddaman	IO $0 "$@"
1258*b4dd7d09SAndy Fiddaman}
1259*b4dd7d09SAndy Fiddaman
1260*b4dd7d09SAndy Fiddamanfunction FIFO # INPUT|OUTPUT|ERROR file|- data ...
1261*b4dd7d09SAndy Fiddaman{
1262*b4dd7d09SAndy Fiddaman	IO $0 "$@"
1263*b4dd7d09SAndy Fiddaman}
1264*b4dd7d09SAndy Fiddaman
1265*b4dd7d09SAndy Fiddamanfunction IF # command(s) [note]
1266*b4dd7d09SAndy Fiddaman{
1267*b4dd7d09SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1268*b4dd7d09SAndy Fiddaman	RUN
1269*b4dd7d09SAndy Fiddaman	(( COND++ ))
1270*b4dd7d09SAndy Fiddaman	COND_LINE[COND]=$LINE
1271*b4dd7d09SAndy Fiddaman	if	(( COND > 1 && COND_SKIP[COND-1] ))
1272*b4dd7d09SAndy Fiddaman	then	(( COND_KEPT[COND] = 1 ))
1273*b4dd7d09SAndy Fiddaman		(( COND_SKIP[COND] = 1 ))
1274*b4dd7d09SAndy Fiddaman	elif	eval "{ $1 ;} >/dev/null 2>&1"
1275*b4dd7d09SAndy Fiddaman	then	(( COND_KEPT[COND] = 1 ))
1276*b4dd7d09SAndy Fiddaman		(( COND_SKIP[COND] = 0 ))
1277*b4dd7d09SAndy Fiddaman		[[ $2 && ! $TEST_quiet ]] && print -u2 "NOTE	$2"
1278*b4dd7d09SAndy Fiddaman	else	(( COND_KEPT[COND] = 0 ))
1279*b4dd7d09SAndy Fiddaman		(( COND_SKIP[COND] = 1 ))
1280*b4dd7d09SAndy Fiddaman	fi
1281*b4dd7d09SAndy Fiddaman}
1282*b4dd7d09SAndy Fiddaman
1283*b4dd7d09SAndy Fiddamanfunction ELIF # command(s) [note]
1284*b4dd7d09SAndy Fiddaman{
1285*b4dd7d09SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1286*b4dd7d09SAndy Fiddaman	RUN
1287*b4dd7d09SAndy Fiddaman	if	(( COND <= 0 ))
1288*b4dd7d09SAndy Fiddaman	then	FATAL line $LINE: no matching IF for ELIF
1289*b4dd7d09SAndy Fiddaman	fi
1290*b4dd7d09SAndy Fiddaman	if	(( COND_KEPT[COND] ))
1291*b4dd7d09SAndy Fiddaman	then	(( COND_SKIP[COND] = 0 ))
1292*b4dd7d09SAndy Fiddaman	elif	eval "$* > /dev/null 2>&1"
1293*b4dd7d09SAndy Fiddaman	then	(( COND_KEPT[COND] = 1 ))
1294*b4dd7d09SAndy Fiddaman		(( COND_SKIP[COND] = 0 ))
1295*b4dd7d09SAndy Fiddaman		[[ $2 && ! $TEST_quiet ]] && print -u2 "NOTE	$2"
1296*b4dd7d09SAndy Fiddaman	else	(( COND_SKIP[COND] = 1 ))
1297*b4dd7d09SAndy Fiddaman	fi
1298*b4dd7d09SAndy Fiddaman}
1299*b4dd7d09SAndy Fiddaman
1300*b4dd7d09SAndy Fiddamanfunction ELSE # [note]
1301*b4dd7d09SAndy Fiddaman{
1302*b4dd7d09SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1303*b4dd7d09SAndy Fiddaman	RUN
1304*b4dd7d09SAndy Fiddaman	if	(( COND <= 0 ))
1305*b4dd7d09SAndy Fiddaman	then	FATAL line $LINE: no matching IF for ELSE
1306*b4dd7d09SAndy Fiddaman	fi
1307*b4dd7d09SAndy Fiddaman	if	(( COND_KEPT[COND] ))
1308*b4dd7d09SAndy Fiddaman	then	(( COND_SKIP[COND] = 1 ))
1309*b4dd7d09SAndy Fiddaman	else	(( COND_KEPT[COND] = 1 ))
1310*b4dd7d09SAndy Fiddaman		(( COND_SKIP[COND] = 0 ))
1311*b4dd7d09SAndy Fiddaman		[[ $1 && ! $TEST_quiet ]] && print -u2 "NOTE	$1"
1312*b4dd7d09SAndy Fiddaman	fi
1313*b4dd7d09SAndy Fiddaman}
1314*b4dd7d09SAndy Fiddaman
1315*b4dd7d09SAndy Fiddamanfunction FI
1316*b4dd7d09SAndy Fiddaman{
1317*b4dd7d09SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1318*b4dd7d09SAndy Fiddaman	RUN
1319*b4dd7d09SAndy Fiddaman	if	(( COND <= 0 ))
1320*b4dd7d09SAndy Fiddaman	then	FATAL line $LINE: no matching IF for FI on line $LINE
1321*b4dd7d09SAndy Fiddaman	fi
1322*b4dd7d09SAndy Fiddaman	(( ! COND_KEPT[COND] )) && [[ $1 && ! $TEST_quiet ]] && print -u2 "NOTE	$1"
1323*b4dd7d09SAndy Fiddaman	(( COND-- ))
1324*b4dd7d09SAndy Fiddaman}
1325*b4dd7d09SAndy Fiddaman
1326*b4dd7d09SAndy Fiddaman# main
1327*b4dd7d09SAndy Fiddaman
1328*b4dd7d09SAndy Fiddamaninteger ERRORS=0 ENVIRONS=0 EXPORTS=0 TESTS=0 SUBTESTS=0 LINE=0 TESTLINE=0
1329*b4dd7d09SAndy Fiddamaninteger ITEM=0 LASTITEM=0 COND=0 UNIT_READONLY=0 COUNT
1330*b4dd7d09SAndy Fiddamantypeset ARGS COMMAND COPY DIAGNOSTICS ERROR EXEC FLUSHED=0 GROUP=INIT
1331*b4dd7d09SAndy Fiddamantypeset IGNORE INPUT KEEP OUTPUT TEST SOURCE MOVE NOTE UMASK UMASK_ORIG
1332*b4dd7d09SAndy Fiddamantypeset ARGS_ORIG COMMAND_ORIG TITLE UNIT ARGV PREFIX OFFSET IGNORESPACE
1333*b4dd7d09SAndy Fiddamantypeset COMPARE MAIN JOBPID='' JOBSTATUS=''
1334*b4dd7d09SAndy Fiddamantypeset TEST_file TEST_keep TEST_pipe_input TEST_pipe_io TEST_pipe_output TEST_local
1335*b4dd7d09SAndy Fiddamantypeset TEST_quiet TEST_regular=1 TEST_rmflags='-rf --' TEST_rmu TEST_select
1336*b4dd7d09SAndy Fiddaman
1337*b4dd7d09SAndy Fiddamantypeset -A SAME VIEWS FILE TYPE READONLY FILTER
1338*b4dd7d09SAndy Fiddamantypeset -a COND_LINE COND_SKIP COND_KEPT ENVIRON EXPORT
1339*b4dd7d09SAndy Fiddamantypeset -Z LAST=00
1340*b4dd7d09SAndy Fiddaman
1341*b4dd7d09SAndy Fiddamanunset FIGNORE
1342*b4dd7d09SAndy Fiddaman
1343*b4dd7d09SAndy Fiddamanwhile	getopts -a $command "$USAGE" OPT
1344*b4dd7d09SAndy Fiddamando	case $OPT in
1345*b4dd7d09SAndy Fiddaman	b)	(( $OPTARG )) && IGNORESPACE=-b
1346*b4dd7d09SAndy Fiddaman		;;
1347*b4dd7d09SAndy Fiddaman	i)	SET - pipe-input=$OPTARG
1348*b4dd7d09SAndy Fiddaman		;;
1349*b4dd7d09SAndy Fiddaman	k)	SET - keep=$OPTARG
1350*b4dd7d09SAndy Fiddaman		;;
1351*b4dd7d09SAndy Fiddaman	l)	SET - local
1352*b4dd7d09SAndy Fiddaman		;;
1353*b4dd7d09SAndy Fiddaman	o)	SET - pipe-output=$OPTARG
1354*b4dd7d09SAndy Fiddaman		;;
1355*b4dd7d09SAndy Fiddaman	p)	SET - pipe-io=$OPTARG
1356*b4dd7d09SAndy Fiddaman		;;
1357*b4dd7d09SAndy Fiddaman	q)	SET - quiet=$OPTARG
1358*b4dd7d09SAndy Fiddaman		;;
1359*b4dd7d09SAndy Fiddaman	r)	SET - regular=$OPTARG
1360*b4dd7d09SAndy Fiddaman		;;
1361*b4dd7d09SAndy Fiddaman	t)	if	[[ $TEST_select ]]
1362*b4dd7d09SAndy Fiddaman		then	TEST_select="$TEST_select|${OPTARG//,/\|}"
1363*b4dd7d09SAndy Fiddaman		else	TEST_select="${OPTARG//,/\|}"
1364*b4dd7d09SAndy Fiddaman		fi
1365*b4dd7d09SAndy Fiddaman		;;
1366*b4dd7d09SAndy Fiddaman	x)	SET - trace=$OPTARG
1367*b4dd7d09SAndy Fiddaman		;;
1368*b4dd7d09SAndy Fiddaman	v)	SET - verbose=$OPTARG
1369*b4dd7d09SAndy Fiddaman		;;
1370*b4dd7d09SAndy Fiddaman	*)	GROUP=FINI
1371*b4dd7d09SAndy Fiddaman		exit 2
1372*b4dd7d09SAndy Fiddaman		;;
1373*b4dd7d09SAndy Fiddaman	esac
1374*b4dd7d09SAndy Fiddamandone
1375*b4dd7d09SAndy Fiddamanshift $OPTIND-1
1376*b4dd7d09SAndy Fiddamancase $# in
1377*b4dd7d09SAndy Fiddaman0)	FATAL test unit name omitted ;;
1378*b4dd7d09SAndy Fiddamanesac
1379*b4dd7d09SAndy Fiddamanexport COLUMNS=80
1380*b4dd7d09SAndy FiddamanSOURCE=$PWD
1381*b4dd7d09SAndy FiddamanPATH=$SOURCE:${PATH#?(.):}
1382*b4dd7d09SAndy FiddamanPATH=${PATH%%:?(.)}:/bin:/usr/bin
1383*b4dd7d09SAndy FiddamanUNIT=$1
1384*b4dd7d09SAndy Fiddamanshift
1385*b4dd7d09SAndy Fiddamanif	[[ -f $UNIT && ! -x $UNIT ]]
1386*b4dd7d09SAndy Fiddamanthen	REGRESS=$UNIT
1387*b4dd7d09SAndy Fiddamanelse	REGRESS=${UNIT%.tst}
1388*b4dd7d09SAndy Fiddaman	REGRESS=$REGRESS.tst
1389*b4dd7d09SAndy Fiddaman	[[ -f $REGRESS ]] || FATAL $REGRESS: regression tests not found
1390*b4dd7d09SAndy Fiddamanfi
1391*b4dd7d09SAndy FiddamanUNIT=${UNIT##*/}
1392*b4dd7d09SAndy FiddamanUNIT=${UNIT%.tst}
1393*b4dd7d09SAndy FiddamanMAIN=$UNIT
1394*b4dd7d09SAndy Fiddamanif	[[ $VPATH ]]
1395*b4dd7d09SAndy Fiddamanthen	set -A VIEWS ${VPATH//:/' '}
1396*b4dd7d09SAndy Fiddaman	OFFSET=${SOURCE#${VIEWS[0]}}
1397*b4dd7d09SAndy Fiddaman	if	[[ $OFFSET ]]
1398*b4dd7d09SAndy Fiddaman	then	OFFSET=${OFFSET#/}/
1399*b4dd7d09SAndy Fiddaman	fi
1400*b4dd7d09SAndy Fiddamanfi
1401*b4dd7d09SAndy Fiddamanif	[[ $REGRESS == */* ]]
1402*b4dd7d09SAndy Fiddamanthen	PREFIX=${REGRESS%/*}
1403*b4dd7d09SAndy Fiddaman	if	[[ ${#VIEWS[@]} ]]
1404*b4dd7d09SAndy Fiddaman	then	for i in ${VIEWS[@]}
1405*b4dd7d09SAndy Fiddaman		do	PREFIX=${PREFIX#$i/}
1406*b4dd7d09SAndy Fiddaman		done
1407*b4dd7d09SAndy Fiddaman	fi
1408*b4dd7d09SAndy Fiddaman	PREFIX=${PREFIX#$OFFSET}
1409*b4dd7d09SAndy Fiddaman	if	[[ $PREFIX ]]
1410*b4dd7d09SAndy Fiddaman	then	PREFIX=$PREFIX/
1411*b4dd7d09SAndy Fiddaman	fi
1412*b4dd7d09SAndy Fiddamanfi
1413*b4dd7d09SAndy FiddamanTWD=$PWD/$UNIT.tmp
1414*b4dd7d09SAndy FiddamanPMP=$(pwd -P)/$UNIT.tmp
1415*b4dd7d09SAndy FiddamanUMASK_ORIG=$(umask)
1416*b4dd7d09SAndy FiddamanUMASK=$UMASK_ORIG
1417*b4dd7d09SAndy FiddamanARGV=("$@")
1418*b4dd7d09SAndy Fiddamanif	[[ ${ARGV[0]} && ${ARGV[0]} != [-+]* ]]
1419*b4dd7d09SAndy Fiddamanthen	UNIT "${ARGV[@]}"
1420*b4dd7d09SAndy Fiddaman	UNIT_READONLY=1
1421*b4dd7d09SAndy Fiddamanfi
1422*b4dd7d09SAndy Fiddamantrap 'code=$?; CLEANUP $code' EXIT
1423*b4dd7d09SAndy Fiddamanif	[[ ! $TEST_select ]]
1424*b4dd7d09SAndy Fiddamanthen	TEST_select="[0123456789]*"
1425*b4dd7d09SAndy Fiddamanfi
1426*b4dd7d09SAndy FiddamanTEST_select="@($TEST_select|+(0))"
1427*b4dd7d09SAndy Fiddamanif	[[ $TEST_trace ]]
1428*b4dd7d09SAndy Fiddamanthen	export PS4=':$LINENO: '
1429*b4dd7d09SAndy Fiddaman	typeset -ft $(typeset +f)
1430*b4dd7d09SAndy Fiddaman	set -x
1431*b4dd7d09SAndy Fiddamanfi
1432*b4dd7d09SAndy Fiddamanif	[[ $TEST_verbose ]]
1433*b4dd7d09SAndy Fiddamanthen	typeset SHOW
1434*b4dd7d09SAndy Fiddamanelse	typeset -L70 SHOW
1435*b4dd7d09SAndy Fiddamanfi
1436*b4dd7d09SAndy Fiddamanif	[[ ! $TEST_keep ]] && (ulimit -c 0) >/dev/null 2>&1
1437*b4dd7d09SAndy Fiddamanthen	ulimit -c 0
1438*b4dd7d09SAndy Fiddamanfi
1439*b4dd7d09SAndy Fiddamanset --pipefail
1440*b4dd7d09SAndy Fiddaman
1441*b4dd7d09SAndy Fiddaman# some last minute shenanigans
1442*b4dd7d09SAndy Fiddaman
1443*b4dd7d09SAndy Fiddamanalias BODY='BODY=BODY; function BODY'
1444*b4dd7d09SAndy Fiddamanalias CONTINUE='LINE=$LINENO; CONTINUE'
1445*b4dd7d09SAndy Fiddamanalias DO='(( $ITEM != $FLUSHED )) && RUN DO; DO &&'
1446*b4dd7d09SAndy Fiddamanalias DONE='DONE=DONE; function DONE'
1447*b4dd7d09SAndy Fiddamanalias EXEC='LINE=$LINENO; EXEC'
1448*b4dd7d09SAndy Fiddamanalias EXITED='LINE=$LINENO; EXITED'
1449*b4dd7d09SAndy Fiddamanalias INIT='INIT=INIT; function INIT'
1450*b4dd7d09SAndy Fiddamanalias JOB='LINE=$LINENO; JOB'
1451*b4dd7d09SAndy Fiddamanalias KILL='LINE=$LINENO; KILL'
1452*b4dd7d09SAndy Fiddamanalias PROG='LINE=$LINENO; FLUSH; PROG'
1453*b4dd7d09SAndy Fiddamanalias TEST='TESTLINE=$LINENO; TEST'
1454*b4dd7d09SAndy Fiddamanalias IF='LINE=$LINENO; FLUSH; IF'
1455*b4dd7d09SAndy Fiddamanalias ELIF='LINE=$LINENO; FLUSH; ELIF'
1456*b4dd7d09SAndy Fiddamanalias ELSE='LINE=$LINENO; FLUSH; ELSE'
1457*b4dd7d09SAndy Fiddamanalias FI='LINE=$LINENO; FLUSH; FI'
1458*b4dd7d09SAndy Fiddaman
1459*b4dd7d09SAndy Fiddaman# do the tests
1460*b4dd7d09SAndy Fiddaman
1461*b4dd7d09SAndy Fiddaman. $REGRESS
1462*b4dd7d09SAndy FiddamanRUN
1463*b4dd7d09SAndy FiddamanGROUP=FINI
1464