#!/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 # # 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 <&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