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
371*b30d1939SAndy Fiddaman#print -u2 AHA#$LINENO $0 GROUP=$GROUP ITEM=$ITEM FLUSHED=$FLUSHED JOBOP=$JOBOP
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
408*b30d1939SAndy Fiddaman		((COUNT++))
409*b30d1939SAndy Fiddaman		if	(( $ITEM <= $LASTITEM ))
410*b30d1939SAndy Fiddaman		then	LABEL=$TEST#$COUNT
411*b30d1939SAndy Fiddaman		else	LASTITEM=$ITEM
412*b30d1939SAndy Fiddaman			LABEL=$TEST:$ITEM
413*b30d1939SAndy Fiddaman		fi
414*b30d1939SAndy Fiddaman		TEST_file=""
415*b30d1939SAndy Fiddaman		exec >/dev/null
416*b30d1939SAndy Fiddaman		for i in $INPUT
417*b30d1939SAndy Fiddaman		do	case " $OUTPUT " in
418*b30d1939SAndy Fiddaman			*" $i "*)
419*b30d1939SAndy Fiddaman				if	[[ -f $i.sav ]]
420*b30d1939SAndy Fiddaman				then	cp $i.sav $i
421*b30d1939SAndy Fiddaman					COMPARE="$COMPARE $i"
422*b30d1939SAndy Fiddaman				elif	[[ -f $i ]]
423*b30d1939SAndy Fiddaman				then	cp $i $i.sav
424*b30d1939SAndy Fiddaman					COMPARE="$COMPARE $i"
425*b30d1939SAndy Fiddaman				fi
426*b30d1939SAndy Fiddaman				;;
427*b30d1939SAndy Fiddaman			esac
428*b30d1939SAndy Fiddaman		done
429*b30d1939SAndy Fiddaman		for i in $OUTPUT
430*b30d1939SAndy Fiddaman		do	case " $COMPARE " in
431*b30d1939SAndy Fiddaman			*" $i "*)
432*b30d1939SAndy Fiddaman				;;
433*b30d1939SAndy Fiddaman			*)	COMPARE="$COMPARE $i"
434*b30d1939SAndy Fiddaman				;;
435*b30d1939SAndy Fiddaman			esac
436*b30d1939SAndy Fiddaman		done
437*b30d1939SAndy Fiddaman		for i in $INIT
438*b30d1939SAndy Fiddaman		do	$i $TEST INIT
439*b30d1939SAndy Fiddaman		done
440*b30d1939SAndy Fiddaman#print -u2 AHA#$LINENO $0 GROUP=$GROUP ITEM=$ITEM JOBOP=$JOBOP JOBPID=$JOBPID JOBSTATUS=$JOBSTATUS
441*b30d1939SAndy Fiddaman		if	[[ $JOBPID != 0 && ( $JOBPID || $JOBSTATUS ) ]]
442*b30d1939SAndy Fiddaman		then	if	[[ ! $TEST_quiet ]]
443*b30d1939SAndy Fiddaman			then	print -nu2 "$LABEL"
444*b30d1939SAndy Fiddaman			fi
445*b30d1939SAndy Fiddaman			RESULTS
446*b30d1939SAndy Fiddaman		elif	[[ $BODY ]]
447*b30d1939SAndy Fiddaman		then	SHOW=$NOTE
448*b30d1939SAndy Fiddaman			if	[[ ! $TEST_quiet ]]
449*b30d1939SAndy Fiddaman			then	print -r -u2 "	$SHOW"
450*b30d1939SAndy Fiddaman			fi
451*b30d1939SAndy Fiddaman			for i in $BODY
452*b30d1939SAndy Fiddaman			do	$i $TEST BODY
453*b30d1939SAndy Fiddaman			done
454*b30d1939SAndy Fiddaman		else	SHOW=
455*b30d1939SAndy Fiddaman			if	[[ ${TYPE[INPUT]} == PIPE ]]
456*b30d1939SAndy Fiddaman			then	if	[[ ${TYPE[OUTPUT]} == PIPE ]]
457*b30d1939SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
458*b30d1939SAndy Fiddaman					then	print -nu2 "$LABEL"
459*b30d1939SAndy Fiddaman					fi
460*b30d1939SAndy Fiddaman					cat <$TWD/INPUT | COMMAND "${ARGS[@]}" | cat >$TWD/OUTPUT
461*b30d1939SAndy Fiddaman					RESULTS 'pipe input'
462*b30d1939SAndy Fiddaman				else	if	[[ ! $TEST_quiet ]]
463*b30d1939SAndy Fiddaman					then	print -nu2 "$LABEL"
464*b30d1939SAndy Fiddaman					fi
465*b30d1939SAndy Fiddaman					cat <$TWD/INPUT | COMMAND "${ARGS[@]}" >$TWD/OUTPUT
466*b30d1939SAndy Fiddaman					RESULTS 'pipe io'
467*b30d1939SAndy Fiddaman				fi
468*b30d1939SAndy Fiddaman			elif	[[ ${TYPE[OUTPUT]} == PIPE ]]
469*b30d1939SAndy Fiddaman			then	if	[[ ! $TEST_quiet ]]
470*b30d1939SAndy Fiddaman				then	print -nu2 "$LABEL"
471*b30d1939SAndy Fiddaman				fi
472*b30d1939SAndy Fiddaman				COMMAND "${ARGS[@]}" <$TWD/INPUT | cat >$TWD/OUTPUT
473*b30d1939SAndy Fiddaman				RESULTS 'pipe output'
474*b30d1939SAndy Fiddaman			else	if	[[ $TEST_regular ]]
475*b30d1939SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
476*b30d1939SAndy Fiddaman					then	print -nu2 "$LABEL"
477*b30d1939SAndy Fiddaman					fi
478*b30d1939SAndy Fiddaman					if	[[ ${TYPE[INPUT]} == FIFO ]]
479*b30d1939SAndy Fiddaman					then	COMMAND "${ARGS[@]}" >$TWD/OUTPUT
480*b30d1939SAndy Fiddaman					else	COMMAND "${ARGS[@]}" <$TWD/INPUT >$TWD/OUTPUT
481*b30d1939SAndy Fiddaman					fi
482*b30d1939SAndy Fiddaman					RESULTS
483*b30d1939SAndy Fiddaman				fi
484*b30d1939SAndy Fiddaman				if	[[ $TEST_pipe_input ]]
485*b30d1939SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
486*b30d1939SAndy Fiddaman					then	print -nu2 "$LABEL"
487*b30d1939SAndy Fiddaman					fi
488*b30d1939SAndy Fiddaman					(trap '' PIPE; cat <$TWD/INPUT 2>/dev/null; exit 0) | COMMAND "${ARGS[@]}" >$TWD/OUTPUT
489*b30d1939SAndy Fiddaman					STATUS=$?
490*b30d1939SAndy Fiddaman					RESULTS 'pipe input'
491*b30d1939SAndy Fiddaman				fi
492*b30d1939SAndy Fiddaman				if	[[ $TEST_pipe_output ]]
493*b30d1939SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
494*b30d1939SAndy Fiddaman					then	print -nu2 "$LABEL"
495*b30d1939SAndy Fiddaman					fi
496*b30d1939SAndy Fiddaman					COMMAND "${ARGS[@]}" <$TWD/INPUT | cat >$TWD/OUTPUT
497*b30d1939SAndy Fiddaman					STATUS=$?
498*b30d1939SAndy Fiddaman					RESULTS 'pipe output'
499*b30d1939SAndy Fiddaman				fi
500*b30d1939SAndy Fiddaman				if	[[ $TEST_pipe_io ]]
501*b30d1939SAndy Fiddaman				then	if	[[ ! $TEST_quiet ]]
502*b30d1939SAndy Fiddaman					then	print -nu2 "$LABEL"
503*b30d1939SAndy Fiddaman					fi
504*b30d1939SAndy Fiddaman					(trap '' PIPE; cat <$TWD/INPUT 2>/dev/null; exit 0) | COMMAND "${ARGS[@]}" | cat >$TWD/OUTPUT
505*b30d1939SAndy Fiddaman					STATUS=$?
506*b30d1939SAndy Fiddaman					RESULTS 'pipe io'
507*b30d1939SAndy Fiddaman				fi
508*b30d1939SAndy Fiddaman			fi
509*b30d1939SAndy Fiddaman			set -- $COPY
510*b30d1939SAndy Fiddaman			COPY=""
511*b30d1939SAndy Fiddaman			while	:
512*b30d1939SAndy Fiddaman			do	case $# in
513*b30d1939SAndy Fiddaman				0|1)	break ;;
514*b30d1939SAndy Fiddaman				*)	cp $1 $2 ;;
515*b30d1939SAndy Fiddaman				esac
516*b30d1939SAndy Fiddaman				shift 2
517*b30d1939SAndy Fiddaman			done
518*b30d1939SAndy Fiddaman			set -- $MOVE
519*b30d1939SAndy Fiddaman			MOVE=""
520*b30d1939SAndy Fiddaman			while	(( $# > 1 ))
521*b30d1939SAndy Fiddaman			do	mv $1 $2
522*b30d1939SAndy Fiddaman				shift 2
523*b30d1939SAndy Fiddaman			done
524*b30d1939SAndy Fiddaman		fi
525*b30d1939SAndy Fiddaman		for i in $DONE
526*b30d1939SAndy Fiddaman		do	$i $TEST DONE $STATUS
527*b30d1939SAndy Fiddaman		done
528*b30d1939SAndy Fiddaman		COMPARE=""
529*b30d1939SAndy Fiddaman		r=0
530*b30d1939SAndy Fiddaman		;;
531*b30d1939SAndy Fiddaman	esac
532*b30d1939SAndy Fiddaman	if	[[ $COMMAND_ORIG ]]
533*b30d1939SAndy Fiddaman	then	COMMAND=$COMMAND_ORIG
534*b30d1939SAndy Fiddaman		COMMAND_ORIG=
535*b30d1939SAndy Fiddaman		ARGS=(${ARGS_ORIG[@]})
536*b30d1939SAndy Fiddaman	fi
537*b30d1939SAndy Fiddaman	return $r
538*b30d1939SAndy Fiddaman}
539*b30d1939SAndy Fiddaman
540*b30d1939SAndy Fiddamanfunction DO # cmd ...
541*b30d1939SAndy Fiddaman{
542*b30d1939SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return 1
543*b30d1939SAndy Fiddaman	(( COND_SKIP[COND] )) && return 1
544*b30d1939SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK
545*b30d1939SAndy Fiddaman	return 0
546*b30d1939SAndy Fiddaman}
547*b30d1939SAndy Fiddaman
548*b30d1939SAndy Fiddamanfunction UNIT # cmd arg ...
549*b30d1939SAndy Fiddaman{
550*b30d1939SAndy Fiddaman	typeset cmd=$1
551*b30d1939SAndy Fiddaman	case $cmd in
552*b30d1939SAndy Fiddaman	[-+])	shift
553*b30d1939SAndy Fiddaman		if	(( UNIT_READONLY ))
554*b30d1939SAndy Fiddaman		then	COMMAND="$COMMAND $*"
555*b30d1939SAndy Fiddaman		else	#BUG# ARGV=("${ARGV[@]}" "$@")
556*b30d1939SAndy Fiddaman			set -- "${ARGV[@]}" "$@"
557*b30d1939SAndy Fiddaman			ARGV=("$@")
558*b30d1939SAndy Fiddaman		fi
559*b30d1939SAndy Fiddaman		return
560*b30d1939SAndy Fiddaman		;;
561*b30d1939SAndy Fiddaman	esac
562*b30d1939SAndy Fiddaman	(( UNIT_READONLY )) && return
563*b30d1939SAndy Fiddaman	if	[[ $UNIT ]] && (( $# <= 1 ))
564*b30d1939SAndy Fiddaman	then	set -- "${ARGV[@]}"
565*b30d1939SAndy Fiddaman		case $1 in
566*b30d1939SAndy Fiddaman		"")	set -- "$cmd" ;;
567*b30d1939SAndy Fiddaman		[-+]*)	set -- "$cmd" "${ARGV[@]}" ;;
568*b30d1939SAndy Fiddaman		*)	cmd=$1 ;;
569*b30d1939SAndy Fiddaman		esac
570*b30d1939SAndy Fiddaman	fi
571*b30d1939SAndy Fiddaman	UNIT=
572*b30d1939SAndy Fiddaman	COMMAND=$cmd
573*b30d1939SAndy Fiddaman	shift
574*b30d1939SAndy Fiddaman	typeset cmd=$(whence $COMMAND)
575*b30d1939SAndy Fiddaman	if	[[ ! $cmd ]]
576*b30d1939SAndy Fiddaman	then	FATAL $COMMAND: not found
577*b30d1939SAndy Fiddaman	elif	[[ ! $cmd ]]
578*b30d1939SAndy Fiddaman	then	FATAL $cmd: not found
579*b30d1939SAndy Fiddaman	fi
580*b30d1939SAndy Fiddaman	case $# in
581*b30d1939SAndy Fiddaman	0)	;;
582*b30d1939SAndy Fiddaman	*)	COMMAND="$COMMAND $*" ;;
583*b30d1939SAndy Fiddaman	esac
584*b30d1939SAndy Fiddaman}
585*b30d1939SAndy Fiddaman
586*b30d1939SAndy Fiddamanfunction TWD # [ dir ]
587*b30d1939SAndy Fiddaman{
588*b30d1939SAndy Fiddaman	case $1 in
589*b30d1939SAndy Fiddaman	'')	TWD=${TWD##*/}; TWD=${TMPDIR:-/tmp}/tst-${TWD%.*}-$$-$RANDOM ;;
590*b30d1939SAndy Fiddaman	/*)	TWD=$1 ;;
591*b30d1939SAndy Fiddaman	*)	TWD=${TMPDIR:-/tmp}/$1 ;;
592*b30d1939SAndy Fiddaman	esac
593*b30d1939SAndy Fiddaman}
594*b30d1939SAndy Fiddaman
595*b30d1939SAndy Fiddamanfunction TEST # number description arg ...
596*b30d1939SAndy Fiddaman{
597*b30d1939SAndy Fiddaman	RUN
598*b30d1939SAndy Fiddaman	LINE=$TESTLINE
599*b30d1939SAndy Fiddaman	UNWIND
600*b30d1939SAndy Fiddaman	COUNT=0
601*b30d1939SAndy Fiddaman	LASTITEM=0
602*b30d1939SAndy Fiddaman	case $1 in
603*b30d1939SAndy Fiddaman	-)		((LAST++)); TEST=$LAST ;;
604*b30d1939SAndy Fiddaman	+([0123456789]))	LAST=$1 TEST=$1 ;;
605*b30d1939SAndy Fiddaman	*)		LAST=0${1/[!0123456789]/} TEST=$1 ;;
606*b30d1939SAndy Fiddaman	esac
607*b30d1939SAndy Fiddaman	NOTE=
608*b30d1939SAndy Fiddaman	if	[[ ! $TEST_quiet && $TEST == $TEST_select ]] && (( ! COND_SKIP[COND] ))
609*b30d1939SAndy Fiddaman	then	print -r -u2 "$TEST	$2"
610*b30d1939SAndy Fiddaman	fi
611*b30d1939SAndy Fiddaman	unset ARGS
612*b30d1939SAndy Fiddaman	unset EXPORT
613*b30d1939SAndy Fiddaman	EXPORTS=0
614*b30d1939SAndy Fiddaman	TEST_file=""
615*b30d1939SAndy Fiddaman	if	[[ $TEST != ${GROUP}* ]]
616*b30d1939SAndy Fiddaman	then	GROUP=${TEST%%+([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ])}
617*b30d1939SAndy Fiddaman		if	[[ $GROUP == $TEST_select ]] && (( ! COND_SKIP[COND] ))
618*b30d1939SAndy Fiddaman		then	INITIALIZE
619*b30d1939SAndy Fiddaman		fi
620*b30d1939SAndy Fiddaman	fi
621*b30d1939SAndy Fiddaman	((SUBTESTS=0))
622*b30d1939SAndy Fiddaman	[[ $TEST == $TEST_select ]] && (( ! COND_SKIP[COND] ))
623*b30d1939SAndy Fiddaman}
624*b30d1939SAndy Fiddaman
625*b30d1939SAndy Fiddamanfunction EXEC # arg ...
626*b30d1939SAndy Fiddaman{
627*b30d1939SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
628*b30d1939SAndy Fiddaman	then	return
629*b30d1939SAndy Fiddaman	fi
630*b30d1939SAndy Fiddaman	if	((SUBTESTS++))
631*b30d1939SAndy Fiddaman	then	RUN
632*b30d1939SAndy Fiddaman	fi
633*b30d1939SAndy Fiddaman	case $# in
634*b30d1939SAndy Fiddaman	0)	set -- "${ARGS[@]}" ;;
635*b30d1939SAndy Fiddaman	esac
636*b30d1939SAndy Fiddaman	ITEM=$LINE
637*b30d1939SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $COMMAND_ORIG "$@")${JOBPID:+&}"
638*b30d1939SAndy Fiddaman	ARGS=("$@")
639*b30d1939SAndy Fiddaman}
640*b30d1939SAndy Fiddaman
641*b30d1939SAndy Fiddamanfunction JOB # arg ...
642*b30d1939SAndy Fiddaman{
643*b30d1939SAndy Fiddaman	JOBPID=0
644*b30d1939SAndy Fiddaman	EXEC "$@"
645*b30d1939SAndy Fiddaman}
646*b30d1939SAndy Fiddaman
647*b30d1939SAndy Fiddamanfunction CONTINUE
648*b30d1939SAndy Fiddaman{
649*b30d1939SAndy Fiddaman	RUN || return
650*b30d1939SAndy Fiddaman	JOBOP=CONTINUE
651*b30d1939SAndy Fiddaman	ITEM=$LINE
652*b30d1939SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $JOBOP)"
653*b30d1939SAndy Fiddaman#print -u2 AHA#$LINENO JOBOP=$JOBOP ITEM=$ITEM NOTE=$NOTE
654*b30d1939SAndy Fiddaman}
655*b30d1939SAndy Fiddaman
656*b30d1939SAndy Fiddamanfunction EXITED
657*b30d1939SAndy Fiddaman{
658*b30d1939SAndy Fiddaman	RUN || return
659*b30d1939SAndy Fiddaman	JOBOP=EXITED
660*b30d1939SAndy Fiddaman	ITEM=$LINE
661*b30d1939SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $JOBOP)"
662*b30d1939SAndy Fiddaman#print -u2 AHA#$LINENO JOBOP=$JOBOP ITEM=$ITEM NOTE=$NOTE
663*b30d1939SAndy Fiddaman}
664*b30d1939SAndy Fiddaman
665*b30d1939SAndy Fiddamanfunction KILL # [ signal ]
666*b30d1939SAndy Fiddaman{
667*b30d1939SAndy Fiddaman	RUN || return
668*b30d1939SAndy Fiddaman	JOBOP=$2
669*b30d1939SAndy Fiddaman	[[ $JOBOP ]] || JOBOP=KILL
670*b30d1939SAndy Fiddaman	ITEM=$LINE
671*b30d1939SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- $JOBOP)"
672*b30d1939SAndy Fiddaman}
673*b30d1939SAndy Fiddaman
674*b30d1939SAndy Fiddamanfunction CD
675*b30d1939SAndy Fiddaman{
676*b30d1939SAndy Fiddaman	RUN
677*b30d1939SAndy Fiddaman	if	[[ $GROUP == $TEST_select ]] && (( ! COND_SKIP[COND] ))
678*b30d1939SAndy Fiddaman	then	mkdir -p "$@" && cd "$@" || FATAL cannot initialize working directory "$@"
679*b30d1939SAndy Fiddaman	fi
680*b30d1939SAndy Fiddaman}
681*b30d1939SAndy Fiddaman
682*b30d1939SAndy Fiddamanfunction EXPORT
683*b30d1939SAndy Fiddaman{
684*b30d1939SAndy Fiddaman	typeset x n v
685*b30d1939SAndy Fiddaman	if	[[ $GROUP == INIT ]]
686*b30d1939SAndy Fiddaman	then	for x
687*b30d1939SAndy Fiddaman		do	n=${x%%=*}
688*b30d1939SAndy Fiddaman			v=${x#*=}
689*b30d1939SAndy Fiddaman			ENVIRON[ENVIRONS++]=$n="'$v'"
690*b30d1939SAndy Fiddaman		done
691*b30d1939SAndy Fiddaman	else	RUN
692*b30d1939SAndy Fiddaman		if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
693*b30d1939SAndy Fiddaman		then	return
694*b30d1939SAndy Fiddaman		fi
695*b30d1939SAndy Fiddaman		for x
696*b30d1939SAndy Fiddaman		do	n=${x%%=*}
697*b30d1939SAndy Fiddaman			v=${x#*=}
698*b30d1939SAndy Fiddaman			EXPORT[EXPORTS++]=$n="'$v'"
699*b30d1939SAndy Fiddaman		done
700*b30d1939SAndy Fiddaman	fi
701*b30d1939SAndy Fiddaman}
702*b30d1939SAndy Fiddaman
703*b30d1939SAndy Fiddamanfunction FLUSH
704*b30d1939SAndy Fiddaman{
705*b30d1939SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
706*b30d1939SAndy Fiddaman	then	return
707*b30d1939SAndy Fiddaman	fi
708*b30d1939SAndy Fiddaman	if	((SUBTESTS++))
709*b30d1939SAndy Fiddaman	then	RUN
710*b30d1939SAndy Fiddaman	fi
711*b30d1939SAndy Fiddaman}
712*b30d1939SAndy Fiddaman
713*b30d1939SAndy Fiddamanfunction PROG # cmd arg ...
714*b30d1939SAndy Fiddaman{
715*b30d1939SAndy Fiddaman	typeset command args
716*b30d1939SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
717*b30d1939SAndy Fiddaman	then	return
718*b30d1939SAndy Fiddaman	fi
719*b30d1939SAndy Fiddaman	ITEM=$LINE
720*b30d1939SAndy Fiddaman	NOTE="$(print -r -f '%q ' -- "$@")"
721*b30d1939SAndy Fiddaman	COMMAND_ORIG=$COMMAND
722*b30d1939SAndy Fiddaman	COMMAND=$1
723*b30d1939SAndy Fiddaman	shift
724*b30d1939SAndy Fiddaman	ARGS_ORIG=(${ARGS[@]})
725*b30d1939SAndy Fiddaman	ARGS=("$@")
726*b30d1939SAndy Fiddaman}
727*b30d1939SAndy Fiddaman
728*b30d1939SAndy Fiddamanfunction NOTE # description
729*b30d1939SAndy Fiddaman{
730*b30d1939SAndy Fiddaman	NOTE=$*
731*b30d1939SAndy Fiddaman}
732*b30d1939SAndy Fiddaman
733*b30d1939SAndy Fiddamanfunction IO # [ PIPE ] INPUT|OUTPUT|ERROR [-f*|-n] file|- data ...
734*b30d1939SAndy Fiddaman{
735*b30d1939SAndy Fiddaman	typeset op i v f file type x
736*b30d1939SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
737*b30d1939SAndy Fiddaman	then	return
738*b30d1939SAndy Fiddaman	fi
739*b30d1939SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
740*b30d1939SAndy Fiddaman	while	:
741*b30d1939SAndy Fiddaman	do	case $1 in
742*b30d1939SAndy Fiddaman		FIFO|PIPE)	type=$1; shift ;;
743*b30d1939SAndy Fiddaman		*)		break ;;
744*b30d1939SAndy Fiddaman		esac
745*b30d1939SAndy Fiddaman	done
746*b30d1939SAndy Fiddaman	op=$1
747*b30d1939SAndy Fiddaman	shift
748*b30d1939SAndy Fiddaman	[[ $type ]] && TYPE[$op]=$type
749*b30d1939SAndy Fiddaman	FILTER[$op]=
750*b30d1939SAndy Fiddaman	file=$TWD/$op
751*b30d1939SAndy Fiddaman	while	:
752*b30d1939SAndy Fiddaman	do	case $1 in
753*b30d1939SAndy Fiddaman		-x)	x=1
754*b30d1939SAndy Fiddaman			shift
755*b30d1939SAndy Fiddaman			;;
756*b30d1939SAndy Fiddaman		-e)	(( $# > 1 )) && shift
757*b30d1939SAndy Fiddaman			FILTER[$op]=$1
758*b30d1939SAndy Fiddaman			shift
759*b30d1939SAndy Fiddaman			;;
760*b30d1939SAndy Fiddaman		-e*)	FILTER[$op]=${1#-e}
761*b30d1939SAndy Fiddaman			shift
762*b30d1939SAndy Fiddaman			;;
763*b30d1939SAndy Fiddaman		-f*|-n)	f=$1
764*b30d1939SAndy Fiddaman			shift
765*b30d1939SAndy Fiddaman			;;
766*b30d1939SAndy Fiddaman		*)	break
767*b30d1939SAndy Fiddaman			;;
768*b30d1939SAndy Fiddaman		esac
769*b30d1939SAndy Fiddaman	done
770*b30d1939SAndy Fiddaman	case $# in
771*b30d1939SAndy Fiddaman	0)	;;
772*b30d1939SAndy Fiddaman	*)	case $1 in
773*b30d1939SAndy Fiddaman		-)	;;
774*b30d1939SAndy Fiddaman		*)	file=$1
775*b30d1939SAndy Fiddaman			eval i='$'$op
776*b30d1939SAndy Fiddaman			case " $i " in
777*b30d1939SAndy Fiddaman			*" $file "*)
778*b30d1939SAndy Fiddaman				;;
779*b30d1939SAndy Fiddaman			*)	eval $op='"$'$op' $file"'
780*b30d1939SAndy Fiddaman				;;
781*b30d1939SAndy Fiddaman			esac
782*b30d1939SAndy Fiddaman			;;
783*b30d1939SAndy Fiddaman		esac
784*b30d1939SAndy Fiddaman		shift
785*b30d1939SAndy Fiddaman		;;
786*b30d1939SAndy Fiddaman	esac
787*b30d1939SAndy Fiddaman	case " $IGNORE " in
788*b30d1939SAndy Fiddaman	*" $file "*)
789*b30d1939SAndy Fiddaman		for i in $IGNORE
790*b30d1939SAndy Fiddaman		do	case $i in
791*b30d1939SAndy Fiddaman			$file)	;;
792*b30d1939SAndy Fiddaman			*)	v="$v $i" ;;
793*b30d1939SAndy Fiddaman			esac
794*b30d1939SAndy Fiddaman		done
795*b30d1939SAndy Fiddaman		IGNORE=$v
796*b30d1939SAndy Fiddaman		;;
797*b30d1939SAndy Fiddaman	esac
798*b30d1939SAndy Fiddaman	FILE[$op]=$file
799*b30d1939SAndy Fiddaman	case $op in
800*b30d1939SAndy Fiddaman	OUTPUT|ERROR)
801*b30d1939SAndy Fiddaman		file=$file.ex
802*b30d1939SAndy Fiddaman		if	[[ $file != /* ]]
803*b30d1939SAndy Fiddaman		then	file=$TWD/$file
804*b30d1939SAndy Fiddaman		fi
805*b30d1939SAndy Fiddaman		;;
806*b30d1939SAndy Fiddaman	esac
807*b30d1939SAndy Fiddaman	#unset SAME[$op]
808*b30d1939SAndy Fiddaman	SAME[$op]=
809*b30d1939SAndy Fiddaman	if	[[ $file == /* ]]
810*b30d1939SAndy Fiddaman	then	RM $file.sav
811*b30d1939SAndy Fiddaman	else	RM $TWD/$file.sav
812*b30d1939SAndy Fiddaman	fi
813*b30d1939SAndy Fiddaman	if	[[ $file == */* ]]
814*b30d1939SAndy Fiddaman	then	mkdir -p ${file%/*}
815*b30d1939SAndy Fiddaman	fi
816*b30d1939SAndy Fiddaman	if	[[ $file != */ ]]
817*b30d1939SAndy Fiddaman	then	if	[[ $type == FIFO ]]
818*b30d1939SAndy Fiddaman		then	rm -f $file
819*b30d1939SAndy Fiddaman			mkfifo $file
820*b30d1939SAndy Fiddaman		fi
821*b30d1939SAndy Fiddaman		if	[[ ${TYPE[$op]} != FIFO ]]
822*b30d1939SAndy Fiddaman		then	if	[[ $JOBOP ]]
823*b30d1939SAndy Fiddaman			then	case $#:$f in
824*b30d1939SAndy Fiddaman				0:)	;;
825*b30d1939SAndy Fiddaman				*:-f)	printf -- "$@" ;;
826*b30d1939SAndy Fiddaman				*:-f*)	printf -- "${f#-f}""$@" ;;
827*b30d1939SAndy Fiddaman				*)	print $f -r -- "$@" ;;
828*b30d1939SAndy Fiddaman				esac >> $file
829*b30d1939SAndy Fiddaman			else	case $#:$f in
830*b30d1939SAndy Fiddaman				0:)	;;
831*b30d1939SAndy Fiddaman				*:-f)	printf -- "$@" ;;
832*b30d1939SAndy Fiddaman				*:-f*)	printf -- "${f#-f}""$@" ;;
833*b30d1939SAndy Fiddaman				*)	print $f -r -- "$@" ;;
834*b30d1939SAndy Fiddaman				esac > $file
835*b30d1939SAndy Fiddaman			fi
836*b30d1939SAndy Fiddaman		elif	[[ $#:$f != 0: ]]
837*b30d1939SAndy Fiddaman		then	case $#:$f in
838*b30d1939SAndy Fiddaman			*:-f)	printf -- "$@" ;;
839*b30d1939SAndy Fiddaman			*:-f*)	printf -- "${f#-f}""$@" ;;
840*b30d1939SAndy Fiddaman			*)	print $f -r -- "$@" ;;
841*b30d1939SAndy Fiddaman			esac >> $file &
842*b30d1939SAndy Fiddaman		fi
843*b30d1939SAndy Fiddaman		if	[[ $x ]]
844*b30d1939SAndy Fiddaman		then	chmod +x $file
845*b30d1939SAndy Fiddaman		fi
846*b30d1939SAndy Fiddaman	fi
847*b30d1939SAndy Fiddaman}
848*b30d1939SAndy Fiddaman
849*b30d1939SAndy Fiddamanfunction INPUT # file|- data ...
850*b30d1939SAndy Fiddaman{
851*b30d1939SAndy Fiddaman	IO $0 "$@"
852*b30d1939SAndy Fiddaman}
853*b30d1939SAndy Fiddaman
854*b30d1939SAndy Fiddamanfunction COPY # from to
855*b30d1939SAndy Fiddaman{
856*b30d1939SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
857*b30d1939SAndy Fiddaman	then	return
858*b30d1939SAndy Fiddaman	fi
859*b30d1939SAndy Fiddaman	COPY="$COPY $@"
860*b30d1939SAndy Fiddaman}
861*b30d1939SAndy Fiddaman
862*b30d1939SAndy Fiddamanfunction MOVE # from to
863*b30d1939SAndy Fiddaman{
864*b30d1939SAndy Fiddaman	typeset f
865*b30d1939SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
866*b30d1939SAndy Fiddaman	then	return
867*b30d1939SAndy Fiddaman	fi
868*b30d1939SAndy Fiddaman	for f
869*b30d1939SAndy Fiddaman	do	case $f in
870*b30d1939SAndy Fiddaman		INPUT|OUTPUT|ERROR)
871*b30d1939SAndy Fiddaman			f=$TWD/$f
872*b30d1939SAndy Fiddaman			;;
873*b30d1939SAndy Fiddaman		/*)	;;
874*b30d1939SAndy Fiddaman		*)	f=$PWD/$f
875*b30d1939SAndy Fiddaman			;;
876*b30d1939SAndy Fiddaman		esac
877*b30d1939SAndy Fiddaman		MOVE="$MOVE $f"
878*b30d1939SAndy Fiddaman	done
879*b30d1939SAndy Fiddaman}
880*b30d1939SAndy Fiddaman
881*b30d1939SAndy Fiddamanfunction SAME # new old
882*b30d1939SAndy Fiddaman{
883*b30d1939SAndy Fiddaman	typeset i file v
884*b30d1939SAndy Fiddaman	if	[[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] ))
885*b30d1939SAndy Fiddaman	then	return
886*b30d1939SAndy Fiddaman	fi
887*b30d1939SAndy Fiddaman	case $# in
888*b30d1939SAndy Fiddaman	2)	case $1 in
889*b30d1939SAndy Fiddaman		INPUT)	cat $2 > $1; return ;;
890*b30d1939SAndy Fiddaman		esac
891*b30d1939SAndy Fiddaman		SAME[$1]=$2
892*b30d1939SAndy Fiddaman		file=$1
893*b30d1939SAndy Fiddaman		COMPARE="$COMPARE $1"
894*b30d1939SAndy Fiddaman		;;
895*b30d1939SAndy Fiddaman	3)	SAME[$2]=$3
896*b30d1939SAndy Fiddaman		file=$2
897*b30d1939SAndy Fiddaman		eval i='$'$1
898*b30d1939SAndy Fiddaman		case " $i " in
899*b30d1939SAndy Fiddaman		*" $2 "*)
900*b30d1939SAndy Fiddaman			;;
901*b30d1939SAndy Fiddaman		*)	eval $1='"$'$1' $2"'
902*b30d1939SAndy Fiddaman			;;
903*b30d1939SAndy Fiddaman		esac
904*b30d1939SAndy Fiddaman		COMPARE="$COMPARE $2"
905*b30d1939SAndy Fiddaman		;;
906*b30d1939SAndy Fiddaman	esac
907*b30d1939SAndy Fiddaman	case " $IGNORE " in
908*b30d1939SAndy Fiddaman	*" $file "*)
909*b30d1939SAndy Fiddaman		for i in $IGNORE
910*b30d1939SAndy Fiddaman		do	case $i in
911*b30d1939SAndy Fiddaman			$file)	;;
912*b30d1939SAndy Fiddaman			*)	v="$v $i" ;;
913*b30d1939SAndy Fiddaman			esac
914*b30d1939SAndy Fiddaman		done
915*b30d1939SAndy Fiddaman		IGNORE=$v
916*b30d1939SAndy Fiddaman		;;
917*b30d1939SAndy Fiddaman	esac
918*b30d1939SAndy Fiddaman}
919*b30d1939SAndy Fiddaman
920*b30d1939SAndy Fiddamanfunction OUTPUT # file|- data ...
921*b30d1939SAndy Fiddaman{
922*b30d1939SAndy Fiddaman	IO $0 "$@"
923*b30d1939SAndy Fiddaman}
924*b30d1939SAndy Fiddaman
925*b30d1939SAndy Fiddamanfunction ERROR # file|- data ...
926*b30d1939SAndy Fiddaman{
927*b30d1939SAndy Fiddaman	IO $0 "$@"
928*b30d1939SAndy Fiddaman}
929*b30d1939SAndy Fiddaman
930*b30d1939SAndy Fiddamanfunction RM # rm(1) args
931*b30d1939SAndy Fiddaman{
932*b30d1939SAndy Fiddaman	if	[[ ! $TEST_rmu ]]
933*b30d1939SAndy Fiddaman	then	chmod -R u+rwx "$@" >/dev/null 2>&1
934*b30d1939SAndy Fiddaman	fi
935*b30d1939SAndy Fiddaman	rm $TEST_rmu $TEST_rmflags "$@"
936*b30d1939SAndy Fiddaman}
937*b30d1939SAndy Fiddaman
938*b30d1939SAndy Fiddamanfunction REMOVE # file ...
939*b30d1939SAndy Fiddaman{
940*b30d1939SAndy Fiddaman	typeset i
941*b30d1939SAndy Fiddaman	for i
942*b30d1939SAndy Fiddaman	do	RM $i $i.sav
943*b30d1939SAndy Fiddaman	done
944*b30d1939SAndy Fiddaman}
945*b30d1939SAndy Fiddaman
946*b30d1939SAndy Fiddamanfunction IGNORE # file ...
947*b30d1939SAndy Fiddaman{
948*b30d1939SAndy Fiddaman	typeset i
949*b30d1939SAndy Fiddaman	for i
950*b30d1939SAndy Fiddaman	do	case $i in
951*b30d1939SAndy Fiddaman		INPUT|OUTPUT|ERROR)
952*b30d1939SAndy Fiddaman			i=$TWD/$i
953*b30d1939SAndy Fiddaman			;;
954*b30d1939SAndy Fiddaman		esac
955*b30d1939SAndy Fiddaman		case " $IGNORE " in
956*b30d1939SAndy Fiddaman		*" $i "*)
957*b30d1939SAndy Fiddaman			;;
958*b30d1939SAndy Fiddaman		*)	IGNORE="$IGNORE $i"
959*b30d1939SAndy Fiddaman			;;
960*b30d1939SAndy Fiddaman		esac
961*b30d1939SAndy Fiddaman	done
962*b30d1939SAndy Fiddaman}
963*b30d1939SAndy Fiddaman
964*b30d1939SAndy Fiddamanfunction KEEP # pattern ...
965*b30d1939SAndy Fiddaman{
966*b30d1939SAndy Fiddaman	typeset i
967*b30d1939SAndy Fiddaman	for i
968*b30d1939SAndy Fiddaman	do	case $KEEP in
969*b30d1939SAndy Fiddaman		"")	KEEP="$i" ;;
970*b30d1939SAndy Fiddaman		*)	KEEP="$KEEP|$i" ;;
971*b30d1939SAndy Fiddaman		esac
972*b30d1939SAndy Fiddaman	done
973*b30d1939SAndy Fiddaman}
974*b30d1939SAndy Fiddaman
975*b30d1939SAndy Fiddamanfunction DIAGNOSTICS # [ 1 | 0 ]
976*b30d1939SAndy Fiddaman{
977*b30d1939SAndy Fiddaman	case $#:$1 in
978*b30d1939SAndy Fiddaman	0:|1:1)	DIAGNOSTICS=1
979*b30d1939SAndy Fiddaman		EXIT='*'
980*b30d1939SAndy Fiddaman		;;
981*b30d1939SAndy Fiddaman	1:|1:0)	DIAGNOSTICS=""
982*b30d1939SAndy Fiddaman		EXIT=0
983*b30d1939SAndy Fiddaman		;;
984*b30d1939SAndy Fiddaman	*)	DIAGNOSTICS=$1
985*b30d1939SAndy Fiddaman		EXIT='*'
986*b30d1939SAndy Fiddaman		;;
987*b30d1939SAndy Fiddaman	esac
988*b30d1939SAndy Fiddaman}
989*b30d1939SAndy Fiddaman
990*b30d1939SAndy Fiddamanfunction IGNORESPACE
991*b30d1939SAndy Fiddaman{
992*b30d1939SAndy Fiddaman	: ${IGNORESPACE=-b}
993*b30d1939SAndy Fiddaman}
994*b30d1939SAndy Fiddaman
995*b30d1939SAndy Fiddamanfunction EXIT # status
996*b30d1939SAndy Fiddaman{
997*b30d1939SAndy Fiddaman	EXIT=$1
998*b30d1939SAndy Fiddaman}
999*b30d1939SAndy Fiddaman
1000*b30d1939SAndy Fiddamanfunction INFO # info description
1001*b30d1939SAndy Fiddaman{
1002*b30d1939SAndy Fiddaman	typeset -R15 info=$1
1003*b30d1939SAndy Fiddaman	if	[[ ! $1 ]]
1004*b30d1939SAndy Fiddaman	then	info=no
1005*b30d1939SAndy Fiddaman	fi
1006*b30d1939SAndy Fiddaman	shift
1007*b30d1939SAndy Fiddaman	if	[[ ! $TEST_quiet ]]
1008*b30d1939SAndy Fiddaman	then	print -r -u2 "$info " "$@"
1009*b30d1939SAndy Fiddaman	fi
1010*b30d1939SAndy Fiddaman}
1011*b30d1939SAndy Fiddaman
1012*b30d1939SAndy Fiddamanfunction COMMAND # arg ...
1013*b30d1939SAndy Fiddaman{
1014*b30d1939SAndy Fiddaman	typeset input
1015*b30d1939SAndy Fiddaman	((TESTS++))
1016*b30d1939SAndy Fiddaman	case " ${ENVIRON[*]} ${EXPORT[*]}" in
1017*b30d1939SAndy Fiddaman	*' 'LC_ALL=*)
1018*b30d1939SAndy Fiddaman		;;
1019*b30d1939SAndy Fiddaman	*' 'LC_+([A-Z])=*)
1020*b30d1939SAndy Fiddaman		EXPORT[EXPORTS++]="LC_ALL="
1021*b30d1939SAndy Fiddaman		;;
1022*b30d1939SAndy Fiddaman	esac
1023*b30d1939SAndy Fiddaman	if	[[ $TEST_keep ]]
1024*b30d1939SAndy Fiddaman	then	(
1025*b30d1939SAndy Fiddaman		PS4=''
1026*b30d1939SAndy Fiddaman		set -x
1027*b30d1939SAndy Fiddaman		print -r -- "${ENVIRON[@]}" "${EXPORT[@]}" "PATH=$PATH" $COMMAND "$@"
1028*b30d1939SAndy Fiddaman		) 2>&1 >/dev/null |
1029*b30d1939SAndy Fiddaman		sed -e 's,^print -r -- ,,' -e 's,$, "$@",' >$TWD/COMMAND
1030*b30d1939SAndy Fiddaman		chmod +x $TWD/COMMAND
1031*b30d1939SAndy Fiddaman	fi
1032*b30d1939SAndy Fiddaman	if	[[ $UMASK != $UMASK_ORIG ]]
1033*b30d1939SAndy Fiddaman	then	: >$TWD/ERROR
1034*b30d1939SAndy Fiddaman		umask $UMASK
1035*b30d1939SAndy Fiddaman	fi
1036*b30d1939SAndy Fiddaman	if	[[ ${TYPE[INPUT]} == FIFO && ${FILE[INPUT]} == */INPUT ]]
1037*b30d1939SAndy Fiddaman	then	input="< ${FILE[INPUT]}"
1038*b30d1939SAndy Fiddaman	fi
1039*b30d1939SAndy Fiddaman	if	[[ $TEST_trace ]]
1040*b30d1939SAndy Fiddaman	then	set +x
1041*b30d1939SAndy Fiddaman		eval print -u2 "$PS4" "${ENVIRON[@]}" "${EXPORT[@]}" PATH='$PATH' '$'COMMAND '"$@"' '$input' '"2>$TWD/ERROR"' '"${JOBPID:+&}"'
1042*b30d1939SAndy Fiddaman	fi
1043*b30d1939SAndy Fiddaman	eval "${ENVIRON[@]}" "${EXPORT[@]}" PATH='$PATH' '$'COMMAND '"$@"' $input "2>$TWD/ERROR" "${JOBPID:+&}"
1044*b30d1939SAndy Fiddaman	STATUS=$?
1045*b30d1939SAndy Fiddaman	[[ $TEST_trace ]] && set -x
1046*b30d1939SAndy Fiddaman	if	[[ $JOBPID ]]
1047*b30d1939SAndy Fiddaman	then	JOBPID=$!
1048*b30d1939SAndy Fiddaman	fi
1049*b30d1939SAndy Fiddaman	[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
1050*b30d1939SAndy Fiddaman	return $STATUS
1051*b30d1939SAndy Fiddaman}
1052*b30d1939SAndy Fiddaman
1053*b30d1939SAndy Fiddamanfunction RESULTS # pipe*
1054*b30d1939SAndy Fiddaman{
1055*b30d1939SAndy Fiddaman	typeset i j k s failed ignore io op
1056*b30d1939SAndy Fiddaman	if	[[ $1 ]]
1057*b30d1939SAndy Fiddaman	then	io="$1 "
1058*b30d1939SAndy Fiddaman	fi
1059*b30d1939SAndy Fiddaman	[[ $JOBOP || $JOBPID || $JOBSTATUS ]] && sleep 1
1060*b30d1939SAndy Fiddaman	for i in $COMPARE $TWD/OUTPUT $TWD/ERROR
1061*b30d1939SAndy Fiddaman	do	case " $IGNORE $ignore $MOVE " in
1062*b30d1939SAndy Fiddaman		*" $i "*)	continue ;;
1063*b30d1939SAndy Fiddaman		esac
1064*b30d1939SAndy Fiddaman		ignore="$ignore $i"
1065*b30d1939SAndy Fiddaman		op=${i##*/}
1066*b30d1939SAndy Fiddaman		if	[[ ${FILTER[$op]} ]]
1067*b30d1939SAndy Fiddaman		then	eval "{ ${FILTER[$op]} ;} < $i > $i.fi"
1068*b30d1939SAndy Fiddaman			mv $i.fi $i
1069*b30d1939SAndy Fiddaman		fi
1070*b30d1939SAndy Fiddaman		j=${SAME[$op]}
1071*b30d1939SAndy Fiddaman		if	[[ ! $j ]]
1072*b30d1939SAndy Fiddaman		then	if	[[ $i == /* ]]
1073*b30d1939SAndy Fiddaman			then	k=$i
1074*b30d1939SAndy Fiddaman			else	k=$TWD/$i
1075*b30d1939SAndy Fiddaman			fi
1076*b30d1939SAndy Fiddaman			for s in ex sav err
1077*b30d1939SAndy Fiddaman			do	[[ -f $k.$s ]] && break
1078*b30d1939SAndy Fiddaman			done
1079*b30d1939SAndy Fiddaman			j=$k.$s
1080*b30d1939SAndy Fiddaman		fi
1081*b30d1939SAndy Fiddaman		if	[[ "$DIAGNOSTICS" && $i == */ERROR ]]
1082*b30d1939SAndy Fiddaman		then	if	[[ $STATUS == 0 && ! -s $TWD/ERROR || $DIAGNOSTICS != 1 && $(<$i) != $DIAGNOSTICS ]]
1083*b30d1939SAndy Fiddaman			then	failed=$failed${failed:+,}DIAGNOSTICS
1084*b30d1939SAndy Fiddaman				if	[[ $TEST_verbose && $DIAGNOSTICS != 1 ]]
1085*b30d1939SAndy Fiddaman				then	print -u2 "	===" "diagnostic pattern '$DIAGNOSTICS' did not match" ${i#$TWD/} "==="
1086*b30d1939SAndy Fiddaman					cat $i >&2
1087*b30d1939SAndy Fiddaman				fi
1088*b30d1939SAndy Fiddaman			fi
1089*b30d1939SAndy Fiddaman			continue
1090*b30d1939SAndy Fiddaman		fi
1091*b30d1939SAndy Fiddaman		diff $IGNORESPACE $i $j >$i.diff 2>&1
1092*b30d1939SAndy Fiddaman		if	[[ -s $i.diff ]]
1093*b30d1939SAndy Fiddaman		then	failed=$failed${failed:+,}${i#$TWD/}
1094*b30d1939SAndy Fiddaman			if	[[ $TEST_verbose ]]
1095*b30d1939SAndy Fiddaman			then	print -u2 "	===" diff $IGNORESPACE ${i#$TWD/} "<actual >expected ==="
1096*b30d1939SAndy Fiddaman				cat $i.diff >&2
1097*b30d1939SAndy Fiddaman			fi
1098*b30d1939SAndy Fiddaman		fi
1099*b30d1939SAndy Fiddaman	done
1100*b30d1939SAndy Fiddaman	if	[[ $JOBOP ]]
1101*b30d1939SAndy Fiddaman	then	if	[[ $JOBPID ]] && ! kill -0 $JOBPID 2>/dev/null
1102*b30d1939SAndy Fiddaman		then	wait $JOBPID
1103*b30d1939SAndy Fiddaman			JOBSTATUS=$?
1104*b30d1939SAndy Fiddaman			JOBPID=
1105*b30d1939SAndy Fiddaman		fi
1106*b30d1939SAndy Fiddaman#print -u2 AHA#$LINENO JOBOP=$JOBOP JOBPID=$JOBPID JOBSTATUS=$JOBSTATUS
1107*b30d1939SAndy Fiddaman		case $JOBOP in
1108*b30d1939SAndy Fiddaman		CONTINUE)
1109*b30d1939SAndy Fiddaman			if	[[ ! $JOBPID ]]
1110*b30d1939SAndy Fiddaman			then	failed=$failed${failed:+,}EXITED
1111*b30d1939SAndy Fiddaman			fi
1112*b30d1939SAndy Fiddaman			;;
1113*b30d1939SAndy Fiddaman		EXITED) if	[[ $JOBPID ]]
1114*b30d1939SAndy Fiddaman			then	failed=$failed${failed:+,}RUNNING
1115*b30d1939SAndy Fiddaman			fi
1116*b30d1939SAndy Fiddaman			;;
1117*b30d1939SAndy Fiddaman		*)	if	[[ ! $JOBPID ]]
1118*b30d1939SAndy Fiddaman			then	failed=$failed${failed:+,}EXITED
1119*b30d1939SAndy Fiddaman			fi
1120*b30d1939SAndy Fiddaman			if	! kill -$JOBOP $JOBPID 2>/dev/null
1121*b30d1939SAndy Fiddaman			then	failed=$failed${failed:+,}KILL-$JOBOP
1122*b30d1939SAndy Fiddaman			fi
1123*b30d1939SAndy Fiddaman			;;
1124*b30d1939SAndy Fiddaman		esac
1125*b30d1939SAndy Fiddaman		JOBOP=
1126*b30d1939SAndy Fiddaman	fi
1127*b30d1939SAndy Fiddaman	if	[[ ! $failed && $STATUS != $EXIT ]]
1128*b30d1939SAndy Fiddaman	then	failed="exit code $EXIT expected -- got $STATUS"
1129*b30d1939SAndy Fiddaman	fi
1130*b30d1939SAndy Fiddaman	if	[[ $failed ]]
1131*b30d1939SAndy Fiddaman	then	((ERRORS++))
1132*b30d1939SAndy Fiddaman		if	[[ ! $TEST_quiet ]]
1133*b30d1939SAndy Fiddaman		then	SHOW="FAILED ${io}[ $failed ] $NOTE"
1134*b30d1939SAndy Fiddaman			print -r -u2 "	$SHOW"
1135*b30d1939SAndy Fiddaman		fi
1136*b30d1939SAndy Fiddaman		if	[[ $TEST_keep ]]
1137*b30d1939SAndy Fiddaman		then	GROUP=FINI
1138*b30d1939SAndy Fiddaman			exit
1139*b30d1939SAndy Fiddaman		fi
1140*b30d1939SAndy Fiddaman	elif	[[ ! $TEST_quiet ]]
1141*b30d1939SAndy Fiddaman	then	SHOW=$NOTE
1142*b30d1939SAndy Fiddaman		print -r -u2 "	$SHOW"
1143*b30d1939SAndy Fiddaman	fi
1144*b30d1939SAndy Fiddaman}
1145*b30d1939SAndy Fiddaman
1146*b30d1939SAndy Fiddamanfunction SET # [no]name[=value]
1147*b30d1939SAndy Fiddaman{
1148*b30d1939SAndy Fiddaman	typeset i r
1149*b30d1939SAndy Fiddaman	if	[[ $TEST ]]
1150*b30d1939SAndy Fiddaman	then	RUN
1151*b30d1939SAndy Fiddaman	fi
1152*b30d1939SAndy Fiddaman	for i
1153*b30d1939SAndy Fiddaman	do	if	[[ $i == - ]]
1154*b30d1939SAndy Fiddaman		then	r=1
1155*b30d1939SAndy Fiddaman		elif	[[ $i == + ]]
1156*b30d1939SAndy Fiddaman		then	r=
1157*b30d1939SAndy Fiddaman		else	if	[[ $i == no?* ]]
1158*b30d1939SAndy Fiddaman			then	i=${i#no}
1159*b30d1939SAndy Fiddaman				v=
1160*b30d1939SAndy Fiddaman			elif	[[ $i == *=* ]]
1161*b30d1939SAndy Fiddaman			then	v=${i#*=}
1162*b30d1939SAndy Fiddaman				if	[[ $v == 0 ]]
1163*b30d1939SAndy Fiddaman				then	v=
1164*b30d1939SAndy Fiddaman				fi
1165*b30d1939SAndy Fiddaman				i=${i%%=*}
1166*b30d1939SAndy Fiddaman			else	v=1
1167*b30d1939SAndy Fiddaman			fi
1168*b30d1939SAndy Fiddaman			i=${i//-/_}
1169*b30d1939SAndy Fiddaman			if	[[ $r ]]
1170*b30d1939SAndy Fiddaman			then	READONLY[$i]=1
1171*b30d1939SAndy Fiddaman			elif	[[ ${READONLY[$i]} ]]
1172*b30d1939SAndy Fiddaman			then	continue
1173*b30d1939SAndy Fiddaman			fi
1174*b30d1939SAndy Fiddaman			eval TEST_$i=$v
1175*b30d1939SAndy Fiddaman		fi
1176*b30d1939SAndy Fiddaman	done
1177*b30d1939SAndy Fiddaman}
1178*b30d1939SAndy Fiddaman
1179*b30d1939SAndy Fiddamanfunction VIEW # var [ file ]
1180*b30d1939SAndy Fiddaman{
1181*b30d1939SAndy Fiddaman	nameref var=$1
1182*b30d1939SAndy Fiddaman	typeset i bwd file pwd view root offset
1183*b30d1939SAndy Fiddaman	if	[[ $var ]]
1184*b30d1939SAndy Fiddaman	then	return 0
1185*b30d1939SAndy Fiddaman	fi
1186*b30d1939SAndy Fiddaman	case $# in
1187*b30d1939SAndy Fiddaman	1)	file=$1 ;;
1188*b30d1939SAndy Fiddaman	*)	file=$2 ;;
1189*b30d1939SAndy Fiddaman	esac
1190*b30d1939SAndy Fiddaman	pwd=${TWD%/*}
1191*b30d1939SAndy Fiddaman	bwd=${PMP%/*}
1192*b30d1939SAndy Fiddaman	if	[[ -r $file ]]
1193*b30d1939SAndy Fiddaman	then	if	[[ ! -d $file ]]
1194*b30d1939SAndy Fiddaman		then	var=$PWD/$file
1195*b30d1939SAndy Fiddaman			return 0
1196*b30d1939SAndy Fiddaman		fi
1197*b30d1939SAndy Fiddaman		for i in $file/*
1198*b30d1939SAndy Fiddaman		do	if	[[ -r $i ]]
1199*b30d1939SAndy Fiddaman			then	var=$PWD/$file
1200*b30d1939SAndy Fiddaman				return 0
1201*b30d1939SAndy Fiddaman			fi
1202*b30d1939SAndy Fiddaman			break
1203*b30d1939SAndy Fiddaman		done
1204*b30d1939SAndy Fiddaman	fi
1205*b30d1939SAndy Fiddaman	for view in ${VIEWS[@]}
1206*b30d1939SAndy Fiddaman	do	case $view in
1207*b30d1939SAndy Fiddaman		/*)	;;
1208*b30d1939SAndy Fiddaman		*)	view=$pwd/$view ;;
1209*b30d1939SAndy Fiddaman		esac
1210*b30d1939SAndy Fiddaman		case $offset in
1211*b30d1939SAndy Fiddaman		'')	case $pwd in
1212*b30d1939SAndy Fiddaman			$view/*)	offset=${pwd#$view} ;;
1213*b30d1939SAndy Fiddaman			*)		offset=${bwd#$view} ;;
1214*b30d1939SAndy Fiddaman			esac
1215*b30d1939SAndy Fiddaman			;;
1216*b30d1939SAndy Fiddaman		esac
1217*b30d1939SAndy Fiddaman		if	[[ -r $view$offset/$file ]]
1218*b30d1939SAndy Fiddaman		then	if	[[ ! -d $view$offset/$file ]]
1219*b30d1939SAndy Fiddaman			then	var=$view$offset/$file
1220*b30d1939SAndy Fiddaman				return 0
1221*b30d1939SAndy Fiddaman			fi
1222*b30d1939SAndy Fiddaman			for i in $view$offset/$file/*
1223*b30d1939SAndy Fiddaman			do	if	[[ -f $i ]]
1224*b30d1939SAndy Fiddaman				then	var=$view$offset/$file
1225*b30d1939SAndy Fiddaman					return 0
1226*b30d1939SAndy Fiddaman				fi
1227*b30d1939SAndy Fiddaman				break
1228*b30d1939SAndy Fiddaman			done
1229*b30d1939SAndy Fiddaman		fi
1230*b30d1939SAndy Fiddaman	done
1231*b30d1939SAndy Fiddaman	var=
1232*b30d1939SAndy Fiddaman	return 1
1233*b30d1939SAndy Fiddaman}
1234*b30d1939SAndy Fiddaman
1235*b30d1939SAndy Fiddamanfunction INCLUDE # file ...
1236*b30d1939SAndy Fiddaman{
1237*b30d1939SAndy Fiddaman	typeset f v x
1238*b30d1939SAndy Fiddaman	for f
1239*b30d1939SAndy Fiddaman	do	if	VIEW v $f || [[ $PREFIX && $f != /* ]] && VIEW v $PREFIX$f
1240*b30d1939SAndy Fiddaman		then	x=$x$'\n'". $v"
1241*b30d1939SAndy Fiddaman		else	FATAL $f: not found
1242*b30d1939SAndy Fiddaman		fi
1243*b30d1939SAndy Fiddaman	done
1244*b30d1939SAndy Fiddaman	[[ $x ]] && trap "$x" 0
1245*b30d1939SAndy Fiddaman}
1246*b30d1939SAndy Fiddaman
1247*b30d1939SAndy Fiddamanfunction UMASK # [ mask ]
1248*b30d1939SAndy Fiddaman{
1249*b30d1939SAndy Fiddaman	if	(( $# ))
1250*b30d1939SAndy Fiddaman	then	UMASK=$1
1251*b30d1939SAndy Fiddaman	else	UMASK=$UMASK_ORIG
1252*b30d1939SAndy Fiddaman	fi
1253*b30d1939SAndy Fiddaman}
1254*b30d1939SAndy Fiddaman
1255*b30d1939SAndy Fiddamanfunction PIPE # INPUT|OUTPUT|ERROR file|- data ...
1256*b30d1939SAndy Fiddaman{
1257*b30d1939SAndy Fiddaman	IO $0 "$@"
1258*b30d1939SAndy Fiddaman}
1259*b30d1939SAndy Fiddaman
1260*b30d1939SAndy Fiddamanfunction FIFO # INPUT|OUTPUT|ERROR file|- data ...
1261*b30d1939SAndy Fiddaman{
1262*b30d1939SAndy Fiddaman	IO $0 "$@"
1263*b30d1939SAndy Fiddaman}
1264*b30d1939SAndy Fiddaman
1265*b30d1939SAndy Fiddamanfunction IF # command(s) [note]
1266*b30d1939SAndy Fiddaman{
1267*b30d1939SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1268*b30d1939SAndy Fiddaman	RUN
1269*b30d1939SAndy Fiddaman	(( COND++ ))
1270*b30d1939SAndy Fiddaman	COND_LINE[COND]=$LINE
1271*b30d1939SAndy Fiddaman	if	(( COND > 1 && COND_SKIP[COND-1] ))
1272*b30d1939SAndy Fiddaman	then	(( COND_KEPT[COND] = 1 ))
1273*b30d1939SAndy Fiddaman		(( COND_SKIP[COND] = 1 ))
1274*b30d1939SAndy Fiddaman	elif	eval "{ $1 ;} >/dev/null 2>&1"
1275*b30d1939SAndy Fiddaman	then	(( COND_KEPT[COND] = 1 ))
1276*b30d1939SAndy Fiddaman		(( COND_SKIP[COND] = 0 ))
1277*b30d1939SAndy Fiddaman		[[ $2 && ! $TEST_quiet ]] && print -u2 "NOTE	$2"
1278*b30d1939SAndy Fiddaman	else	(( COND_KEPT[COND] = 0 ))
1279*b30d1939SAndy Fiddaman		(( COND_SKIP[COND] = 1 ))
1280*b30d1939SAndy Fiddaman	fi
1281*b30d1939SAndy Fiddaman}
1282*b30d1939SAndy Fiddaman
1283*b30d1939SAndy Fiddamanfunction ELIF # command(s) [note]
1284*b30d1939SAndy Fiddaman{
1285*b30d1939SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1286*b30d1939SAndy Fiddaman	RUN
1287*b30d1939SAndy Fiddaman	if	(( COND <= 0 ))
1288*b30d1939SAndy Fiddaman	then	FATAL line $LINE: no matching IF for ELIF
1289*b30d1939SAndy Fiddaman	fi
1290*b30d1939SAndy Fiddaman	if	(( COND_KEPT[COND] ))
1291*b30d1939SAndy Fiddaman	then	(( COND_SKIP[COND] = 0 ))
1292*b30d1939SAndy Fiddaman	elif	eval "$* > /dev/null 2>&1"
1293*b30d1939SAndy Fiddaman	then	(( COND_KEPT[COND] = 1 ))
1294*b30d1939SAndy Fiddaman		(( COND_SKIP[COND] = 0 ))
1295*b30d1939SAndy Fiddaman		[[ $2 && ! $TEST_quiet ]] && print -u2 "NOTE	$2"
1296*b30d1939SAndy Fiddaman	else	(( COND_SKIP[COND] = 1 ))
1297*b30d1939SAndy Fiddaman	fi
1298*b30d1939SAndy Fiddaman}
1299*b30d1939SAndy Fiddaman
1300*b30d1939SAndy Fiddamanfunction ELSE # [note]
1301*b30d1939SAndy Fiddaman{
1302*b30d1939SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1303*b30d1939SAndy Fiddaman	RUN
1304*b30d1939SAndy Fiddaman	if	(( COND <= 0 ))
1305*b30d1939SAndy Fiddaman	then	FATAL line $LINE: no matching IF for ELSE
1306*b30d1939SAndy Fiddaman	fi
1307*b30d1939SAndy Fiddaman	if	(( COND_KEPT[COND] ))
1308*b30d1939SAndy Fiddaman	then	(( COND_SKIP[COND] = 1 ))
1309*b30d1939SAndy Fiddaman	else	(( COND_KEPT[COND] = 1 ))
1310*b30d1939SAndy Fiddaman		(( COND_SKIP[COND] = 0 ))
1311*b30d1939SAndy Fiddaman		[[ $1 && ! $TEST_quiet ]] && print -u2 "NOTE	$1"
1312*b30d1939SAndy Fiddaman	fi
1313*b30d1939SAndy Fiddaman}
1314*b30d1939SAndy Fiddaman
1315*b30d1939SAndy Fiddamanfunction FI
1316*b30d1939SAndy Fiddaman{
1317*b30d1939SAndy Fiddaman	[[ $GROUP == $TEST_select ]] || return
1318*b30d1939SAndy Fiddaman	RUN
1319*b30d1939SAndy Fiddaman	if	(( COND <= 0 ))
1320*b30d1939SAndy Fiddaman	then	FATAL line $LINE: no matching IF for FI on line $LINE
1321*b30d1939SAndy Fiddaman	fi
1322*b30d1939SAndy Fiddaman	(( ! COND_KEPT[COND] )) && [[ $1 && ! $TEST_quiet ]] && print -u2 "NOTE	$1"
1323*b30d1939SAndy Fiddaman	(( COND-- ))
1324*b30d1939SAndy Fiddaman}
1325*b30d1939SAndy Fiddaman
1326*b30d1939SAndy Fiddaman# main
1327*b30d1939SAndy Fiddaman
1328*b30d1939SAndy Fiddamaninteger ERRORS=0 ENVIRONS=0 EXPORTS=0 TESTS=0 SUBTESTS=0 LINE=0 TESTLINE=0
1329*b30d1939SAndy Fiddamaninteger ITEM=0 LASTITEM=0 COND=0 UNIT_READONLY=0 COUNT
1330*b30d1939SAndy Fiddamantypeset ARGS COMMAND COPY DIAGNOSTICS ERROR EXEC FLUSHED=0 GROUP=INIT
1331*b30d1939SAndy Fiddamantypeset IGNORE INPUT KEEP OUTPUT TEST SOURCE MOVE NOTE UMASK UMASK_ORIG
1332*b30d1939SAndy Fiddamantypeset ARGS_ORIG COMMAND_ORIG TITLE UNIT ARGV PREFIX OFFSET IGNORESPACE
1333*b30d1939SAndy Fiddamantypeset COMPARE MAIN JOBPID='' JOBSTATUS=''
1334*b30d1939SAndy Fiddamantypeset TEST_file TEST_keep TEST_pipe_input TEST_pipe_io TEST_pipe_output TEST_local
1335*b30d1939SAndy Fiddamantypeset TEST_quiet TEST_regular=1 TEST_rmflags='-rf --' TEST_rmu TEST_select
1336*b30d1939SAndy Fiddaman
1337*b30d1939SAndy Fiddamantypeset -A SAME VIEWS FILE TYPE READONLY FILTER
1338*b30d1939SAndy Fiddamantypeset -a COND_LINE COND_SKIP COND_KEPT ENVIRON EXPORT
1339*b30d1939SAndy Fiddamantypeset -Z LAST=00
1340*b30d1939SAndy Fiddaman
1341*b30d1939SAndy Fiddamanunset FIGNORE
1342*b30d1939SAndy Fiddaman
1343*b30d1939SAndy Fiddamanwhile	getopts -a $command "$USAGE" OPT
1344*b30d1939SAndy Fiddamando	case $OPT in
1345*b30d1939SAndy Fiddaman	b)	(( $OPTARG )) && IGNORESPACE=-b
1346*b30d1939SAndy Fiddaman		;;
1347*b30d1939SAndy Fiddaman	i)	SET - pipe-input=$OPTARG
1348*b30d1939SAndy Fiddaman		;;
1349*b30d1939SAndy Fiddaman	k)	SET - keep=$OPTARG
1350*b30d1939SAndy Fiddaman		;;
1351*b30d1939SAndy Fiddaman	l)	SET - local
1352*b30d1939SAndy Fiddaman		;;
1353*b30d1939SAndy Fiddaman	o)	SET - pipe-output=$OPTARG
1354*b30d1939SAndy Fiddaman		;;
1355*b30d1939SAndy Fiddaman	p)	SET - pipe-io=$OPTARG
1356*b30d1939SAndy Fiddaman		;;
1357*b30d1939SAndy Fiddaman	q)	SET - quiet=$OPTARG
1358*b30d1939SAndy Fiddaman		;;
1359*b30d1939SAndy Fiddaman	r)	SET - regular=$OPTARG
1360*b30d1939SAndy Fiddaman		;;
1361*b30d1939SAndy Fiddaman	t)	if	[[ $TEST_select ]]
1362*b30d1939SAndy Fiddaman		then	TEST_select="$TEST_select|${OPTARG//,/\|}"
1363*b30d1939SAndy Fiddaman		else	TEST_select="${OPTARG//,/\|}"
1364*b30d1939SAndy Fiddaman		fi
1365*b30d1939SAndy Fiddaman		;;
1366*b30d1939SAndy Fiddaman	x)	SET - trace=$OPTARG
1367*b30d1939SAndy Fiddaman		;;
1368*b30d1939SAndy Fiddaman	v)	SET - verbose=$OPTARG
1369*b30d1939SAndy Fiddaman		;;
1370*b30d1939SAndy Fiddaman	*)	GROUP=FINI
1371*b30d1939SAndy Fiddaman		exit 2
1372*b30d1939SAndy Fiddaman		;;
1373*b30d1939SAndy Fiddaman	esac
1374*b30d1939SAndy Fiddamandone
1375*b30d1939SAndy Fiddamanshift $OPTIND-1
1376*b30d1939SAndy Fiddamancase $# in
1377*b30d1939SAndy Fiddaman0)	FATAL test unit name omitted ;;
1378*b30d1939SAndy Fiddamanesac
1379*b30d1939SAndy Fiddamanexport COLUMNS=80
1380*b30d1939SAndy FiddamanSOURCE=$PWD
1381*b30d1939SAndy FiddamanPATH=$SOURCE:${PATH#?(.):}
1382*b30d1939SAndy FiddamanPATH=${PATH%%:?(.)}:/bin:/usr/bin
1383*b30d1939SAndy FiddamanUNIT=$1
1384*b30d1939SAndy Fiddamanshift
1385*b30d1939SAndy Fiddamanif	[[ -f $UNIT && ! -x $UNIT ]]
1386*b30d1939SAndy Fiddamanthen	REGRESS=$UNIT
1387*b30d1939SAndy Fiddamanelse	REGRESS=${UNIT%.tst}
1388*b30d1939SAndy Fiddaman	REGRESS=$REGRESS.tst
1389*b30d1939SAndy Fiddaman	[[ -f $REGRESS ]] || FATAL $REGRESS: regression tests not found
1390*b30d1939SAndy Fiddamanfi
1391*b30d1939SAndy FiddamanUNIT=${UNIT##*/}
1392*b30d1939SAndy FiddamanUNIT=${UNIT%.tst}
1393*b30d1939SAndy FiddamanMAIN=$UNIT
1394*b30d1939SAndy Fiddamanif	[[ $VPATH ]]
1395*b30d1939SAndy Fiddamanthen	set -A VIEWS ${VPATH//:/' '}
1396*b30d1939SAndy Fiddaman	OFFSET=${SOURCE#${VIEWS[0]}}
1397*b30d1939SAndy Fiddaman	if	[[ $OFFSET ]]
1398*b30d1939SAndy Fiddaman	then	OFFSET=${OFFSET#/}/
1399*b30d1939SAndy Fiddaman	fi
1400*b30d1939SAndy Fiddamanfi
1401*b30d1939SAndy Fiddamanif	[[ $REGRESS == */* ]]
1402*b30d1939SAndy Fiddamanthen	PREFIX=${REGRESS%/*}
1403*b30d1939SAndy Fiddaman	if	[[ ${#VIEWS[@]} ]]
1404*b30d1939SAndy Fiddaman	then	for i in ${VIEWS[@]}
1405*b30d1939SAndy Fiddaman		do	PREFIX=${PREFIX#$i/}
1406*b30d1939SAndy Fiddaman		done
1407*b30d1939SAndy Fiddaman	fi
1408*b30d1939SAndy Fiddaman	PREFIX=${PREFIX#$OFFSET}
1409*b30d1939SAndy Fiddaman	if	[[ $PREFIX ]]
1410*b30d1939SAndy Fiddaman	then	PREFIX=$PREFIX/
1411*b30d1939SAndy Fiddaman	fi
1412*b30d1939SAndy Fiddamanfi
1413*b30d1939SAndy FiddamanTWD=$PWD/$UNIT.tmp
1414*b30d1939SAndy FiddamanPMP=$(pwd -P)/$UNIT.tmp
1415*b30d1939SAndy FiddamanUMASK_ORIG=$(umask)
1416*b30d1939SAndy FiddamanUMASK=$UMASK_ORIG
1417*b30d1939SAndy FiddamanARGV=("$@")
1418*b30d1939SAndy Fiddamanif	[[ ${ARGV[0]} && ${ARGV[0]} != [-+]* ]]
1419*b30d1939SAndy Fiddamanthen	UNIT "${ARGV[@]}"
1420*b30d1939SAndy Fiddaman	UNIT_READONLY=1
1421*b30d1939SAndy Fiddamanfi
1422*b30d1939SAndy Fiddamantrap 'code=$?; CLEANUP $code' EXIT
1423*b30d1939SAndy Fiddamanif	[[ ! $TEST_select ]]
1424*b30d1939SAndy Fiddamanthen	TEST_select="[0123456789]*"
1425*b30d1939SAndy Fiddamanfi
1426*b30d1939SAndy FiddamanTEST_select="@($TEST_select|+(0))"
1427*b30d1939SAndy Fiddamanif	[[ $TEST_trace ]]
1428*b30d1939SAndy Fiddamanthen	export PS4=':$LINENO: '
1429*b30d1939SAndy Fiddaman	typeset -ft $(typeset +f)
1430*b30d1939SAndy Fiddaman	set -x
1431*b30d1939SAndy Fiddamanfi
1432*b30d1939SAndy Fiddamanif	[[ $TEST_verbose ]]
1433*b30d1939SAndy Fiddamanthen	typeset SHOW
1434*b30d1939SAndy Fiddamanelse	typeset -L70 SHOW
1435*b30d1939SAndy Fiddamanfi
1436*b30d1939SAndy Fiddamanif	[[ ! $TEST_keep ]] && (ulimit -c 0) >/dev/null 2>&1
1437*b30d1939SAndy Fiddamanthen	ulimit -c 0
1438*b30d1939SAndy Fiddamanfi
1439*b30d1939SAndy Fiddamanset --pipefail
1440*b30d1939SAndy Fiddaman
1441*b30d1939SAndy Fiddaman# some last minute shenanigans
1442*b30d1939SAndy Fiddaman
1443*b30d1939SAndy Fiddamanalias BODY='BODY=BODY; function BODY'
1444*b30d1939SAndy Fiddamanalias CONTINUE='LINE=$LINENO; CONTINUE'
1445*b30d1939SAndy Fiddamanalias DO='(( $ITEM != $FLUSHED )) && RUN DO; DO &&'
1446*b30d1939SAndy Fiddamanalias DONE='DONE=DONE; function DONE'
1447*b30d1939SAndy Fiddamanalias EXEC='LINE=$LINENO; EXEC'
1448*b30d1939SAndy Fiddamanalias EXITED='LINE=$LINENO; EXITED'
1449*b30d1939SAndy Fiddamanalias INIT='INIT=INIT; function INIT'
1450*b30d1939SAndy Fiddamanalias JOB='LINE=$LINENO; JOB'
1451*b30d1939SAndy Fiddamanalias KILL='LINE=$LINENO; KILL'
1452*b30d1939SAndy Fiddamanalias PROG='LINE=$LINENO; FLUSH; PROG'
1453*b30d1939SAndy Fiddamanalias TEST='TESTLINE=$LINENO; TEST'
1454*b30d1939SAndy Fiddamanalias IF='LINE=$LINENO; FLUSH; IF'
1455*b30d1939SAndy Fiddamanalias ELIF='LINE=$LINENO; FLUSH; ELIF'
1456*b30d1939SAndy Fiddamanalias ELSE='LINE=$LINENO; FLUSH; ELSE'
1457*b30d1939SAndy Fiddamanalias FI='LINE=$LINENO; FLUSH; FI'
1458*b30d1939SAndy Fiddaman
1459*b30d1939SAndy Fiddaman# do the tests
1460*b30d1939SAndy Fiddaman
1461*b30d1939SAndy Fiddaman. $REGRESS
1462*b30d1939SAndy FiddamanRUN
1463*b30d1939SAndy FiddamanGROUP=FINI
1464