diff --git a/test_script/clean.sh b/test_script/clean.sh deleted file mode 100644 index d203552..0000000 --- a/test_script/clean.sh +++ /dev/null @@ -1,3 +0,0 @@ -rm -rf tmp/* -rm -rf *.s *.ll *clang *sysyc -rm -rf *_riscv32 \ No newline at end of file diff --git a/test_script/exe-riscv32.sh b/test_script/exe-riscv32.sh deleted file mode 100644 index 3f4ce73..0000000 --- a/test_script/exe-riscv32.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# 定义输入目录 -input_dir="./tmp" - -# 获取tmp目录下的所有符合条件的可执行文件,并按前缀数字升序排序 -executable_files=$(ls "$input_dir" | grep -E '^[0-9]+_.*' | grep -E '_gcc_riscv32$|_sysyc_riscv32$' | sort -t '_' -k1,1n) - -# 用于存储前缀数字和返回值 -declare -A gcc_results -declare -A sysyc_results - -# 遍历所有符合条件的可执行文件 -for file in $executable_files; do - # 提取文件名前缀和后缀 - prefix=$(echo "$file" | cut -d '_' -f 1) - suffix=$(echo "$file" | cut -d '_' -f 2) - - # 检查是否已经处理过该前缀的两个文件 - if [[ ${gcc_results["$prefix"]} && ${sysyc_results["$prefix"]} ]]; then - continue - fi - - # 执行可执行文件并捕获返回值 - echo "Executing: $file" - qemu-riscv32 "$input_dir/$file" - ret_code=$? - - # 明确记录返回值 - echo "Return code for $file: $ret_code" - - # 根据后缀存储返回值 - if [[ "$suffix" == "gcc" ]]; then - gcc_results["$prefix"]=$ret_code - elif [[ "$suffix" == "sysyc" ]]; then - sysyc_results["$prefix"]=$ret_code - fi - - # 如果同一个前缀的两个文件都已执行,比较它们的返回值 - if [[ ${gcc_results["$prefix"]} && ${sysyc_results["$prefix"]} ]]; then - gcc_ret=${gcc_results["$prefix"]} - sysyc_ret=${sysyc_results["$prefix"]} - if [[ "$gcc_ret" -ne "$sysyc_ret" ]]; then - echo -e "\e[31mWARNING: Return codes differ for prefix $prefix: _gcc=$gcc_ret, _sysyc=$sysyc_ret\e[0m" - else - echo "Return codes match for prefix $prefix: $gcc_ret" - fi - fi -done diff --git a/test_script/exe.sh b/test_script/exe.sh deleted file mode 100644 index 0a03309..0000000 --- a/test_script/exe.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# 定义输入目录 -input_dir="." - -# 获取当前目录下的所有符合条件的可执行文件,并按前缀数字升序排序 -executable_files=$(ls "$input_dir" | grep -E '^[0-9]+_.*' | grep -E '_clang$|_sysyc$' | sort -t '_' -k1,1n) - -# 用于存储前缀数字和返回值 -declare -A clang_results -declare -A sysyc_results - -# 遍历所有符合条件的可执行文件 -for file in $executable_files; do - # 提取文件名前缀和后缀 - prefix=$(echo "$file" | cut -d '_' -f 1) - suffix=$(echo "$file" | cut -d '_' -f 2) - - # 检查是否已经处理过该前缀的两个文件 - if [[ ${clang_results["$prefix"]} && ${sysyc_results["$prefix"]} ]]; then - continue - fi - - # 执行可执行文件并捕获返回值 - echo "Executing: $file" - "./$file" - ret_code=$? - - # 明确记录返回值 - echo "Return code for $file: $ret_code" - - # 根据后缀存储返回值 - if [[ "$suffix" == "clang" ]]; then - clang_results["$prefix"]=$ret_code - elif [[ "$suffix" == "sysyc" ]]; then - sysyc_results["$prefix"]=$ret_code - fi - - # 如果同一个前缀的两个文件都已执行,比较它们的返回值 - if [[ ${clang_results["$prefix"]} && ${sysyc_results["$prefix"]} ]]; then - clang_ret=${clang_results["$prefix"]} - sysyc_ret=${sysyc_results["$prefix"]} - if [[ "$clang_ret" -ne "$sysyc_ret" ]]; then - echo -e "\e[31mWARNING: Return codes differ for prefix $prefix: _clang=$clang_ret, _sysyc=$sysyc_ret\e[0m" - else - echo "Return codes match for prefix $prefix: $clang_ret" - fi - fi -done \ No newline at end of file diff --git a/test_script/gcc-riscv32.sh b/test_script/gcc-riscv32.sh deleted file mode 100644 index 2598498..0000000 --- a/test_script/gcc-riscv32.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# 定义输入和输出路径 -input_dir="../test/" -output_dir="./tmp" - -# 默认不生成可执行文件 -generate_executable=false - -# 解析命令行参数 -while [[ "$#" -gt 0 ]]; do - case $1 in - --executable|-e) - generate_executable=true - shift - ;; - *) - echo "Unknown parameter: $1" - exit 1 - ;; - esac -done - -# 确保输出目录存在 -mkdir -p "$output_dir" - -# 遍历输入路径中的所有 .sy 文件 -for sy_file in "$input_dir"*.sy; do - # 获取文件名(不带路径和扩展名) - base_name=$(basename "$sy_file" .sy) - - # 定义输出文件路径 - output_file="${output_dir}/${base_name}_gcc_riscv32.s" - - # 使用 gcc 编译 .sy 文件为 .ll 文件 - riscv32-unknown-elf-gcc -x c -S "$sy_file" -o "$output_file" - - # 检查是否成功 - if [ $? -eq 0 ]; then - echo "Compiled $sy_file -> $output_file" - else - echo "Failed to compile $sy_file" - continue - fi - - # 如果指定了 --executable 或 -e 参数,则进一步编译为可执行文件 - if $generate_executable; then - executable_file="${output_dir}/${base_name}_gcc_riscv32" - riscv32-unknown-elf-gcc "$output_file" -o "$executable_file" - - if [ $? -eq 0 ]; then - echo "Generated executable: $executable_file" - else - echo "Failed to generate executable from $output_file" - fi - fi -done diff --git a/test_script/ll.sh b/test_script/ll.sh deleted file mode 100644 index a64b92d..0000000 --- a/test_script/ll.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# 定义输入和输出路径 -input_dir="../test/" -output_dir="./" - -# 默认不生成可执行文件 -generate_executable=false - -# 解析命令行参数 -while [[ "$#" -gt 0 ]]; do - case $1 in - --executable|-e) - generate_executable=true - shift - ;; - *) - echo "Unknown parameter: $1" - exit 1 - ;; - esac -done - -# 确保输出目录存在 -mkdir -p "$output_dir" - -# 遍历输入路径中的所有 .sy 文件 -for sy_file in "$input_dir"*.sy; do - # 获取文件名(不带路径和扩展名) - base_name=$(basename "$sy_file" .sy) - - # 定义输出文件路径 - output_file="${base_name}_clang.ll" - - # 使用 clang 编译 .sy 文件为 .ll 文件 - clang -x c -S -emit-llvm "$sy_file" -o "$output_file" - - # 检查是否成功 - if [ $? -eq 0 ]; then - echo "Compiled $sy_file -> $output_file" - else - echo "Failed to compile $sy_file" - continue - fi - - # 如果指定了 --executable 或 -e 参数,则进一步编译为可执行文件 - if $generate_executable; then - executable_file="${base_name}_clang" - clang "$output_file" -o "$executable_file" - - if [ $? -eq 0 ]; then - echo "Generated executable: $executable_file" - else - echo "Failed to generate executable from $output_file" - fi - fi -done \ No newline at end of file diff --git a/test_script/runit-riscv64-single.sh b/test_script/runit-riscv64-single.sh index 3e2c5c7..ad093d0 100644 --- a/test_script/runit-riscv64-single.sh +++ b/test_script/runit-riscv64-single.sh @@ -14,6 +14,7 @@ TESTDATA_DIR="${SCRIPT_DIR}/testdata" # 用于查找 .in/.out 文件 GCC_NATIVE="gcc" # VM 内部的原生 gcc # --- 初始化变量 --- +CLEAN_MODE=false GCC_TIMEOUT=10 # gcc 编译超时 (秒) EXEC_TIMEOUT=5 # 程序自动化执行超时 (秒) MAX_OUTPUT_LINES=50 # 对比失败时显示的最大行数 @@ -29,6 +30,7 @@ show_help() { echo "如果找到对应的 .in/.out 文件,则进行自动化测试。否则,进入交互模式。" echo "" echo "选项:" + echo " -c, --clean 清理 tmp 临时目录下的所有文件。" echo " -ct N 设置 gcc 编译超时为 N 秒 (默认: 10)。" echo " -t N 设置程序自动化执行超时为 N 秒 (默认: 5)。" echo " -ml N, --max-lines N 当输出对比失败时,最多显示 N 行内容 (默认: 50)。" @@ -57,10 +59,24 @@ display_file_content() { fi } +# --- 新增功能: 清理临时文件的函数 --- +clean_tmp() { + echo "正在清理临时目录: ${TMP_DIR}" + if [ -d "${TMP_DIR}" ]; then + rm -rf "${TMP_DIR}"/* 2>/dev/null + echo "清理完成。" + else + echo "临时目录 ${TMP_DIR} 不存在,无需清理。" + fi +} + # --- 参数解析 --- # 从参数中分离出 .s 文件和选项 for arg in "$@"; do case "$arg" in + -c|--clean) + CLEAN_MODE=true + ;; -ct|-t|-ml|--max-lines) # 选项和其值将在下一个循环中处理 ;; @@ -74,6 +90,7 @@ for arg in "$@"; do args_processed=true # 标记已处理过参数 while [[ "$#" -gt 0 ]]; do case "$1" in + -c|--clean) ;; # 已在外部处理 -ct) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then GCC_TIMEOUT="$2"; shift; else echo "错误: -ct 需要一个正整数参数。" >&2; exit 1; fi ;; -t) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then EXEC_TIMEOUT="$2"; shift; else echo "错误: -t 需要一个正整数参数。" >&2; exit 1; fi ;; -ml|--max-lines) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then MAX_OUTPUT_LINES="$2"; shift; else echo "错误: --max-lines 需要一个正整数参数。" >&2; exit 1; fi ;; @@ -95,6 +112,14 @@ for arg in "$@"; do done # --- 主逻辑开始 --- +if ${CLEAN_MODE}; then + clean_tmp + # 如果只提供了 -c 选项,则退出 + if [ ${#S_FILES[@]} -eq 0 ]; then + exit 0 + fi +fi + if [ ${#S_FILES[@]} -eq 0 ]; then echo "错误: 未提供任何 .s 文件作为输入。" show_help @@ -162,14 +187,17 @@ for s_file in "${S_FILES[@]}"; do EXPECTED_STDOUT_FILE="${TMP_DIR}/${base_name_from_s_file}.expected_stdout" head -n -1 "${output_reference_file}" > "${EXPECTED_STDOUT_FILE}" if [ "$ACTUAL_RETURN_CODE" -ne "$EXPECTED_RETURN_CODE" ]; then echo -e "\e[31m 返回码测试失败: 期望 ${EXPECTED_RETURN_CODE}, 实际 ${ACTUAL_RETURN_CODE}\e[0m"; is_passed=0; fi - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then + + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if ! diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then echo -e "\e[31m 标准输出测试失败。\e[0m"; is_passed=0 display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file}" " \e[36m--- 实际输出 ---\e[0m" "${MAX_OUTPUT_LINES}" echo -e " \e[36m----------------\e[0m" fi else - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${output_reference_file}") >/dev/null 2>&1; then echo -e "\e[32m 标准输出测试成功。\e[0m" else echo -e "\e[31m 标准输出测试失败。\e[0m"; is_passed=0 diff --git a/test_script/runit-riscv64.sh b/test_script/runit-riscv64.sh index c125bfb..3a0026f 100644 --- a/test_script/runit-riscv64.sh +++ b/test_script/runit-riscv64.sh @@ -175,7 +175,8 @@ while IFS= read -r s_file; do is_passed=0 fi - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if ! diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then echo -e "\e[31m 标准输出测试失败\e[0m" is_passed=0 display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" @@ -186,7 +187,9 @@ while IFS= read -r s_file; do if [ $ACTUAL_RETURN_CODE -ne 0 ]; then echo -e "\e[33m警告: 程序以非零状态 ${ACTUAL_RETURN_CODE} 退出 (纯输出比较模式)。\e[0m" fi - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then + + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${output_reference_file}") >/dev/null 2>&1; then echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m" else echo -e "\e[31m 失败: 输出不匹配\e[0m" diff --git a/test_script/runit-single.sh b/test_script/runit-single.sh index 27d91a7..106873b 100644 --- a/test_script/runit-single.sh +++ b/test_script/runit-single.sh @@ -225,21 +225,22 @@ for sy_file in "${SY_FILES[@]}"; do EXPECTED_STDOUT_FILE="${TMP_DIR}/${base_name}.expected_stdout" head -n -1 "${output_reference_file}" > "${EXPECTED_STDOUT_FILE}" if [ "$ACTUAL_RETURN_CODE" -ne "$EXPECTED_RETURN_CODE" ]; then echo -e "\e[31m 返回码测试失败: 期望 ${EXPECTED_RETURN_CODE}, 实际 ${ACTUAL_RETURN_CODE}\e[0m"; is_passed=0; fi - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then + + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if ! diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then echo -e "\e[31m 标准输出测试失败。\e[0m" is_passed=0 - # --- 本次修改点: 使用新函数显示输出 --- display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file}" " \e[36m--- 实际输出 ---\e[0m" "${MAX_OUTPUT_LINES}" echo -e " \e[36m----------------\e[0m" fi else - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${output_reference_file}") >/dev/null 2>&1; then echo -e "\e[32m 标准输出测试成功。\e[0m" else echo -e "\e[31m 标准输出测试失败。\e[0m" is_passed=0 - # --- 本次修改点: 使用新函数显示输出 --- display_file_content "${output_reference_file}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file}" " \e[36m--- 实际输出 ---\e[0m" "${MAX_OUTPUT_LINES}" echo -e " \e[36m----------------\e[0m" @@ -261,7 +262,6 @@ for sy_file in "${SY_FILES[@]}"; do "${QEMU_RISCV64}" "${executable_file}" INTERACTIVE_RET_CODE=$? echo -e "\e[33m\n 交互模式执行完毕,程序返回码: ${INTERACTIVE_RET_CODE}\e[0m" - # 交互模式无法自动判断对错,默认算通过,但会提示 echo " 注意: 交互模式的结果未经验证。" fi fi diff --git a/test_script/runit.sh b/test_script/runit.sh index f17e7b2..c8fa87f 100644 --- a/test_script/runit.sh +++ b/test_script/runit.sh @@ -203,7 +203,9 @@ while IFS= read -r sy_file; do echo -e "\e[31m 返回码测试失败: 期望: ${EXPECTED_RETURN_CODE}, 实际: ${ACTUAL_RETURN_CODE}\e[0m" is_passed=0 fi - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then + + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if ! diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then echo -e "\e[31m 标准输出测试失败\e[0m" is_passed=0 display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" @@ -214,7 +216,9 @@ while IFS= read -r sy_file; do if [ $ACTUAL_RETURN_CODE -ne 0 ]; then echo -e "\e[33m警告: 程序以非零状态 ${ACTUAL_RETURN_CODE} 退出 (纯输出比较模式)。\e[0m" fi - if ! diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then + + # --- 本次修改点: 使用 tr 删除所有空白字符后再比较 --- + if diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${output_reference_file}") >/dev/null 2>&1; then echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m" else echo -e "\e[31m 失败: 输出不匹配\e[0m" diff --git a/test_script/sysy-riscv32.sh b/test_script/sysy-riscv32.sh deleted file mode 100644 index e2f236e..0000000 --- a/test_script/sysy-riscv32.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# 定义输入和输出路径 -input_dir="../test/" -output_dir="./tmp" - -# 默认不生成可执行文件 -generate_executable=false - -# 解析命令行参数 -while [[ "$#" -gt 0 ]]; do - case $1 in - --executable|-e) - generate_executable=true - shift - ;; - *) - echo "Unknown parameter: $1" - exit 1 - ;; - esac -done - -# 确保输出目录存在 -mkdir -p "$output_dir" - -# 遍历输入路径中的所有 .sy 文件 -for sy_file in "$input_dir"*.sy; do - # 获取文件名(不带路径和扩展名) - base_name=$(basename "$sy_file" .sy) - - # 定义输出文件路径 - output_file="${output_dir}/${base_name}_sysyc_riscv32.s" - - # 使用 sysyc 编译 .sy 文件为 .s 文件 - ../build/bin/sysyc -s asm "$sy_file" > "$output_file" - - # 检查是否成功 - if [ $? -eq 0 ]; then - echo "Compiled $sy_file -> $output_file" - else - echo "Failed to compile $sy_file" - continue - fi - - # 如果指定了 --executable 或 -e 参数,则进一步编译为可执行文件 - if $generate_executable; then - executable_file="${output_dir}/${base_name}_sysyc_riscv32" - riscv32-unknown-elf-gcc "$output_file" -o "$executable_file" - - if [ $? -eq 0 ]; then - echo "Generated executable: $executable_file" - else - echo "Failed to generate executable from $output_file" - fi - fi -done diff --git a/test_script/sysyll.sh b/test_script/sysyll.sh deleted file mode 100644 index f3b6334..0000000 --- a/test_script/sysyll.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# 定义输入和输出路径 -input_dir="../test/" -output_dir="./" - -# 默认不生成可执行文件 -generate_executable=false - -# 解析命令行参数 -while [[ "$#" -gt 0 ]]; do - case $1 in - --executable|-e) - generate_executable=true - shift - ;; - *) - echo "Unknown parameter: $1" - exit 1 - ;; - esac -done - -# 确保输出目录存在 -mkdir -p "$output_dir" - -# 遍历输入路径中的所有 .sy 文件 -for sy_file in "$input_dir"*.sy; do - # 获取文件名(不带路径和扩展名) - base_name=$(basename "$sy_file" .sy) - - # 定义输出文件路径 - output_file="${base_name}_sysyc.ll" - - # 使用 sysyc 编译 .sy 文件为 .ll 文件 - ../build/bin/sysyc -s ir "$sy_file" > "$output_file" - - # 检查是否成功 - if [ $? -eq 0 ]; then - echo "Compiled $sy_file -> $output_file" - else - echo "Failed to compile $sy_file" - continue - fi - - # 如果指定了 --executable 或 -e 参数,则进一步编译为可执行文件 - if $generate_executable; then - executable_file="${base_name}_sysyc" - clang "$output_file" -o "$executable_file" - - if [ $? -eq 0 ]; then - echo "Generated executable: $executable_file" - else - echo "Failed to generate executable from $output_file" - fi - fi -done \ No newline at end of file diff --git a/test_script/wrapper.sh b/test_script/wrapper.sh deleted file mode 100644 index b00583a..0000000 --- a/test_script/wrapper.sh +++ /dev/null @@ -1,3 +0,0 @@ -sh ./gcc-riscv32.sh -e -sh ./sysy-riscv32.sh -e -sh ./exe-riscv32.sh \ No newline at end of file