source: git/factory/fex/runfex @ 5df7d0

fieker-DuValspielwiese
Last change on this file since 5df7d0 was 341696, checked in by Hans Schönemann <hannes@…>, 15 years ago
Adding Id property to all files git-svn-id: file:///usr/local/Singular/svn/trunk@12231 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 11.3 KB
Line 
1#! /bin/bash
2# $Id$
3
4#{{{ docu
5#
6# runfex - run factory example collection.
7#
8#}}}
9
10set -o nounset
11set -o noglob
12
13trap signalHandlerInterrupt SIGINT
14trap signalHandlerQuit SIGQUIT
15
16#
17# - functions.
18#
19
20#{{{ signalHandlerInterrupt (), signalHandlerQuit ()
21#{{{ docu
22#
23# signalHandler*() - catch signals.
24#
25#}}}
26signalHandlerInterrupt()
27{
28    warn "received signal SIGINT"
29    exit
30}
31
32signalHandlerQuit()
33{
34    warn "received signal SIGQUIT"
35    exit
36}
37#}}}
38
39#{{{ warn ()
40#{{{ docu
41#
42# warn() - print arguments to stderr prefixed by ExecName.
43#
44# ExecName (global constant): name of the shell script
45#   being executed
46#
47#}}}
48readonly ExecName="$0"
49
50warn()
51{
52    echo "$ExecName:" "${@-}" >&2
53}
54#}}}
55
56#{{{ usage ()
57usage()
58{
59echo "
60Usage: runfex [<options>] [<factoryOpts>] [<factoryEnvSpec>] <fexFile> [<examplePatterns>]
61
62Runs all examples in <fexFile> matching <examplePattern>.
63<examplePatterns> should be regular shell patterns, which may be
64preceded by a \`^' to exclude all examples matching <examplePattern>.
65
66When run in foreground, SIGQUIT immediately interrupts \`runfex',
67while SIGINT only interrupts the example currently being
68calculated.  In background, SIGTERM interrupts \`runfex' after the
69current example has been finished.
70
71<options>:  -d:         debug mode.  In debug mode, examples are
72                        echoed to stdout instead of being executed.
73            -C <runConfiguration>: specifies which object/executable
74                        configuration to use.  Defaults to \`opt'.
75            -t:         do not run checks
76
77Besides from regular shell commands, the commands \`collection'
78and \`example' may be used in a Factory example file.
79\`collection' specifies options and environment common to a
80collection of examples, \`example' defines an example.
81
82collection <collectionName> [<collectionOptions>] [<factoryOpts>] [<factoryEnvSpec>]
83example <exampleName> [<exampleOptions>] [<factoryOpts>] [<factoryEnvSpec>] <example>
84
85<collectionOptions>/<exampleOptions>:
86            -n <note>: specifies comment on the collection/example
87
88<factoryOpts>:
89            -a <time>:  sets alarm option
90            -c <times>: sets times option
91            -O <options>: specifies optional arguments
92            -o <outputOptions>: specifies which results to print
93
94<outputOptions>:
95            <number>: column width              x: do not print anything
96            h: header                           p: characteristic
97            s: switches                         v: variables
98            n: number fo runs                   g: random generator seed
99            f: Factories version                t: time
100            c: check                            r: result" \
101    >& 2
102}
103#}}}
104
105#{{{ defineSkip ()
106#{{{ docu
107#
108# defineSkip() - define function skipExample().
109#
110# rest: the patterns
111#
112# One function at least that does not use neither global
113# variables nor constants.
114#
115#}}}
116defineSkip()
117{
118    typeset regExp=""
119    typeset notRegExp=""
120    typeset rawArg arg
121
122    for rawArg; do
123        # check for leading ^
124        arg="${rawArg#^}"
125        if [ "$rawArg" = "$arg" ]; then
126            regExp="$regExp|$arg"
127        else
128            notRegExp="$notRegExp|$arg"
129        fi
130        shift
131    done
132    regExp="${regExp#|}"
133    notRegExp="${notRegExp#|}"
134
135    if [ -z "$regExp" -a -z "$notRegExp" ]; then
136        eval "
137skipExample()
138{
139    return 1
140}
141"
142    elif [ -n "$regExp" -a -z "$notRegExp" ]; then
143        eval "
144skipExample()
145{
146    case \"\$1\" in
147        ($regExp) return 1 ;;
148        (*) return 0 ;;
149    esac
150}
151"
152    elif [ -z "$regExp" -a -n "$notRegExp" ]; then
153        eval "
154skipExample()
155{
156    case \"\$1\" in
157        ($notRegExp) return 0 ;;
158        (*) return 1 ;;
159    esac
160}
161"
162    else
163        eval "
164skipExample()
165{
166    case \"\$1\" in
167        ($notRegExp) return 0 ;;
168        ($regExp) return 1 ;;
169        (*) return 0 ;;
170    esac
171}
172"
173    fi
174}
175#}}}
176
177#{{{ runAlgorithm ()
178#{{{ docu
179#
180# runAlgorithm() - run algorithm with the correct options.
181#
182# To a pity, there is a lot of global variables necessary to
183# determine the "correct options".  The run* variables are set
184# in main program, the collection* variables in collection()
185# and the example* variables in example().
186# All of these variables are exclusively used here.
187#
188# $1: debugMode
189# $2: algorithm to run
190# rest: its arguments
191#
192# runConfiguration (global variable): which configurations'
193#   executables to use
194# run* (global variables): options, optional arguments, and
195#   environment specified at run level
196# collection* (global variables): options, optional arguments,
197#   and environment specified at collection level
198# example* (global variables): options, optional arguments,
199#   and environment specified at example level
200#
201#}}}
202runConfiguration="opt"
203
204runOptions=""
205runOptArguments=""
206runEnvironment=""
207
208collectionOptions=""
209collectionOptArguments=""
210collectionEnvironment=""
211
212exampleOptions=""
213exampleOptArguments=""
214exampleEnvironment=""
215
216runAlgorithm()
217{
218    typeset debugMode="$1" \
219            name="$2"
220    shift 2
221
222    # now its time to paste the options together
223    $debugMode "$name.$runConfiguration" \
224        $collectionOptions $exampleOptions $runOptions -oa -- \
225        $collectionEnvironment $exampleEnvironment $runEnvironment \
226        ${runOptArguments:-${exampleOptArguments:-${collectionOptArguments}}} \
227        "$@"
228}
229#}}}
230
231#{{{ printData ()
232#{{{ docu
233#
234# printData() - print example data.
235#
236# Yet another bunch of global variables.  The *OutputOptions are
237# set by the main program, collection(), and example(), resp.,
238# and determine which information to print.  All the variables
239# are used exclusively here.
240#
241# $1: name
242# $2: note
243#
244# defColWidth (global constant): default width to print results
245# *OutputOptions (global variables): which information to print
246#
247#}}}
248typeset -ir defColWidth=80
249
250runOutputOptions=""
251collectionOutputOptions=""
252exampleOutputOptions=""
253
254printData()
255{
256    typeset -i colWidth
257
258    typeset name="$1" \
259            note="$2" \
260            options="${runOutputOptions:-${exampleOutputOptions:-${collectionOutputOptions}}}" \
261            line=""
262
263    # get column width (we use line as a dummy here)
264    line="$( echo "$options" | sed s/[^0-9]//g )"
265    colWidth=${line:-$defColWidth}
266
267    case "$options" in
268        (*x*) return ;;
269    esac
270
271    case "$options" in
272        (*h*)
273            # do some pretty printing
274            if [ ${#name} -lt 7 ]; then
275                echo "$name:            $note."
276            elif  [ ${#name} -lt 15 ]; then
277                echo "$name:    $note."
278            else
279                echo "$name: $note."
280            fi ;;
281    esac
282    if read line; then case "$options" in
283        (*p*) echo "$line" ;;
284    esac; fi
285    if read line; then case "$options" in
286        (*s*) echo "$line" ;;
287    esac; fi
288    if read line; then case "$options" in
289        (*v*) echo "$line" ;;
290    esac; fi
291    if read line; then case "$options" in
292        (*n*) echo "$line" ;;
293    esac; fi
294    if read line; then case "$options" in
295        (*g*) echo "$line" ;;
296    esac; fi
297    if read line; then case "$options" in
298        (*f*) echo "$line" ;;
299    esac; fi
300    if read line; then case "$options" in
301        (*t*) echo "$line" ;;
302    esac; fi
303    if read line; then case "$options" in
304        (*c*) echo "$line" ;;
305    esac; fi
306
307    # format the result
308    case "$options" in
309        (*r*)
310            if [ $colWidth = 0 ]; then
311                cat -u
312            else
313                fold -s -w "$colWidth"
314            fi ;;
315    esac
316}
317#}}}
318
319#{{{ example ()
320#{{{ docu
321#
322# example() - run an example.
323#
324# Sets the example* variables from the commandline.  Runs the
325# example in dependency on debugMode and on the result of
326# skipExample().  Collects data from the example in the alg*
327# variables for printData().
328#
329# debugMode (global variable): set by main program.  Whether to
330#   run examples or to print them.
331#
332#}}}
333debugMode=""
334
335example()
336{
337    typeset name="" \
338            note="" \
339            \
340            options="" \
341            optArguments="" \
342            environment="" \
343            \
344            outputOptions=""
345
346    # read example name and skip if necessary
347    if [ "$#" = "0" ]; then
348        warn "no example name specified"
349        exit 1
350    fi
351    name="$1"
352    shift
353
354    if skipExample "$name"; then
355        if [ -n "$debugMode" ]; then
356            echo "skipping $name"
357        fi
358        return
359    else
360        warn "running $name"
361    fi
362   
363    # read options
364    typeset opt
365    while getopts "n:a:c:O:o:" opt; do
366        case "$opt" in
367            (n) note="$OPTARG" ;;
368            (a) options="$options -a$OPTARG" ;;
369            (c) options="$options -c$OPTARG" ;;
370            (O) optArguments="$optArguments $OPTARG" ;;
371            (o) outputOptions="$OPTARG" ;;
372            (?) warn "bad example option"; exit 1 ;;
373        esac
374    done
375    # shift options and reset OPTIND
376    typeset -i optind
377    optind=OPTIND-1
378    shift $optind
379    OPTIND=1
380
381    # read environment
382    while [ "${1-}" != "${1+${1#/}}" ]; do
383        environment="$environment $1"
384        shift
385    done
386
387    # set global variables
388    exampleOptions="$options"
389    exampleOptArguments="$optArguments"
390    exampleEnvironment="$environment"
391    exampleOutputOptions="$outputOptions"
392
393    # run algorithm and print data
394    if [ -n "$debugMode" ]; then
395        runAlgorithm "echo" "$@"
396    else
397        runAlgorithm "" "$@" | printData "$name" "$note"
398    fi
399}
400#}}}
401
402#{{{ collection ()
403#{{{ docu
404#
405# collection() - set up collection data.
406#
407# Sets the collection* variables from commandline.
408#
409#}}}
410collection()
411{
412    typeset options="" \
413            optArguments="" \
414            environment="" \
415            \
416            outputOptions="" \
417   
418    # read collection name (and ignore it)
419    if [ "$#" = "0" ]; then
420        warn "no collection name specified"
421        exit 1
422    fi
423    shift
424
425    # read options
426    typeset opt
427    while getopts "n:a:c:O:o:" opt; do
428        case "$opt" in
429            (n) : ;;
430            (a) options="$options -a$OPTARG" ;;
431            (c) options="$options -c$OPTARG" ;;
432            (O) optArguments="$optArguments $OPTARG" ;;
433            (o) outputOptions="$OPTARG" ;;
434            (?) warn "bad collection option"; exit 1 ;;
435        esac
436    done
437    # shift options and reset OPTIND
438    typeset -i optind
439    optind=OPTIND-1
440    shift $optind
441    OPTIND=1
442
443    # read environment
444    while [ "${1-}" != "${1+${1#/}}" ]; do
445        environment="$environment $1"
446        shift
447    done
448
449    # set global variables
450    collectionOptions="$options"
451    collectionOptArguments="$optArguments"
452    collectionEnvironment="$environment"
453    collectionOutputOptions="$outputOptions"
454}
455#}}}
456
457#{{{ main program
458#{{{ docu
459#
460# - main program.
461#
462# Sets the run* variables for runAlgorithm() and printData()
463# from commandline.  Sets debugMode for example().  Reads the
464# collection.
465#
466#}}}
467typeset configuration="opt" \
468        \
469        options="" \
470        optArguments="" \
471        environment="" \
472        \
473        outputOptions="" \
474        \
475        fexFile=""
476
477# read options
478typeset opt
479while getopts "dC:ta:c:O:o:" opt; do
480    case "$opt" in
481        (d)  debugMode="1" ;;
482        (C)  configuration="$OPTARG" ;;
483        (t)  options="$options -t" ;;
484        (a)  options="$options -a$OPTARG" ;;
485        (c)  options="$options -c$OPTARG" ;;
486        (O)  optArguments="$optArguments $OPTARG" ;;
487        (o)  outputOptions="$OPTARG" ;;
488        (?)  warn "bad run option"; usage; exit 1 ;;
489    esac
490done
491# shift options and reset OPTIND
492typeset -i optind
493optind=OPTIND-1
494shift $optind
495OPTIND=1
496
497# read environment
498while [ "${1-}" != "${1+${1#/}}" ]; do
499    environment="$environment $1"
500    shift
501done
502
503# process rest of arguments
504if [ "$#" = "0" ]; then
505    warn "no fexFile specified"
506    usage
507    exit 1
508fi
509fexFile="${1%.fex}"
510shift
511
512defineSkip "$@"
513
514# before going on, check for existence of collection
515if [ ! -f "$fexFile.fex" ]; then
516    warn "collection $fexFile.fex not found"
517    exit 1
518fi
519
520# reset factory environemnt to exclude external influences
521FTEST_ENV=""
522FTEST_CIRCLE=""
523FTEST_ALARM=""
524
525# set global variables and execute collection
526runConfiguration="$configuration"
527runOptions="$options"
528runOptArguments="$optArguments"
529runEnvironment="$environment"
530runOutputOptions="$outputOptions"
531
532. "$fexFile.fex"
533#}}}
Note: See TracBrowser for help on using the repository browser.