update
This commit is contained in:
parent
8dfd101ae9
commit
11354a5a2f
103
src/main.cpp
103
src/main.cpp
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user