-
Notifications
You must be signed in to change notification settings - Fork 100
/
Copy pathtest_compiler.sh
executable file
·158 lines (130 loc) · 4.03 KB
/
test_compiler.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/bash
padding_dots=$(printf '%0.1s' "."{1..60})
padlength=50
cmp=$1
success_total=0
failure_total=0
print_test_name () {
test_name=$1
printf '%s' "$test_name"
printf '%*.*s' 0 $((padlength - ${#test_name})) "$padding_dots"
}
test_success () {
echo "OK"
((success++))
}
test_failure () {
echo "FAIL"
((fail++))
}
test_not_implemented () {
echo "NOT IMPLEMENTED"
}
run_our_program () {
actual_out=`./$1 2>/dev/null`
actual_exit_code=$?
rm $1 2>/dev/null
}
run_correct_program () {
expected_out=`./a.out`
expected_exit_code=$?
rm a.out
}
compare_program_results () {
# make sure exit code is correct
if [ "$expected_exit_code" -ne "$actual_exit_code" ] || [ "$expected_out" != "$actual_out" ]
then
test_failure
else
test_success
fi
}
test_stage () {
success=0
fail=0
echo "===================================================="
echo "STAGE $1"
echo "===================Valid Programs==================="
for prog in `find . -type f -name "*.c" -path "./stage_$1/valid/*" -not -path "*/valid_multifile/*" 2>/dev/null`; do
gcc -w $prog
run_correct_program
base="${prog%.*}" #name of executable (filename w/out extension)
test_name="${base##*valid/}"
print_test_name $test_name
$cmp $prog 2>/dev/null
status=$?
if [[ $test_name == "skip_on_failure"* ]]; then
# this may depend on features we haven't implemented yet
# if compilation succeeds, make sure it gives the right result
# otherwise don't count it as success or failure
if [[ -f $base ]] && [[ $status -eq 0 ]]; then
# it succeeded, so run it and make sure it gives the right result
run_our_program $base
compare_program_results
else
test_not_implemented
fi
else
run_our_program $base
compare_program_results
fi
done
# programs with multiple source files
for dir in `ls -d stage_$1/valid_multifile/* 2>/dev/null` ; do
gcc -w $dir/*
run_correct_program
base="${dir%.*}" #name of executable (directory w/out extension)
test_name="${base##*valid_multifile/}"
# need to explicitly specify output name
$cmp -o "$test_name" $dir/* >/dev/null
print_test_name $test_name
# check output/exit codes
run_our_program $test_name
compare_program_results
done
echo "===================Invalid Programs================="
for prog in `ls stage_$1/invalid/{,**/}*.c 2>/dev/null`; do
base="${prog%.*}" #name of executable (filename w/out extension)
test_name="${base##*invalid/}"
$cmp $prog >/dev/null 2>&1
status=$? #failed, as we expect, if exit code != 0
print_test_name $test_name
# make sure neither executable nor assembly was produced
# and exit code is non-zero
if [[ -f $base || -f $base".s" ]]
then
test_failure
rm $base 2>/dev/null
rm $base".s" 2>/dev/null
else
test_success
fi
done
echo "===================Stage $1 Summary================="
printf "%d successes, %d failures\n" $success $fail
((success_total=success_total+success))
((failure_total=failure_total + fail))
}
total_summary () {
echo "===================TOTAL SUMMARY===================="
printf "%d successes, %d failures\n" $success_total $failure_total
}
if [ "$1" == "" ]; then
echo "USAGE: ./test_compiler.sh /path/to/compiler [stages(optional)]"
echo "EXAMPLE(test specific stages): ./test_compiler.sh ./mycompiler 1 2 4"
echo "EXAMPLE(test all): ./test_compiler.sh ./mycompiler"
exit 1
fi
if test 1 -lt $#; then
testcases=("$@") # [1..-1] is testcases
for i in `seq 2 $#`; do
test_stage ${testcases[$i-1]}
done
total_summary
exit 0
fi
num_stages=10
for i in `seq 1 $num_stages`; do
test_stage $i
done
total_summary