blob: 5ae9905e3a300c810e92d0a8fa6c5e79479f9330 [file] [log] [blame]
#!/bin/sh
type=float
abi=0
name=
srcdir="$(cd "${0%/*}" && pwd)/tests"
sim="$GCC_TEST_SIMULATOR"
# output_mode values:
# print only failures with minimal context
readonly really_quiet=0
# as above plus same-line output of last successful test
readonly same_line=1
# as above plus percentage
readonly percentage=2
# print one line per finished test with minimal context on failure
readonly verbose=3
# print one line per finished test with full output of the compiler and test
readonly really_verbose=4
output_mode=$really_quiet
[ -t 1 ] && output_mode=$same_line
timeout=180
run_expensive=false
if [ -n "$GCC_TEST_RUN_EXPENSIVE" ]; then
run_expensive=true
fi
keep_failed=false
only=
usage() {
cat <<EOF
Usage: $0 [Options] <g++ invocation>
Options:
-h, --help Print this message and exit.
-q, --quiet Disable same-line progress output (default if stdout is
not a tty).
-p, --percentage Add percentage to default same-line progress output.
-v, --verbose Print one line per test and minimal extra information on
failure.
-vv Print all compiler and test output.
-t <type>, --type <type>
The value_type to test (default: $type).
-a [0-9], --abi [0-9]
The ABI tag subset to test (default: $abi).
-n <name>, --name <name>
The name of the test (required).
-k, --keep-failed Keep executables of failed tests.
--srcdir <path> The source directory of the tests (default: $srcdir).
--sim <executable> Path to an executable that is prepended to the test
execution binary (default: the value of
GCC_TEST_SIMULATOR).
--timeout-factor <x>
Multiply the default timeout with x.
-x, --run-expensive Compile and run tests marked as expensive (default:
true if GCC_TEST_RUN_EXPENSIVE is set, false otherwise).
-o <pattern>, --only <pattern>
Compile and run only tests matching the given pattern.
EOF
}
while [ $# -gt 0 ]; do
case "$1" in
-h|--help)
usage
exit
;;
-q|--quiet)
output_mode=$really_quiet
;;
-p|--percentage)
output_mode=$percentage
;;
-v|--verbose)
if [ $output_mode -lt $verbose ]; then
output_mode=$verbose
else
output_mode=$really_verbose
fi
;;
-x|--run-expensive)
run_expensive=true
;;
-k|--keep-failed)
keep_failed=true
;;
-o|--only)
only="$2"
shift
;;
-t|--type)
type="$2"
shift
;;
-a|--abi)
abi="$2"
shift
;;
-n|--name)
name="$2"
shift
;;
--srcdir)
srcdir="$2"
shift
;;
--sim)
sim="$2"
shift
;;
--timeout-factor)
timeout=$(awk "BEGIN { print int($timeout * $2) }")
shift
;;
--)
shift
break
;;
--*=*)
opt="$1"
shift
value=${opt#*=}
set -- ${opt%=$value} "$value" ${1+"$@"}
continue
;;
-[ahknopqtvx][ahknopqtvx]*)
opt="$1"
shift
next=${opt#??}
set -- ${opt%$next} "-$next" ${1+"$@"}
continue
;;
-*)
echo "Error: Unrecognized option '$1'" >&2
exit 1
;;
*)
break
;;
esac
shift
done
if [ $output_mode = $percentage ]; then
inc_progress() {
{
flock -n 9
n=$(($(cat .progress) + 1))
echo $n >&9
echo $n
} 9<>.progress
}
fi
CXX="$1"
shift
CXXFLAGS="$@"
src="${srcdir}/${name}.cc"
shorttype=$(echo $type|sed -e 's/long /l/' -e 's/unsigned /u/' -e 's/signed /s/')
testname="${name}-${shorttype}-${abi}"
exe="${testname}.exe"
log="${testname}.log"
sum="${testname}.sum"
if [ -n "$only" ]; then
if echo "$testname"|awk "{ exit /$only/ }"; then
touch "$log" "$sum"
[ $output_mode = $percentage ] && inc_progress >/dev/null
exit 0
fi
fi
if [ $abi -eq 0 ]; then
abiflag=""
elif [ $abi -gt 0 -a $abi -lt 10 ]; then
abiflag="-DEXTENDEDTESTS=$((abi-1))"
else
echo "Error: The -a argument must be a value between 0 and 9 (inclusive)." >&2
exit 1
fi
if [ $output_mode = $percentage ]; then
show_progress() {
n=$(inc_progress)
read total < .progress_total
total=${total}0
printf "\e[1G\e[K[%3d %%] ${src##*/} $type $abiflag" \
$((n * 1005 / total))
}
trap 'show_progress' EXIT
prefix="\e[1G\e[K"
elif [ $output_mode = $same_line ]; then
show_progress() {
printf "\e[1G\e[K${src##*/} $type $abiflag"
}
trap 'show_progress' EXIT
prefix="\e[1G\e[K"
else
prefix=""
fi
fail() {
printf "$prefix"
echo "FAIL: $src $type $abiflag ($*)" | tee -a "$sum" "$log"
}
xpass() {
printf "$prefix"
echo "XPASS: $src $type $abiflag ($*)" | tee -a "$sum" "$log"
}
xfail() {
[ $output_mode -ge $verbose ] && echo "XFAIL: $src $type $abiflag ($*)"
echo "XFAIL: $src $type $abiflag ($*)" >> "$sum"
echo "XFAIL: $src $type $abiflag ($*)" >> "$log"
}
pass() {
[ $output_mode -ge $verbose ] && echo "PASS: $src $type $abiflag ($*)"
echo "PASS: $src $type $abiflag ($*)" >> "$sum"
echo "PASS: $src $type $abiflag ($*)" >> "$log"
}
unsupported() {
test
[ $output_mode -ge $verbose ] && echo "UNSUPPORTED: $src $type $abiflag ($*)"
echo "UNSUPPORTED: $src $type $abiflag ($*)" >> "$sum"
echo "UNSUPPORTED: $src $type $abiflag ($*)" >> "$log"
}
write_log_and_verbose() {
echo "$*" >> "$log"
if [ $output_mode = $really_verbose ]; then
if [ -z "$COLUMNS" ] || ! type fmt>/dev/null; then
echo "$*"
else
echo "$*" | fmt -w $COLUMNS -s - || cat
fi
fi
}
matches() {
eval "case '$1' in
$2) return 0;; esac"
return 1
}
test_selector() {
string="$1"
pat_type="${string%% *}"
if matches "$shorttype" "$pat_type"; then
string="${string#* }"
pat_abi="${string%% *}"
if matches "$abi" "$pat_abi"; then
string="${string#* }"
pat_triplet="${string%% *}"
[ -z "$target_triplet" ] && target_triplet=$($CXX -dumpmachine)
if matches "$target_triplet" "$pat_triplet"; then
pat_flags="${string#* }"
if matches "$CXXFLAGS" "*$pat_flags*"; then
return 0
fi
fi
fi
fi
return 1
}
trap "rm -f '$log' '$sum' $exe; exit" INT
rm -f "$log" "$sum"
touch "$log" "$sum"
read_src_option() {
local key tmp var
key="$1"
var="$2"
[ -z "$var" ] && var="$1"
local tmp="$(head -n25 "$src" | grep "^//\\s*${key}: ")"
if [ -n "$tmp" ]; then
tmp="$(echo "${tmp#//*${key}: }" | sed -e 's/ \+/ /g' -e 's/^ //' -e 's/$//')"
eval "$var=\"$tmp\""
else
return 1
fi
}
if read_src_option skip; then
if test_selector "$skip"; then
# silently skip this test
exit 0
fi
fi
if read_src_option only; then
if ! test_selector "$only"; then
# silently skip this test
exit 0
fi
fi
if ! $run_expensive; then
if read_src_option expensive; then
if test_selector "$expensive"; then
unsupported "skip expensive tests"
exit 0
fi
fi
fi
if read_src_option xfail; then
if test_selector "${xfail#* }"; then
xfail="${xfail%% *}"
else
unset xfail
fi
fi
read_src_option timeout
if read_src_option timeout-factor factor; then
timeout=$(awk "BEGIN { print int($timeout * $factor) }")
fi
log_output() {
if [ $output_mode = $really_verbose ]; then
maxcol=${1:-1024}
awk "
BEGIN { count = 0 }
/^###exitstatus### [0-9]+$/ { exit \$2 }
{
print >> \"$log\"
if (count >= 1000) {
print \"Aborting: too much output\" >> \"$log\"
print \"Aborting: too much output\"
exit 125
}
++count
if (length(\$0) > $maxcol) {
i = 1
while (i + $maxcol <= length(\$0)) {
len = $maxcol
line = substr(\$0, i, len)
len = match(line, / [^ ]*$/)
if (len <= 0) {
len = match(substr(\$0, i), / [^ ]/)
if (len <= 0) len = $maxcol
}
print substr(\$0, i, len)
i += len
}
print substr(\$0, i)
} else {
print
}
}
END { close(\"$log\") }
"
else
awk "
BEGIN { count = 0 }
/^###exitstatus### [0-9]+$/ { exit \$2 }
{
print >> \"$log\"
if (count >= 1000) {
print \"Aborting: too much output\" >> \"$log\"
print \"Aborting: too much output\"
exit 125
}
++count
}
END { close(\"$log\") }
"
fi
}
verify_compilation() {
log_output $COLUMNS
exitstatus=$?
if [ $exitstatus -eq 0 ]; then
warnings=$(grep -ic 'warning:' "$log")
if [ $warnings -gt 0 ]; then
fail "excess warnings:" $warnings
if [ $output_mode = $verbose ]; then
grep -i 'warning:' "$log" | head -n5
fi
elif [ "$xfail" = "compile" ]; then
xpass "test for excess errors"
else
pass "test for excess errors"
fi
return 0
else
if [ $exitstatus -eq 124 ]; then
fail "timeout: test for excess errors"
else
errors=$(grep -ic 'error:' "$log")
if [ "$xfail" = "compile" ]; then
xfail "excess errors:" $errors
exit 0
else
fail "excess errors:" $errors
fi
fi
if [ $output_mode = $verbose ]; then
grep -i 'error:' "$log" | head -n5
fi
return 1
fi
}
verify_test() {
log_output $COLUMNS
exitstatus=$?
if [ $exitstatus -eq 0 ]; then
if [ "$xfail" = "run" ]; then
$keep_failed || rm "$exe"
xpass "execution test"
else
rm "$exe"
pass "execution test"
fi
return 0
else
$keep_failed || rm "$exe"
if [ $output_mode = $verbose ]; then
grep -i fail "$log" | head -n5
fi
if [ $exitstatus -eq 124 ]; then
fail "timeout: execution test"
elif [ "$xfail" = "run" ]; then
xfail "execution test"
else
fail "execution test"
fi
return 1
fi
}
write_log_and_verbose "$CXX $src $@ -D_GLIBCXX_SIMD_TESTTYPE=$type $abiflag -o $exe"
{
timeout --foreground $timeout "$CXX" "$src" "$@" "-D_GLIBCXX_SIMD_TESTTYPE=$type" $abiflag -o "$exe" 2>&1 <&-
printf "###exitstatus### %d\n" $?
} | verify_compilation || exit 0
if [ -n "$sim" ]; then
write_log_and_verbose "$sim ./$exe"
else
write_log_and_verbose "./$exe"
timeout=$(awk "BEGIN { print int($timeout / 2) }")
fi
{
timeout --foreground $timeout $sim "./$exe" 2>&1 <&-
printf "###exitstatus### %d\n" $?
} | verify_test || exit 0
# vim: sw=2 et cc=81 si