You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nudt-compiler-cpp/scripts/verify_asm_all_time.sh

161 lines
4.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 || $# -gt 2 ]]; then
echo "用法: $0 <test_dir> [output_dir]" >&2
exit 1
fi
test_dir=${1%/}
out_dir="test/test_result/function/asm_time"
shift
while [[ $# -gt 0 ]]; do
out_dir="$1"
shift
done
if [[ ! -d "$test_dir" ]]; then
echo "测试目录不存在: $test_dir" >&2
exit 1
fi
compiler="./build/bin/compiler"
if [[ ! -x "$compiler" ]]; then
echo "未找到编译器: $compiler ,请先构建。" >&2
exit 1
fi
if ! command -v aarch64-linux-gnu-gcc >/dev/null 2>&1; then
echo "未找到 aarch64-linux-gnu-gcc无法汇编/链接。" >&2
exit 1
fi
if ! command -v qemu-aarch64 >/dev/null 2>&1; then
echo "未找到 qemu-aarch64无法运行生成的可执行文件。" >&2
exit 1
fi
sylib_c="sylib/sylib.c"
if [[ ! -f "$sylib_c" ]]; then
echo "未找到 sylib: $sylib_c" >&2
exit 1
fi
mkdir -p "$out_dir"
sylib_obj="$out_dir/sylib.o"
aarch64-linux-gnu-gcc -c "$sylib_c" -I sylib -o "$sylib_obj"
mapfile -t inputs < <(find "$test_dir" -type f -name '*.sy' | sort)
if [[ ${#inputs[@]} -eq 0 ]]; then
echo "测试目录下未找到 .sy 文件: $test_dir" >&2
exit 1
fi
failures=0
normalize() {
tr -d '\r' < "$1" | sed -e '${ /^$/d; }' | perl -pe 'chomp if eof'
}
run_case() {
local input=$1
local input_dir base stem rel_path rel_dir case_out_dir asm_file exe
local stdin_file expected_file stdout_file actual_file time_file elapsed status
input_dir=$(dirname "$input")
base=$(basename "$input")
stem=${base%.sy}
rel_path=${input#"$test_dir"/}
rel_dir=$(dirname "$rel_path")
case_out_dir="$out_dir"
if [[ "$rel_dir" != "." ]]; then
case_out_dir="$out_dir/$rel_dir"
fi
mkdir -p "$case_out_dir"
asm_file="$case_out_dir/$stem.s"
exe="$case_out_dir/$stem"
stdin_file="$input_dir/$stem.in"
expected_file="$input_dir/$stem.out"
stdout_file="$case_out_dir/$stem.stdout"
actual_file="$case_out_dir/$stem.actual.out"
time_file="$case_out_dir/$stem.time"
if ! "$compiler" --emit-asm "$input" > "$asm_file" 2>"$case_out_dir/$stem.err"; then
echo "$stem: 编译失败"
cat "$case_out_dir/$stem.err" >&2
return 1
fi
if ! aarch64-linux-gnu-gcc "$asm_file" "$sylib_obj" -o "$exe" 2>"$case_out_dir/$stem.link.err"; then
echo "$stem: 链接失败"
cat "$case_out_dir/$stem.link.err" >&2
return 1
fi
set +e
if [[ -f "$stdin_file" ]]; then
/usr/bin/time -f "%e" -o "$time_file" \
qemu-aarch64 -L /usr/aarch64-linux-gnu "$exe" < "$stdin_file" > "$stdout_file"
else
/usr/bin/time -f "%e" -o "$time_file" \
qemu-aarch64 -L /usr/aarch64-linux-gnu "$exe" > "$stdout_file"
fi
status=$?
set -e
elapsed=$(tail -1 "$time_file")
{
cat "$stdout_file"
if [[ -s "$stdout_file" ]] && (( $(tail -c 1 "$stdout_file" | wc -l) == 0 )); then
printf '\n'
fi
printf '%s\n' "$status"
} > "$actual_file"
if [[ -f "$expected_file" ]]; then
if diff <(normalize "$expected_file") <(normalize "$actual_file") >/dev/null 2>&1; then
printf "%s: PASS (%.3fs)\n" "$stem" "$elapsed"
printf '%s\t%s\n' "$elapsed" "$stem" >> "$out_dir/elapsed.log"
return 0
else
printf "%s: FAIL (退出码: %d, 耗时: %.3fs)\n" "$stem" "$status" "$elapsed"
diff -u --strip-trailing-cr "$expected_file" "$actual_file" >&2 || true
return 1
fi
else
printf "%s: SKIP (无预期输出, %.3fs, 退出码: %d)\n" "$stem" "$elapsed" "$status"
printf '%s\t%s\n' "$elapsed" "$stem" >> "$out_dir/elapsed.log"
return 0
fi
}
rm -f "$out_dir/elapsed.log"
for input in "${inputs[@]}"; do
if ! run_case "$input"; then
((failures+=1))
fi
done
total=${#inputs[@]}
passed=$((total - failures))
if [[ -f "$out_dir/elapsed.log" && -s "$out_dir/elapsed.log" ]]; then
total_elapsed=$(awk '{s+=$1} END {printf "%.3f", s}' "$out_dir/elapsed.log")
else
total_elapsed="0.000"
fi
echo "总计: $total, 通过: $passed, 失败: $failures"
echo "通过用例总耗时: $total_elapsed s"
if (( failures > 0 )); then
exit 1
fi