blob: 19624991f19ae69c08fbd3711ab588b2579288e2 (
plain)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
#!/bin/sh -eu
#
# Script to run tests. Currently there's only a bootstrap compiler, so that's
# all that this script supports.
#
# Copyright © 2026 Samuel Lidén Borell <samuel@kodafritt.se>
#
# SPDX-License-Identifier: EUPL-1.2+ OR LGPL-2.1-or-later
#
srcdir='.'
modules='somelib otherlib app'
cc="${CC:-cc}"
cflags="${CFLAGS:--g} -std=c89 -Wall -Wextra -pedantic -Walloca -Wbad-function-cast -Wcast-align -Wconversion -Wdate-time -Wmissing-declarations -Wmissing-prototypes -Wmissing-noreturn -Wnested-externs -Wnull-dereference -Wold-style-definition -Wshadow -Wshift-negative-value -Wshift-overflow -Wstrict-aliasing -Wstrict-overflow=5 -Wstrict-prototypes -Wswitch-enum -Wundef -Wunused -Wvla -Wwrite-strings -fsanitize=undefined"
quiet=0
parse_args=1
enable_bootstrap_tests=0
enable_all_tests=1
enabled_any_test=0
enable_clean=0
while [ $# != 0 ]; do
if [ $parse_args = 1 ]; then
case "$1" in
--)
parse_args=0
;;
-h|--help|-help)
cat <<EOF
usage: $0 [-q|--quiet] [variable=value]... [compiler-stage]...
Runs the test suite. Without arguments, it runs the tests on all compiler
stages.
The compiler-stage parameter is used to specify what to test or do.
By default all tests (currently only "bootstrap") is run.
bootstrap - Test the C bootstrap compiler.
clean - Remove generated files (always runs first).
You can override certain variables with key=value arguments
Note: These are NOT environment variables, although they are used for defaults.
Note: Use quotes if the values contain spaces or other shell characters.
srcdir=path Sets the source directory, can be either of the runtests.sh
script or the root source directory. Default: "."
CC=command Sets the C compiler to use.
Default: CC environment variable, or "cc" if not set.
CFLAGS=flags Sets the flags for the C compiler.
Default: Various warnings for GCC/clang and -g. If the
CFLAGS environment variable is set, it is prepended.
Specifiy the "-q" option to suppress progress output.
Exit status:
0 - if all tests are successful.
1 - if any tests fails (or on environment errors)
2 - if arguments are wrong
3 - if prerequisite files are not founds (i.e. the compiler to test)
EOF
exit
;;
-q|--quiet)
quiet=1
;;
-*)
printf >&2 '%s: invalid option: %s\n' "$0" "$1"
exit 2
;;
bootstrap)
enable_bootstrap_tests=1
enable_all_tests=0
enabled_any_test=1
;;
clean)
enable_clean=1
enable_all_tests=0
;;
CC=*)
cc=${1#CC=}
;;
CFLAGS=*)
cflags=${1#CFLAGS=}
;;
srcdir=*)
srcdir=${1#srcdir=}
;;
*=*)
printf >&2 '%s: unknown flag: %s\n' "$0" "${1#=*}"
exit 2
;;
*)
printf >&2 '%s: unknown compiler stage: %s\n' "$0" "$1"
exit 2
;;
esac
fi
shift
done
if [ $enable_all_tests = 1 ]; then
enable_bootstrap_tests=1
enabled_any_test=1
fi
# Locate directories
if [ -f "$srcdir"/tests/runtests.sh ]; then
true
elif [ -f "$srcdir"/runtests.sh ]; then
srcdir="$srcdir"/..
else
printf >&2 'Cannot locate source tree in "%s".\n' "$srcdir"
exit 1
fi
# =======================================================================
# ||||||||||||||||||||||||| Test preparations |||||||||||||||||||||||||
# =======================================================================
error=0
if [ $enable_bootstrap_tests = 1 ]; then
# Ensure that the bootstrap compiler has been built
if [ -f bootstrap/stage1 ]; then
bsdir=bootstrap
elif [ -f stage1 ]; then
bsdir=.
elif [ -f ../bootstrap/stage1 ]; then
bsdir=../bootstrap
else
echo >&2 'Could not locate the bootstrap compiler (stage1)'
echo >&2 'You need to build it before you can run the tests.'
error=1
fi
if [ -n "${bsdir:-}" ]; then
bscomp="$bsdir"/stage1
fi
fi
if [ -d tests ]; then
outdir='tests/out'
else
outdir=out
fi
if [ $enable_clean = 1 ]; then
for module in $modules; do
rm -f "$outdir/$module.o" \
"$outdir/$module.c" \
"$outdir/$module" \
"$outdir/interfaces/$module.slul"
done
rm -f "$outdir/interfaces/core_wip.slul"
if [ $enabled_any_test = 0 ]; then
exit
fi
fi
if ! mkdir -p "$outdir"; then
printf >&2 'Cannot create output directory "%s".\n' "$outdir"
error=1
fi
interfacedir="$srcdir/stdlib/interfaces"
if [ ! -d "$interfacedir" ]; then
printf >&2 'Interfaces directory %s not found.\n' "$interfacedir"
error=1
fi
if [ $error = 1 ]; then
exit 3
fi
# =======================================================================
# ||||||||||||||||||||||||||||| Run tests |||||||||||||||||||||||||||||
# =======================================================================
if [ $enable_bootstrap_tests = 1 ]; then
mkdir -p "$outdir"/interfaces
cp "$srcdir"/stdlib/interfaces/core_wip.slul "$outdir"/interfaces/
for module in $modules; do
if [ $quiet = 0 ]; then
printf "=== bootstrap: %s ===\n" "$module"
fi
modpath="$srcdir/tests/$module"
genfile="$outdir/$module.c"
if [ -e "$modpath/interface.slul" ]; then
# It's a library. Always copy it, to allow for testing of
# error handling in imported interface files
cp "$modpath/interface.slul" "$outdir/interfaces/$module.slul"
fi
if ! "$bscomp" "$outdir"/interfaces "$modpath" "$genfile"; then
printf >&2 'Failed to compile "%s" with bootstrap compiler!\n' \
"$module"
error=1
continue
fi
if ! "$cc" $cflags -I"$srcdir"/bootstrap/rtlincl \
-c "$genfile" -o "$outdir/$module.o"; then
printf >&2 'Failed to compile "%s" with C compiler\n' \
"$genfile"
error=1
continue
fi
if [ ! -e "$modpath/interface.slul" ]; then
# It's an executable application
"$cc" $cflags \
"$bsdir/rtl/cli.o" \
"$bsdir/rtl/fail.o" \
"$bsdir/rtl/message.o" \
"$bsdir/rtl/string.o" \
"$bsdir/rtl/writer.o" \
"$outdir/somelib.o" \
"$outdir/otherlib.o" \
"$outdir/$module.o" \
-o "$outdir/$module"
if ! "$outdir/$module"; then
printf >&2 'Test module "%s" returned error code %d.\n' \
"$outdir/$module" $?
error=1
fi
fi
done
fi
if [ $error = 1 ]; then
exit 1
fi
|