This commit is contained in:
Zengtudor 2024-08-17 14:21:13 +08:00
parent 8dfd101ae9
commit 11354a5a2f
2 changed files with 48 additions and 65 deletions

View File

@ -12,7 +12,6 @@
#include <queue> #include <queue>
#include <string> #include <string>
#include <thread> #include <thread>
#include <utility>
#ifdef _WIN32 #ifdef _WIN32
#include<windows.h> #include<windows.h>
@ -61,8 +60,20 @@ struct Test{
}; };
struct ProgramRet{ struct ProgramRet{
#ifdef _WIN32
time_point<system_clock> start;
time_point<system_clock> end;
#else
time_point<system_clock> start; time_point<system_clock> start;
time_point<system_clock> end; time_point<system_clock> end;
#endif
path outPath;
unsigned int id;
friend std::ostream& operator<<(std::ostream&os,ProgramRet&ret){
os<<"ProgramRet { start: "<<ret.start<<" ,end: "<<ret.end<<"outPath: "<<ret.outPath<<" ,id: "<<ret.id<<" }";
return os;
}
}; };
template<typename T> template<typename T>
@ -168,25 +179,37 @@ int main(int argc, char* argv[]) {
} }
printValue(testsPath) printValue(testsPath)
const string exePathStr = getProtectPath(exePath); const string exePathStr = getProtectPath(exePath);
for(auto i:tests){ for (int j=1;j<=jsonTests.size();j++) {
tasks.push([i,&exePathStr,&testsPath]()->ProgramRet{ auto &i = tests[j];
string commands; tasks.push([i, &exePathStr, &testsPath]() -> ProgramRet {
std::stringstream ss; string id_str = std::to_string(i.id);
ss<<i.id; path outPath = testsPath / (id_str + ".out");
string id_str;
ss>>id_str; // 构建命令
path outPath = testsPath/(id_str+".out") ; string commands = exePathStr + " < " + getProtectPath(i.in) + " > " + getProtectPath(outPath);
commands = commands+exePathStr+" < "+getProtectPath(i.in)+" > "+getProtectPath(outPath);
LOG(commands) // 输出构建的命令进行调试
LOG(commands);
// 执行命令
auto start = high_resolution_clock::now(); auto start = high_resolution_clock::now();
system(commands.c_str()); int result = system(commands.c_str());
auto end=high_resolution_clock::now(); auto end = high_resolution_clock::now();
if (result != 0) {
cerr << "Error executing command: " << commands << endl;
exit(1);
}
return ProgramRet{ return ProgramRet{
.start=start, .start = start,
.end = end .end = end,
.outPath=outPath,
.id=i.id
}; };
}); });
} }
vector<std::future<ProgramRet>> futures;
while(tasks.size()>0){ while(tasks.size()>0){
auto i = tasks.front(); auto i = tasks.front();
tasks.pop(); tasks.pop();
@ -256,60 +279,10 @@ int compareFiles(const std::string& path1, const std::string& path2) {
return 0; // 文件内容完全一致 return 0; // 文件内容完全一致
} }
#ifdef _WIN32
void executeCommandWithRedirect(const std::string &command, const std::string &inputFile, const std::string &outputFile) {
// 创建输入输出文件的句柄
HANDLE hInput = CreateFile(inputFile.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInput == INVALID_HANDLE_VALUE) {
throw std::runtime_error("Failed to open input file: " + inputFile);
}
HANDLE hOutput = CreateFile(outputFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutput == INVALID_HANDLE_VALUE) {
CloseHandle(hInput);
throw std::runtime_error("Failed to open output file: " + outputFile);
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESTDHANDLES; // 使用标准句柄
si.hStdInput = hInput;
si.hStdOutput = hOutput;
si.hStdError = GetStdHandle(STD_ERROR_HANDLE); // 重定向错误输出
ZeroMemory(&pi, sizeof(pi));
// 将命令转换为 LPSTR 类型
LPSTR cmd = const_cast<LPSTR>(command.c_str());
// 创建进程
if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
CloseHandle(hInput);
CloseHandle(hOutput);
throw std::runtime_error("CreateProcess failed with error: " + std::to_string(GetLastError()));
}
// 等待子进程结束
WaitForSingleObject(pi.hProcess, INFINITE);
// 关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hInput);
CloseHandle(hOutput);
}
#endif
string getProtectPath(const std::filesystem::path &p){ string getProtectPath(const std::filesystem::path &p){
return "\""+p.string()+"\""; return "\""+p.string()+"\"";
} }
template<typename T> template<typename T>
T getValueOrPanic(T value){ T getValueOrPanic(T value){
AS_NE(value, Json::nullValue) AS_NE(value, Json::nullValue)

View File

@ -5,5 +5,15 @@
"args":[ "args":[
"-O3" "-O3"
], ],
"tests":[
{
"in":"a.in",
"ans":"1.ans"
},
{
"in":"a.in",
"ans":"2.ans"
}
],
"runtimeout":100 "runtimeout":100
} }