* same with xv6
[mascara-docs.git] / i386 / ucla / src / lab4 / grade-functions.sh
blob4c636033cf760fa178728b1da66d8da4468af8cc
1 verbose=false
3 if [ "x$1" = "x-v" ]
4 then
5 verbose=true
6 out=/dev/stdout
7 err=/dev/stderr
8 else
9 out=/dev/null
10 err=/dev/null
13 if gmake --version >/dev/null 2>&1; then make=gmake; else make=make; fi
16 # QEMU
19 timeout=30
20 preservefs=n
21 qemu=`$make -s --no-print-directory print-qemu`
22 gdbport=`$make -s --no-print-directory print-gdbport`
23 qemugdb=`$make -s --no-print-directory print-qemugdb`
24 cxxfilt=`$make -s --no-print-directory print-c++filt`
25 brkfn=readline
26 keystrokes=
28 echo_n () {
29 # suns can't echo -n, and Mac OS X can't echo "x\c"
30 # assume argument has no doublequotes
31 awk 'BEGIN { printf("'"$*"'"); }' </dev/null
34 psleep () {
35 # solaris "sleep" doesn't take fractions
36 perl -e "select(undef, undef, undef, $1);"
39 # Run QEMU with serial output redirected to jos.out. If $brkfn is
40 # non-empty, wait until $brkfn is reached or $timeout expires, then
41 # kill QEMU.
42 run () {
43 qemuextra=
44 if [ -n "$brkfn" -a -z "$keystrokes" ]; then
45 qemuextra="-monitor null -S $qemugdb"
46 else
47 qemuextra="-monitor telnet::$gdbport,server,nowait"
50 t0=`date +%s.%N 2>/dev/null`
51 rm -f jos.out
53 ulimit -t $timeout
54 exec $qemu -nographic $qemuopts -serial file:jos.out -no-reboot $qemuextra
55 ) >$out 2>$err &
56 PID=$!
58 # Wait for QEMU to start
59 sleep 1
61 if [ -n "$brkfn" -a -z "$keystrokes" ]; then
62 # Find the address of the kernel $brkfn function,
63 # which is typically what the kernel monitor uses to
64 # read commands interactively.
65 brkaddr=`grep " $brkfn\$" obj/kernel.sym | sed -e's/ .*$//g'`
66 if [ -z "$brkaddr" ]; then
67 # Perhaps the symbol was mangled.
68 brkaddr=`$cxxfilt < obj/kernel.sym | grep " $brkfn(" | sed -e's/ .*$//g'`
72 echo "target remote localhost:$gdbport"
73 echo "br *0x$brkaddr"
74 echo c
75 ) > jos.in
76 gdb -batch -nx -x jos.in > /dev/null 2>&1
77 else
78 # Wait until "Welcome to the JOS kernel monitor" is printed.
79 while ! grep -l -q "^Welcome to the JOS kernel monitor" jos.out >/dev/null 2>&1; do
80 psleep 0.1
81 done
84 while [ -n "$keystrokes" ]; do
85 firstchar=`echo "$keystrokes" | sed -e 's/^\(.\).*/\1/'`
86 keystrokes=`echo "$keystrokes" | sed -e 's/^.//'`
87 if [ "$firstchar" = ';' ]; then
88 echo "sendkey ret"
89 elif [ "$firstchar" = ' ' ]; then
90 echo "sendkey spc"
91 else
92 echo "sendkey $firstchar"
94 psleep 0.05
95 done
97 echo "quit"
98 psleep 1
99 ) | telnet localhost $gdbport >/dev/null 2>$err
102 # Make sure QEMU is dead. On OS X, exiting gdb
103 # doesn't always exit QEMU.
104 kill $PID > /dev/null 2>&1
108 # Scoring
111 pts=5
112 part=0
113 partpos=0
114 total=0
115 totalpos=0
117 showpart () {
118 echo "Part $1 score: $part/$partpos"
119 echo
120 total=`expr $total + $part`
121 totalpos=`expr $totalpos + $partpos`
122 part=0
123 partpos=0
126 showfinal () {
127 total=`expr $total + $part`
128 totalpos=`expr $totalpos + $partpos`
129 echo "Score: $total/$totalpos"
130 if [ $total -lt $totalpos ]; then
131 exit 1
135 passfailmsg () {
136 msg="$1"
137 shift
138 if [ $# -gt 0 ]; then
139 msg="$msg,"
142 t1=`date +%s.%N 2>/dev/null`
143 time=`echo "scale=1; ($t1-$t0)/1" | sed 's/.N/.0/g' | bc 2>/dev/null`
145 echo $msg "$@" "(${time}s)"
148 pass () {
149 passfailmsg OK "$@"
150 part=`expr $part + $pts`
151 partpos=`expr $partpos + $pts`
154 fail () {
155 passfailmsg WRONG "$@"
156 partpos=`expr $partpos + $pts`
161 # User tests
164 # Usage: runtest <tagname> <defs> <check fn> <check args...>
165 runtest () {
166 tag="$1"
167 perl -e "print '$tag: '"
168 rm -f obj/kern/init.o obj/kernel obj/kern/kernel obj/kernel.img
169 [ "$preservefs" = y ] || rm -f obj/fs.img
170 if $verbose
171 then
172 echo "$make $2... "
174 $make $2 >$out
175 if [ $? -ne 0 ]
176 then
177 rm -f obj/kern/init.o
178 echo $make $2 failed
179 exit 1
181 # We just built a weird init.o that runs a specific test. As
182 # a result, 'make qemu' will run the last graded test and
183 # 'make clean; make qemu' will run the user-specified
184 # environment. Remove our weird init.o to fix this.
185 rm -f obj/kern/init.o
188 # Give qemu some more time to run (for asynchronous mode).
189 # This way, we get the small 1 second wait for most tests
190 # and a longer wait (5 seconds) in case qemu needs that
191 # time to load.
192 if [ ! -s jos.out ]
193 then
194 sleep 4
197 if [ ! -s jos.out ]
198 then
199 fail > /dev/null # Still increment number of possible points
200 echo 'no jos.out'
201 else
202 shift
203 shift
204 check=$1
205 shift
206 $check "$tag" "$@"
210 quicktest () {
211 perl -e "print '$1: '"
212 shift
213 checkregexps "" "$@"
216 checkregexps () {
217 okay=yes
218 tag="$1"
219 shift
221 not=false
222 for i
224 if [ "x$i" = "x!" ]
225 then
226 not=true
227 elif $not
228 then
229 if egrep "^$i\$" jos.out >/dev/null
230 then
231 echo "got unexpected line '$i'"
232 if $verbose
233 then
234 exit 1
236 okay=no
238 not=false
239 else
240 egrep "^$i\$" jos.out >/dev/null
241 if [ $? -ne 0 ]
242 then
243 echo "missing '$i'"
244 if $verbose
245 then
246 exit 1
248 okay=no
250 not=false
252 done
253 if [ "$okay" = "yes" ]
254 then
255 pass
256 else
257 fail
258 if [ -n "$tag" ]; then
259 modtag=`echo "$tag" | tr -d '\012' | tr -cs A-Za-z0-9_.- _`
260 cp jos.out jos.out.$modtag
261 echo " => Saving QEMU output in jos.out.$modtag"
266 # Usage: runtest1 [-tag <tagname>] [-dir <dirname>] <progname> [-Ddef...] [-check checkfn] checkargs...
267 runtest1 () {
268 tag=
269 dir=user
270 check=checkregexps
271 while true; do
272 if [ $1 = -tag ]
273 then
274 tag=$2
275 elif [ $1 = -dir ]
276 then
277 dir=$2
278 else
279 break
281 shift
282 shift
283 done
284 prog=$1
285 shift
286 if [ "x$tag" = x ]
287 then
288 tag=$prog
290 runtest1_defs=
291 while expr "x$1" : 'x-D.*' >/dev/null; do
292 runtest1_defs="DEFS+='$1' $runtest1_defs"
293 shift
294 done
295 if [ "x$1" = "x-check" ]; then
296 check=$2
297 shift
298 shift
300 runtest "$tag" "DEFS='-DTEST=_binary_obj_${dir}_${prog}_start' DEFS+='-DTESTSIZE=_binary_obj_${dir}_${prog}_size' $runtest1_defs" "$check" "$@"