1 # The Evaluator -- Shell Function Library
2 # (c) 2001--2004 Martin Mares <mj@ucw.cz>
8 # File handles used: fd1=log, fd2=progress
33 # Report an internal error
35 [ -n "$HAVE_LOG" ] && echo "Fatal error: $@"
41 # Report a fatal error in the program being tested
43 [ -n "$HAVE_LOG" ] && echo "Fatal error: $@"
49 ln $1 $2 2>/dev/null || cp $1 $2
56 pstart "Preparing sandbox... "
57 if [ -z "$TEST_USER" -o "$TEST_USER" == $EVAL_USER ] ; then
58 pcont "running locally (INSECURE), "
64 pcont "used account $TEST_USER, "
65 BOXDIR=$MO_ROOT/eval/$TEST_USER
66 BOXCMD=bin/box-$TEST_USER
68 [ -d $BOXDIR -a -f $BOXCMD ] || die "Sandbox set up incorrectly"
69 BOXCMD="$BOXCMD -c$BOXDIR"
70 echo "Sandbox directory: $BOXDIR"
71 echo "Sandbox command: $BOXCMD"
78 [ -n "$BOXCMD" ] || die "box-init not called"
82 # Initialization of testing directories
86 pstart "Initializing... "
88 PDIR=problems/$PROBLEM
89 SDIR=solutions/$CONTESTANT/$PROBLEM
90 TDIR=testing/$CONTESTANT/$PROBLEM
92 [ -d $PDIR ] || die "Problem $PROBLEM not known"
93 [ -d $SDIR ] || fatal "Solution of $PROBLEM not found"
94 mkdir -p $TDIR $TMPDIR
96 mkdir -p $TDIR $TMPDIR
98 Testing solution of $PROBLEM by $CONTESTANT
99 Test started at `date`
100 Contestant's solution directory: $SDIR
101 Problem directory: $PDIR
102 Testing directory: $TDIR
107 # Locating source file in SDIR, pass name in SRCN (without path) and extension in SRCEXT
109 function locate-source
111 pstart "Finding source... "
112 if [ -n "$1" ] ; then
113 SRCBASE=$(echo $1 | sed 's/\.\([^.]\+\)//')
114 SRCEXT=$(echo $1 | sed 's/.*\.\([^.]\+\)/\1/')
115 if [ -n "$SRCEXT" ] ; then
116 # Full name given, so just check the extension and existence
118 if [ ${SRCN:0:1} == / ] ; then
122 [ -f "$SDIR/$SRCN" ] || die "Cannot find source file $SDIR/$SRCN"
124 for a in $EXTENSIONS ; do
125 if [ $a == $SRCEXT ] ; then
127 echo "Explicitly set source file: $SDIR/$SRCN"
131 die "Unknown extension .$SRCEXT"
136 for a in $EXTENSIONS ; do
137 if [ -f $SDIR/$SBASE.$a ] ; then
138 [ -z "$SRCN" ] || die "Multiple source files found: $SDIR/$PROBLEM.$a and $SDIR/$SRCN. Please fix."
143 [ -n "$SRCN" ] || fatal "NOT FOUND"
145 echo "Found source file: $SDIR/$SRCN"
148 # Compilation (compile SDIR/SRCN with PDIR/COMP_EXTRAS to EXE=TDIR/PROBLEM)
152 pstart "Compiling... "
153 # Beware, the original SRCN can be a strange user-supplied name
155 cp -a $SDIR/$SRCN $TDIR/$SRC
156 if [ -n "$COMP_EXTRAS" ] ; then
157 echo "Extras: $COMP_EXTRAS"
158 for a in $COMP_EXTRAS ; do cp $PDIR/$a $TDIR/ ; done
161 for a in $SRC $COMP_EXTRAS ; do cp $TDIR/$a $BOXDIR/ ; done
164 CCMD=`eval echo ${!CCMD}`
165 COMP_SANDBOX_OPTS=`eval echo $COMP_SANDBOX_OPTS`
166 echo "Compiler command: $CCMD"
167 echo "Compiler sandbox options: $COMP_SANDBOX_OPTS"
168 eval $COMP_SANDBOX_INIT
170 echo "Compiler input files:"
172 echo "Compiler output:"
173 if ! $BOXCMD $COMP_SANDBOX_OPTS -- $CCMD 2>$TDIR/compile.out ; then
174 COMPILE_MSG="`cat $TDIR/compile.out`"
175 pend "FAILED: $COMPILE_MSG"
179 cat $TDIR/compile.out
181 echo "Compiler output files:"
183 if [ ! -f $BOXDIR/$PROBLEM ] ; then
184 pend "FAILED: Missing executable file"
185 echo "Missing executable file"
189 cp -a $BOXDIR/$PROBLEM $EXE
190 echo "Compiled OK, result copied to $EXE"
194 # Running of test program according to current task type (returns exit code and TEST_MSG)
205 if [ -s $TDIR/$TEST.pts ] ; then
206 P=`cat $TDIR/$TEST.pts`
218 echo "Executable file: $TDIR/$PROBLEM"
219 if [ ! -x $TDIR/$PROBLEM ] ; then
220 test-result 0 "Compile error."
222 cp $TDIR/$PROBLEM $BOXDIR/
224 IN_TYPE=${IN_TYPE:-$IO_TYPE}
225 OUT_TYPE=${OUT_TYPE:-$IO_TYPE}
227 file) echo "Input file: $PROBLEM.in (from $PDIR/$TEST.in)"
228 try-ln $PDIR/$TEST.in $TDIR/$TEST.in
229 cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
230 [ $TASK_TYPE == interactive ] || BOX_EXTRAS="$BOX_EXTRAS -i/dev/null"
232 stdio) echo "Input file: <stdin> (from $PDIR/$TEST.in)"
233 try-ln $PDIR/$TEST.in $TDIR/$TEST.in
234 cp $PDIR/$TEST.in $BOXDIR/.stdin
235 BOX_EXTRAS="$BOX_EXTRAS -i.stdin"
237 none) echo "Input file: <none>"
239 *) die "Unknown IN_TYPE $IN_TYPE"
243 file) echo "Output file: $PROBLEM.out"
244 [ $TASK_TYPE == interactive ] || BOX_EXTRAS="$BOX_EXTRAS -o/dev/null"
246 stdio) echo "Output file: <stdout>"
247 BOX_EXTRAS="$BOX_EXTRAS -o.stdout"
249 none) echo "Output file: <none>"
251 *) die "Unknown OUT_TYPE $OUT_TYPE"
254 echo "Timeout: $TIME_LIMIT s"
255 echo "Memory: $MEM_LIMIT KB"
257 echo "Sandbox contents before start:"
263 echo "Sandbox contents after exit:"
265 case ${OUT_TYPE:-$IO_TYPE} in
266 file) [ -f $BOXDIR/$PROBLEM.out ] || test-result 0 "No output file."
267 cp $BOXDIR/$PROBLEM.out $TDIR/$TEST.out
269 stdio) [ -f $BOXDIR/.stdout ] || test-result 0 "No output file."
270 cp $BOXDIR/.stdout $TDIR/$TEST.out
275 # Running of test program with file input/output
277 function test-run-file
281 BOXOPTS="`eval echo $TEST_SANDBOX_OPTS`$BOX_EXTRAS"
282 echo "Sandbox options: $BOXOPTS"
283 if ! $BOXCMD $BOXOPTS -- ./$PROBLEM 2>$TMPDIR/exec.out ; then
285 MSG=`tail -1 $TMPDIR/exec.out`
292 # Running of interactive test programs
294 function test-run-interactive
298 BOXOPTS="`eval echo $TEST_SANDBOX_OPTS`$BOX_EXTRAS"
299 echo "Sandbox options: $BOXOPTS"
300 ICCMD=`eval echo $IA_CHECK`
301 echo "Interactive checker: $ICCMD"
302 if ! $HDIR/bin/iwrapper $BOXCMD $BOXOPTS -- ./$PROBLEM @@ $ICCMD 2>$TMPDIR/exec.out ; then
304 MSG="`head -1 $TMPDIR/exec.out`"
313 function syntax-check
315 [ -n "$SYNTAX_CHECK" ] || return 0
317 SCHECK=`eval echo $SYNTAX_CHECK`
318 echo "Syntax check command: $SCHECK"
319 if ! eval $SCHECK 2>$TMPDIR/exec.out ; then
321 MSG=`tail -1 $TMPDIR/exec.out`
322 if [ -z "$MSG" ] ; then MSG="Wrong syntax." ; fi
330 function output-check
333 if [ -n "$OUTPUT_CHECK" -a "$OUT_TYPE" != none ] ; then
335 [ -f $PDIR/$TEST.out ] && ln $PDIR/$TEST.out $TDIR/$TEST.ok
336 OCHECK=`eval echo $OUTPUT_CHECK`
337 echo "Output check command: $OCHECK"
338 if ! eval $OCHECK 2>$TMPDIR/exec.out ; then
340 MSG=`tail -1 $TMPDIR/exec.out`
341 if [ -z "$MSG" ] ; then MSG="Wrong answer." ; fi
345 MSG=`tail -1 $TMPDIR/exec.out`
347 if [ -z "$MSG" ] ; then MSG="OK" ; fi
348 test-result $POINTS_PER_TEST "$MSG"
351 # Setup of public commands
353 function public-setup
356 PDIR=$MO_ROOT/problems/$PROBLEM
360 [ -d $PDIR ] || die "Unknown problem $PROBLEM"
362 pstart "Initializing... "
368 BOXCMD="$MO_ROOT/bin/box -c$BOXDIR"
370 pend "OK (see 'log' for details)"
373 # Locate output of open data problem, test case TEST
377 [ -f $PDIR/$TEST.in ] || die "Unknown test $TEST"
378 if [ -n "$1" ] ; then
381 SRCN=$SDIR/$PROBLEM$TEST.out
383 [ -f $SRCN ] || fatal "Output file $SRCN not found"