#!/usr/bin/env bash set -e function usage { cat <<-EOF USAGE $0 [-dgGhv] [-f focus-string] [-s seed] OPTIONS -h print this message -b run make under scan-build static analyzer -d run tests in a debugger (either lldb or gdb) -g run tests with valgrind's memcheck tool -G run tests with valgrind's memcheck tool, including a full leak check -v run tests with verbose output -f run only tests whose description contain the given string -s set the seed used to control random behavior -D pipe tests' stderr to \`dot(1)\` to render an SVG log EOF } profile= leak_check=no mode=normal verbose= args=() target=tests export BUILDTYPE=Test cmd="out/${BUILDTYPE}/${target}" run_scan_build= if [ "$(uname -s)" == "Darwin" ]; then export LINK="clang++ -fsanitize=address" fi while getopts "bdf:s:gGhpvD" option; do case ${option} in h) usage exit ;; d) mode=debug ;; g) mode=valgrind ;; G) mode=valgrind leak_check=full ;; p) profile=true ;; f) args+=("--only=${OPTARG}") ;; v) verbose=true ;; s) export TREE_SITTER_SEED=${OPTARG} ;; D) export TREE_SITTER_ENABLE_DEBUG_GRAPHS=1 mode=SVG ;; b) run_scan_build=true ;; esac done if [[ -n $verbose ]]; then args+=("--reporter=spec") else args+=("--reporter=singleline") fi if [[ -n "$run_scan_build" ]]; then . script/util/scan-build.sh scan_build make -j2 $target else make -j2 $target fi args=${args:-""} if [[ -n $profile ]]; then export CPUPROFILE=/tmp/${target}-$(date '+%s').prof fi case ${mode} in valgrind) valgrind \ --suppressions=./script/util/valgrind.supp \ --dsymutil=yes \ --leak-check=${leak_check} \ $cmd "${args[@]}" 2>&1 | \ grep --color -E '\w+_tests?.cc:\d+|$' ;; debug) if which -s lldb; then lldb $cmd -- "${args[@]}" elif which -s gdb; then gdb $cmd -- "${args[@]}" else echo "No debugger found" exit 1 fi ;; SVG) html_file=log.html dot_file=$html_file.dot function write_log_file { echo "" > $html_file line_count=$(grep -n '^$' $dot_file | tail -1 | cut -f1 -d:) if [[ -n $line_count ]]; then head -n $line_count $dot_file | dot -Tsvg >> $html_file else cat $dot_file | grep -v 'Assertion' | dot -Tsvg >> $html_file fi rm $dot_file echo "Wrote $html_file - $line_count" } function handle_sigint { trap '' SIGINT echo write_log_file exit 0 } trap handle_sigint SIGINT $cmd "${args[@]}" 2> $dot_file || export status=$? write_log_file exit $status ;; normal) time $cmd "${args[@]}" ;; esac if [[ -n $profile ]]; then pprof $cmd $CPUPROFILE fi