/*************************************************************************** This file is part of Project Lemon Copyright (C) 2011 Zhipeng Jia 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 . ***************************************************************************/ /** * task.cpp @Project Lemon+ * Update 2018 Dust1404 **/ /** * task.cpp @Project LemonLime * Update 2019 iotang **/ #include "task.h" #include "testcase.h" #include "settings.h" #include "compiler.h" Task::Task(QObject *parent) : QObject(parent) { taskType = Traditional; comparisonMode = IgnoreSpacesMode; diffArguments = "--ignore-space-change --text --brief"; realPrecision = 3; standardInputCheck = false; standardOutputCheck = false; subFolderCheck = false; } auto Task::getTestCaseList() const -> const QList & { return testCaseList; } auto Task::getProblemTile() const -> const QString & { return problemTitle; } auto Task::getSubFolderCheck() const -> bool { return subFolderCheck; } auto Task::getSourceFileName() const -> const QString & { return sourceFileName; } auto Task::getInputFileName() const -> const QString & { return inputFileName; } auto Task::getOutputFileName() const -> const QString & { return outputFileName; } auto Task::getStandardInputCheck() const -> bool { return standardInputCheck; } auto Task::getStandardOutputCheck() const -> bool { return standardOutputCheck; } auto Task::getTaskType() const -> Task::TaskType { return taskType; } auto Task::getComparisonMode() const -> Task::ComparisonMode { return comparisonMode; } auto Task::getDiffArguments() const -> const QString & { return diffArguments; } auto Task::getRealPrecision() const -> int { return realPrecision; } auto Task::getSpecialJudge() const -> const QString & { return specialJudge; } auto Task::getInteractor() const -> const QString & { return interactor; } auto Task::getInteractorName() const -> const QString & { return interactorName; } auto Task::getGrader() const -> const QString & { return grader; } auto Task::getCompilerConfiguration(const QString &compilerName) const -> QString { return compilerConfiguration.value(compilerName); } auto Task::getAnswerFileExtension() const -> const QString & { return answerFileExtension; } auto Task::getSourceFilesPath() const -> const QStringList & { return sourceFilesPath; } auto Task::getSourceFilesName() const -> const QStringList & { return sourceFilesName; } auto Task::getGraderFilesPath() const -> const QStringList & { return graderFilesPath; } auto Task::getGraderFilesName() const -> const QStringList & { return graderFilesName; } void Task::setProblemTitle(const QString &title) { bool changed = problemTitle != title; problemTitle = title; if (changed) emit problemTitleChanged(title); } void Task::setSubFolderCheck(bool check) { subFolderCheck = check; } void Task::setSourceFileName(const QString &fileName) { sourceFileName = fileName; } void Task::setInputFileName(const QString &fileName) { inputFileName = fileName; } void Task::setOutputFileName(const QString &fileName) { outputFileName = fileName; } void Task::setStandardInputCheck(bool check) { standardInputCheck = check; } void Task::setStandardOutputCheck(bool check) { standardOutputCheck = check; } void Task::setTaskType(Task::TaskType type) { taskType = type; } void Task::setComparisonMode(Task::ComparisonMode mode) { comparisonMode = mode; } void Task::setDiffArguments(const QString &argumentsList) { diffArguments = argumentsList; } void Task::setRealPrecision(int precision) { realPrecision = precision; } void Task::setSpecialJudge(const QString &fileName) { specialJudge = fileName; } void Task::setInteractor(const QString &fileName) { interactor = fileName; } void Task::setInteractorName(const QString &fileName) { interactorName = fileName; } void Task::setGrader(const QString &fileName) { grader = fileName; } void Task::setCompilerConfiguration(const QString &compiler, const QString &configuration) { compilerConfiguration.insert(compiler, configuration); } void Task::setAnswerFileExtension(const QString &extension) { answerFileExtension = extension; } void Task::setSourceFilesPath(const QStringList &pathList) { sourceFilesPath = pathList; } void Task::setSourceFilesName(const QStringList &nameList) { sourceFilesName = nameList; } void Task::setGraderFilesPath(const QStringList &pathList) { graderFilesPath = pathList; } void Task::setGraderFilesName(const QStringList &nameList) { graderFilesName = nameList; } void Task::appendSourceFiles(const QString &path, const QString &name) { sourceFilesPath.append(path); sourceFilesName.append(name); } void Task::appendGraderFiles(const QString &path, const QString &name) { graderFilesPath.append(path); graderFilesName.append(name); } void Task::removeSourceFilesAt(int num) { if (num < sourceFilesPath.length()) { sourceFilesPath.removeAt(num); sourceFilesName.removeAt(num); } } void Task::removeGraderFilesAt(int num) { if (num < graderFilesPath.length()) { graderFilesPath.removeAt(num); graderFilesName.removeAt(num); } } void Task::addTestCase(TestCase *testCase) { testCase->setParent(this); testCase->setIndex(testCaseList.size() + 1); testCaseList.append(testCase); } auto Task::getTestCase(int index) const -> TestCase * { if (0 <= index && index < testCaseList.size()) { return testCaseList[index]; } return nullptr; } void Task::deleteTestCase(int index) { if (0 <= index && index < testCaseList.size()) { for (int i = index; i < testCaseList.size(); ++i) testCaseList[i]->clearDependenceSubtask(); delete testCaseList[index]; testCaseList.removeAt(index); } } void Task::refreshCompilerConfiguration(Settings *settings) { QList compilerList = settings->getCompilerList(); QStringList compilerNames; for (auto &i : compilerList) compilerNames.append(i->getCompilerName()); QMap::iterator p; for (p = compilerConfiguration.begin(); p != compilerConfiguration.end();) { if (! compilerNames.contains(p.key())) { p = compilerConfiguration.erase(p); } else { ++p; } } for (auto &i : compilerList) { if (compilerConfiguration.contains(i->getCompilerName())) { const QString &config = compilerConfiguration.value(i->getCompilerName()); const QStringList &configurationNames = i->getConfigurationNames(); if (! configurationNames.contains(config)) { compilerConfiguration.insert(i->getCompilerName(), "default"); } } else { compilerConfiguration.insert(i->getCompilerName(), "default"); } } emit compilerConfigurationRefreshed(); } auto Task::getTotalTimeLimit() const -> int { int total = 0; for (auto i : testCaseList) { total += i->getTimeLimit() * i->getInputFiles().size(); } return total; } auto Task::getTotalScore() const -> int { int total = 0; for (auto i : testCaseList) { total += i->getFullScore(); } return total; } void Task::writeToStream(QDataStream &out) { out << problemTitle; out << sourceFileName; out << inputFileName; out << outputFileName; out << standardInputCheck; out << standardOutputCheck; out << (static_cast(taskType) | ((static_cast(subFolderCheck)) << 8)); out << int (comparisonMode); out << diffArguments; out << realPrecision; QString _specialJudge = specialJudge; _specialJudge.replace(QDir::separator(), '/'); out << _specialJudge; if (taskType == Task::Interaction) { QString _temp = interactor; _temp.replace(QDir::separator(), '/'); out << _temp; _temp = grader; _temp.replace(QDir::separator(), '/'); out << _temp; out << interactorName; } if (taskType == Task::Communication) { out << sourceFilesPath.length(); for (int i = 0; i < sourceFilesPath.length(); i++) { QString temp = sourceFilesPath[i]; temp.replace(QDir::separator(), '/'); out << temp; temp = sourceFilesName[i]; temp.replace(QDir::separator(), '/'); out << temp; } out << graderFilesPath.length(); for (int i = 0; i < graderFilesPath.length(); i++) { QString temp = graderFilesPath[i]; temp.replace(QDir::separator(), '/'); out << temp; temp = graderFilesName[i]; temp.replace(QDir::separator(), '/'); out << temp; } } out << compilerConfiguration; out << answerFileExtension; out << testCaseList.size(); for (auto &i : testCaseList) { i->writeToStream(out); } } void Task::readFromStream(QDataStream &in) { int tmp; int count; in >> problemTitle; in >> sourceFileName; in >> inputFileName; in >> outputFileName; in >> standardInputCheck; in >> standardOutputCheck; in >> tmp; taskType = TaskType(tmp & 0xFF); subFolderCheck = tmp >> 8; in >> tmp; comparisonMode = ComparisonMode(tmp); in >> diffArguments; in >> realPrecision; in >> specialJudge; specialJudge.replace('/', QDir::separator()); if (taskType == Task::Interaction) { in >> interactor; interactor.replace('/', QDir::separator()); in >> grader; grader.replace('/', QDir::separator()); in >> interactorName; } if (taskType == Task::Communication) { int length; in >> length; sourceFilesPath.clear(); sourceFilesName.clear(); for (int i = 0; i < length; i++) { QString temp; in >> temp; temp.replace('/', QDir::separator()); sourceFilesPath.append(temp); in >> temp; temp.replace('/', QDir::separator()); sourceFilesName.append(temp); } in >> length; graderFilesPath.clear(); graderFilesName.clear(); for (int i = 0; i < length; i++) { QString temp; in >> temp; temp.replace('/', QDir::separator()); graderFilesPath.append(temp); in >> temp; temp.replace('/', QDir::separator()); graderFilesName.append(temp); } } in >> compilerConfiguration; in >> answerFileExtension; in >> count; for (int i = 0; i < count; i ++) { auto *newTestCase = new TestCase(this); newTestCase->readFromStream(in); newTestCase->setIndex(testCaseList.size() + 1); testCaseList.append(newTestCase); } }