/* * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ojproblemcasesrunner.h" #include "../utils.h" #include "../settings.h" #include "../systemconsts.h" #include "../widgets/ojproblemsetmodel.h" #include OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir, const QVector& problemCases, QObject *parent): Runner(filename,arguments,workDir,parent) { mProblemCases = problemCases; } OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir, POJProblemCase problemCase, QObject *parent): Runner(filename,arguments,workDir,parent) { mProblemCases.append(problemCase); } void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase) { emit caseStarted(problemCase->getId(),index, mProblemCases.count()); auto action = finally([this,&index, &problemCase]{ emit caseFinished(problemCase->getId(), index, mProblemCases.count()); }); QProcess process; bool errorOccurred = false; process.setProgram(mFilename); process.setArguments(splitProcessCommand(mArguments)); process.setWorkingDirectory(mWorkDir); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); QString path = env.value("PATH"); QStringList pathAdded; if (pSettings->compilerSets().defaultSet()) { foreach(const QString& dir, pSettings->compilerSets().defaultSet()->binDirs()) { pathAdded.append(dir); } } pathAdded.append(pSettings->dirs().appDir()); if (!path.isEmpty()) { path+= PATH_SEPARATOR + pathAdded.join(PATH_SEPARATOR); } else { path = pathAdded.join(PATH_SEPARATOR); } env.insert("PATH",path); process.setProcessEnvironment(env); process.setProcessChannelMode(QProcess::MergedChannels); process.connect( &process, &QProcess::errorOccurred, [&](){ errorOccurred= true; }); problemCase->output.clear(); process.start(); process.waitForStarted(5000); if (process.state()==QProcess::Running) { process.write(problemCase->input.toUtf8()); process.closeWriteChannel(); } QByteArray readed; QByteArray buffer; QStringList outputLines; while (true) { process.waitForFinished(100); readed = process.readAll(); buffer += readed; if (process.state()!=QProcess::Running) { break; } if (mStop) { process.closeReadChannel(QProcess::StandardOutput); process.closeReadChannel(QProcess::StandardError); process.closeWriteChannel(); process.terminate(); process.kill(); break; } if (errorOccurred) break; QList lines = splitByteArrayToLines(buffer); // qDebug()<<"----do buffer----"; // qDebug()<=2) { for (int i=0;igetId(),line); outputLines.append(line); } buffer = lines.last(); while (buffer.endsWith('\0')) { buffer.remove(buffer.length()-1,1); } } } buffer += process.readAll(); QList lines = splitByteArrayToLines(buffer); for (int i=0;igetId(),line); outputLines.append(line); } if (errorOccurred) { //qDebug()<<"process error:"<output = linesToText(outputLines); } void OJProblemCasesRunner::run() { emit started(); auto action = finally([this]{ emit terminated(); }); for (int i=0; i < mProblemCases.size(); i++) { if (mStop) break; POJProblemCase problemCase = mProblemCases[i]; runCase(i,problemCase); } }