]> mj.ucw.cz Git - eval.git/blob - bin/lib
ccb0b9cf6eeccd2f673a080f3306b9e0915a6f7e
[eval.git] / bin / lib
1 # The Evaluator -- Shell Function Library
2 # (c) 2001 Martin Mares <mj@ucw.cz>
3
4 # General settings
5 shopt -s dotglob
6
7 # Logging functions.
8 # File handles used: fd1=log, fd2=progress
9
10 function log-init
11 {
12         exec >>$TDIR/log
13         HAVE_LOG=1
14 }
15
16 function pstart
17 {
18         echo >&2 -n "$@"
19 }
20
21 function pcont
22 {
23         echo >&2 -n "$@"
24 }
25
26 function pend
27 {
28         echo >&2 "$@"
29 }
30
31 function die
32 {
33         echo >&2 "$@"
34         [ -n "$HAVE_LOG" ] && echo "Fatal error: $@"
35         exit 1
36 }
37
38 # Sandbox subroutines
39
40 function box-init
41 {
42         pstart "Preparing sandbox... "
43         [ -n "$TEST_USER" ] || die "TEST_USER not set. Please fix."
44         if [ $TEST_USER == $EVAL_USER ] ; then
45                 pcont "running locally (INSECURE), "
46                 BOXDIR=box
47                 BOXCMD=bin/box
48                 mkdir -p box
49         else
50                 pcont "used account $TEST_USER, "
51                 BOXDIR=$MO_ROOT/$TEST_USER
52                 BOXCMD=bin/box-$TEST_USER
53         fi
54         [ -d $BOXDIR -a -f $BOXCMD ] || die "Sandbox set up incorrectly"
55         BOXCMD="$BOXCMD -c$BOXDIR"
56         echo "Sandbox directory: $BOXDIR"
57         echo "Sandbox command: $BOXCMD"
58         box-clean
59         pend "OK"
60 }
61
62 function box-clean
63 {
64         [ -n "$BOXCMD" ] || die "box-init not called"
65         rm -rf $BOXDIR/*
66 }
67
68 # Initialization of testing directories
69
70 function dir-init
71 {
72         pstart "Initializing... "
73         PDIR=problems/$PROBLEM
74         SDIR=solutions/$CONTESTANT/$PROBLEM
75         TDIR=testing/$CONTESTANT/$PROBLEM
76         [ -d $PDIR ] || die "Problem $PROBLEM not known"
77         [ -d $SDIR ] || die "Solution of $PROBLEM not found"
78         mkdir -p $TDIR
79         rm -rf $TDIR
80         cp -a $SDIR $TDIR
81         cat >$TDIR/log <<EOF
82 Testing solution of $PROBLEM by $CONTESTANT
83 Test started at `date`
84 Contestant's solution directory: $SDIR
85 Problem directory: $PDIR
86 Testing directory: $TDIR
87 EOF
88         >$TDIR/points
89         pend "OK"
90 }
91
92 # Locating source file in SDIR, pass name in SRCN (without path) and extension in SRCEXT
93
94 function locate-source
95 {
96         pstart "Finding source... "
97         SBASE=${1:-$PROBLEM}
98         for a in $EXTENSIONS ; do
99                 if [ -f $SDIR/$SBASE.$a ] ; then
100                         [ -z "$SRCN" ] || die "Multiple source files found: $SDIR/$PROBLEM.$a and $SDIR/$SRCN. Please fix."
101                         SRCN=$SBASE.$a
102                         SRCEXT=$a
103                 fi
104         done
105         [ -n "$SRCN" ] || die "NOT FOUND"
106         pend $SRCN
107         echo "Found source file: $SDIR/$SRCN"
108 }
109
110 # Compilation (compile SDIR/SRCN with PDIR/EXTRAS to EXE=TDIR/PROBLEM)
111
112 function compile
113 {
114         pstart "Compiling... "
115         cp -a $SDIR/$SRCN $TDIR/$SRCN
116         if [ -n "$EXTRAS" ] ; then
117                 echo "Extras: $EXTRAS"
118                 for a in $EXTRAS ; do cp $PDIR/$a $TDIR/ ; done
119         fi
120         box-clean
121         for a in $SRCN $EXTRAS ; do cp $TDIR/$a $BOXDIR/ ; done
122         SRC=$SRCN
123         EXE=$PROBLEM
124         CCMD=COMP_$SRCEXT
125         CCMD="`eval echo ${!CCMD}`"
126         COMP_SANDBOX_OPTS="`eval echo $COMP_SANDBOX_OPTS`"
127         echo "Compiler command: $CCMD"
128         echo "Compiler sandbox options: $COMP_SANDBOX_OPTS"
129
130         echo "Compiler input files:"
131         ls -Al $BOXDIR
132         echo "Compiler output:"
133         if ! $BOXCMD $COMP_SANDBOX_OPTS -- $CCMD 2>$TDIR/compile.out ; then
134                 COMPILE_MSG="`cat $TDIR/compile.out`"
135                 pend "FAILED: $COMPILE_MSG"
136                 echo "$COMPILE_MSG"
137                 return 1
138         fi
139         cat $TDIR/compile.out
140         rm $TDIR/compile.out
141         echo "Compiler output files:"
142         ls -Al $BOXDIR
143         if [ ! -f $BOXDIR/$PROBLEM ] ; then
144                 pend "FAILED: Missing executable file"
145                 echo "Missing executable file"
146                 return 1
147         fi
148         EXE=$TDIR/$PROBLEM
149         cp -a $BOXDIR/$PROBLEM $EXE
150         echo "Compiled OK, result copied to $EXE"
151         pend "OK"
152 }
153
154 # Running of test program according to current task type
155
156 function test-run
157 {
158         test-run-$TASK_TYPE
159 }
160
161 # Running of test program with file input/output
162
163 function test-run-file
164 {
165         pcont "<init> "
166         box-clean
167         echo "Executable file: $TDIR/$PROBLEM"
168         cp $TDIR/$PROBLEM $BOXDIR/
169         echo "Input: $TDIR/$PROBLEM"
170         ln $PDIR/$TEST.in $TDIR/$TEST.in
171         cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
172         echo "Input files:"
173         ls -Al $BOXDIR
174
175         pcont "<run> "
176         echo "Timeout: $TIME_LIMIT s"
177         echo "Memory: $MEM_LIMIT KB"
178         BOXOPTS="`eval echo $TEST_SANDBOX_OPTS`"
179         echo "Sandbox options: $BOXOPTS"
180         if ! $BOXCMD $BOXOPTS -- ./$PROBLEM 2>$TDIR/exec.out ; then
181                 TEST_MSG="`cat $TDIR/exec.out`"
182                 pend "$TEST_MSG"
183                 echo "$TEST_MSG"
184                 echo >>$PTSFILE "0 $TEST_MSG"
185                 return 1
186         fi
187         cat $TDIR/exec.out
188         rm $TDIR/exec.out
189         echo "Output files:"
190         ls -Al $BOXDIR
191         if [ ! -s $BOXDIR/$PROBLEM.out ] ; then
192                 pend "No output file."
193                 echo "No output file."
194                 echo >>$PTSFILE "0 No output."
195                 return 1
196         fi
197         cp $BOXDIR/$PROBLEM.out $TDIR/$TEST.out
198 }
199
200 # Running of interactive test programs
201
202 function test-run-interactive
203 {
204         pcont "<init> "
205         box-clean
206         echo "Executable file: $TDIR/$PROBLEM"
207         cp $TDIR/$PROBLEM $BOXDIR/
208         echo "Input: $TDIR/$PROBLEM"
209         ln $PDIR/$TEST.in $TDIR/$TEST.in
210         cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
211         echo "Input files:"
212         ls -Al $BOXDIR
213
214         pcont "<run> "
215         echo "Timeout: $TIME_LIMIT s"
216         echo "Memory: $MEM_LIMIT KB"
217         BOXOPTS="`eval echo $TEST_SANDBOX_OPTS`"
218         echo "Sandbox options: $BOXOPTS"
219         ICCMD="`eval echo $IA_CHECK`"
220         echo "Interactive checker: $ICCMD"
221         if ! bin/iwrapper $BOXCMD $BOXOPTS -- ./$PROBLEM @@ $ICCMD 2>$TDIR/exec.out ; then
222                 TEST_MSG="`cat $TDIR/exec.out`"
223                 pend "$TEST_MSG"
224                 echo "$TEST_MSG"
225                 echo >>$PTSFILE "0 $TEST_MSG"
226                 return 1
227         fi
228         cat $TDIR/exec.out
229         rm $TDIR/exec.out
230 }
231
232 # Syntax checks
233
234 function syntax-check
235 {
236         [ -n "$SYNTAX_CHECK" ] || return 0
237         pcont "<syntax> "
238         SCHECK="`eval echo $SYNTAX_CHECK`"
239         echo "Syntax check command: $SCHECK"
240         $SCHECK && return 0
241         pend "Wrong syntax."
242         echo "Wrong syntax."
243         echo >>$PTSFILE "0 Wrong syntax."
244         return 1
245 }
246
247 # Output checks
248
249 function output-check
250 {
251         [ -n "$OUTPUT_CHECK" ] || return 0
252         pcont "<check> "
253         ln $PDIR/$TEST.out $TDIR/$TEST.ok
254         OCHECK="`eval echo $OUTPUT_CHECK`"
255         echo "Output check command: $OCHECK"
256         $OCHECK && return 0
257         pend "Wrong answer."
258         echo "Wrong answer."
259         echo >>$PTSFILE "0 Wrong answer."
260         return 1
261 }
262
263 # Setup of public commands
264
265 function public-setup
266 {
267         PDIR=$MO_PUBLIC/problems/$PROBLEM
268         SDIR=.
269         TDIR=~/.test
270         [ -d $PDIR ] || die "Unknown problem $PROBLEM"
271
272         pstart "Initializing... "
273         mkdir -p $TDIR
274         rm -rf $TDIR/*
275         BOXDIR=~/.box
276         mkdir -p $BOXDIR
277         rm -rf $BOXDIR/*
278         BOXCMD="$MO_PUBLIC/bin/box -c$BOXDIR"
279         exec >log
280         pend "OK  (see 'log' for details)"
281 }