import { exec } from "child_process"; import { promisify } from "util"; import path from "path"; import fs from "fs/promises"; const execAsync = promisify(exec); const CPP_STANDARD = process.env.CPP_STANDARD || "c++14"; const CPP_FLAGS = process.env.CPP_FLAGS || "-Wall -Wno-unused-variable"; export async function validateStandardCode(code: string): Promise { if (!code?.trim()) { throw new Error("标准程序不能为空"); } if (!code.includes("#include") || !code.includes("main")) { throw new Error("标准程序必须包含 #include 和 main 函数"); } const os = await import("os"); const tempDir = path.join(os.tmpdir(), "testcase_validate_" + Date.now()); await fs.mkdir(tempDir, { recursive: true }); try { const cppFile = path.join(tempDir, "test.cpp"); const exeFile = path.join(tempDir, "test"); await fs.writeFile(cppFile, code); const compileCommand = `g++ -o "${exeFile}" "${cppFile}" -std=${CPP_STANDARD} ${CPP_FLAGS}`; await execAsync(compileCommand, { timeout: 10000 }); } catch (err) { const message = err instanceof Error ? err.message : String(err); const e = new Error(`编译失败: ${message}`); (e as Error & { code?: string }).code = "COMPILATION_ERROR"; throw e; } finally { await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {}); } } export async function executeStandardCode(code: string, input: string): Promise { const os = await import("os"); const tempDir = path.join(os.tmpdir(), "testcase_run_" + Date.now()); await fs.mkdir(tempDir, { recursive: true }); const cppFile = path.join(tempDir, "solution.cpp"); const exeFile = path.join(tempDir, "solution"); const inputFile = path.join(tempDir, "input.txt"); try { await fs.writeFile(cppFile, code); const compileCommand = `g++ -o "${exeFile}" "${cppFile}" -std=${CPP_STANDARD} ${CPP_FLAGS}`; await execAsync(compileCommand); await fs.writeFile(inputFile, input); const executeCommand = `"${exeFile}" < "${inputFile}"`; const { stdout, stderr } = await execAsync(executeCommand, { timeout: 10000 }); if (stderr) console.warn("C++ execution warning:", stderr); return stdout.trim(); } catch (err) { const message = err instanceof Error ? err.message : String(err); const e = new Error(`程序执行失败: ${message}`); (e as Error & { code?: string }).code = "EXECUTION_ERROR"; throw e; } finally { await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {}); } }