📄 judge.cpp
字号:
/* * $File: judge.cpp * $Author: Jiakai -- gy_jk@126.com * $Date: Thu Mar 26 19:58:42 2009 *//*Copyright (C) (2008) (Jiakai) <gy_jk@126.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 2 of the License, or any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "judge.h"#include "common.h"#include "compile.h"#include "execute.h"#include "byteset.h"#include <cstring>#include <cstdio>using namespace std;#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <dirent.h>#include <errno.h>//------------------------------Function Statements--------------------------------------static bool get_source_path(const string &sfile_dir, const string &prob_sfile, const Conf &conf, string &source_path);static bool remove_dir(const char *path);static bool copy_file(const char *from, const char *to);//---------------------------------------------------------------------------------------bool judge_contestant(const Problem &probconf, const Conf &conf, Judge_result &result, const char *sfile_dir){ string sfile; // source file result.compile_successful = false; result.source_found = false; if (!get_source_path(sfile_dir, probconf.source_file, conf, sfile)) { if (probconf.pm != NULL) probconf.pm("Failed to find the contestant's source file.\n", Problem::MC_RED); return true; } result.source_found = true; remove_dir(TEMP_DIRECTORY); if (mkdir(TEMP_DIRECTORY, 0777) != 0) { if (probconf.pm != NULL) probconf.pm("judge_contestant : Failed to create the temporary directory.\n", Problem::MC_RED); return false; } if (chmod(TEMP_DIRECTORY, 0777) != 0) { if (probconf.pm != NULL) probconf.pm("judge_contestant : Failed to change the mode of temporary directory.", Problem::MC_RED); return false; } char objective_sfile[STRING_MAX_LEN]; strcpy(objective_sfile, TEMP_DIRECTORY); strcat(objective_sfile, "judge"); string::size_type sfile_ext_pos = sfile.length(); while (sfile[-- sfile_ext_pos] != '.'); strcat(objective_sfile, sfile.substr(sfile_ext_pos).c_str()); if (!copy_file(sfile.c_str(), objective_sfile)) { if (probconf.pm != NULL) probconf.pm("judge_contestant : Failed to copy file.\n", Problem::MC_RED); return false; } Compile_status coms; compile(objective_sfile, conf, coms); if (probconf.pm != NULL) probconf.pm("Compiling...\n", Problem::MC_WHITE); if (!coms.success) { result.compile_successful = false; result.compiler_output = coms.compiler_output; if (probconf.pm != NULL) probconf.pm(result.compiler_output.c_str(), Problem::MC_MAGENTA); return true; } char objective_executive[STRING_MAX_LEN]; sprintf(objective_executive, "%sjudge", TEMP_DIRECTORY); char objective_input[STRING_MAX_LEN]; sprintf(objective_input, "%s%s", TEMP_DIRECTORY, probconf.input.c_str()); char objective_output[STRING_MAX_LEN]; sprintf(objective_output, "%s%s", TEMP_DIRECTORY, probconf.output.c_str()); result.score.resize(probconf.standard_input.size(), 0); result.time.resize(probconf.standard_input.size(), 0); result.memory.resize(probconf.standard_input.size(), 0); result.overtime.resize(probconf.standard_input.size(), false); result.compile_successful = true; char msg[STRING_MAX_LEN]; for (unsigned int i = 0; i < probconf.standard_input.size(); i ++) { unlink(objective_output); if (probconf.pm != NULL) { sprintf(msg, "Judging test point %d...\n", i); probconf.pm(msg, Problem::MC_WHITE); } if (!copy_file(probconf.standard_input[i].c_str(), objective_input)) { if (probconf.pm != NULL) probconf.pm("judge_contestant : Failed to copy standard input file.\n", Problem::MC_RED); return false; } unsigned long realtime; unsigned int memusage; int ex_status = executeprogram(objective_executive, TEMP_DIRECTORY, probconf.time_limit[i], realtime, memusage); if (ex_status == EXECUTE_STATUS_NORMAL || ex_status == EXECUTE_STATUS_OVERTIME) { result.time[i] = realtime; result.memory[i] = memusage; if (ex_status == EXECUTE_STATUS_OVERTIME) { result.overtime[i] = true; if (probconf.pm != NULL) probconf.pm("Overtime!\n", Problem::MC_RED); } else { result.score[i] = probconf.fc(probconf.score[i], probconf.standard_output[i].c_str(), objective_output); if (probconf.pm != NULL) { if (result.score[i] == probconf.score[i]) probconf.pm("Right!\n", Problem::MC_GREEN); else probconf.pm("Wrong!\n", Problem::MC_CYAN); } } if (probconf.pm != NULL) { char msg[STRING_MAX_LEN]; sprintf(msg, "Time: %lfs Mem: %dKB\n", double(realtime) / 1e6, memusage); probconf.pm(msg, Problem::MC_WHITE); } } else if (ex_status == EXECUTE_STATUS_FAILTORUN) { result.time[i] = result.memory[i] = 0; if (probconf.pm != NULL) probconf.pm("Failed to execute the contestant's program.\n", Problem::MC_RED); } else { if (probconf.pm != NULL) probconf.pm("judge_contestant : An system error occurred while trying to execute the contestant's program.\n", Problem::MC_RED); return false; } if (probconf.stop_flag != NULL && *probconf.stop_flag) break; } remove_dir(TEMP_DIRECTORY); return true;}bool copy_file(const char *from_, const char *to_){ FILE *from = fopen(from_, "rb"); if (from == NULL) return false; FILE *to = fopen(to_, "wb"); if (to == NULL) { fclose(from); return false; } char buffer[BUFFER_SIZE]; unsigned int nchars; while ((nchars = fread(buffer, sizeof(char), BUFFER_SIZE, from)) > 0) if (fwrite(buffer, sizeof(char), nchars, to) != nchars) { fclose(from); fclose(to); unlink(to_); return false; } fclose(from); fclose(to); return true; }bool remove_dir(const char *path){ DIR *dir = opendir(path); if (dir == NULL) return false; dirent *pdirent; while ((pdirent = readdir(dir)) != NULL) { if (strcmp(pdirent->d_name, "..") == 0 || strcmp(pdirent->d_name, ".") == 0) continue; char tmp[STRING_MAX_LEN]; strcpy(tmp, path); if (tmp[strlen(tmp) - 1] != '/') strcat(tmp, "/"); strcat(tmp, pdirent->d_name); if (pdirent->d_type == DT_DIR) { if (!remove_dir(tmp)) { closedir(dir); return false; } } else { if (unlink(tmp) != 0) { closedir(dir); return false; } } } closedir(dir); return rmdir(path) == 0;}bool get_source_path(const string &sfile_dir, const string &prob_sfile, const Conf &conf, string &source_path){ int ncompilers; vector<string> compiler_ext; if (!conf.read("compiler", "num", ncompilers)) return false; for (int i = 0; i < ncompilers; i ++) { char conf_item[STRING_MAX_LEN]; sprintf(conf_item, "%d.ext", i); char tmp[STRING_MAX_LEN + 1]; if (!conf.read("compiler", conf_item, tmp, STRING_MAX_LEN)) return false; compiler_ext.push_back(tmp); } for (int i = 0; i < ncompilers; i ++) { source_path = sfile_dir; if (*source_path.rbegin() != '/') source_path.append("/"); source_path.append(prob_sfile + "." + compiler_ext[i]); if (access(source_path.c_str(), F_OK | R_OK) == 0) return true; } return false;}//-----------Judge_result->byteset: <points_num>{<score><time><memory><overtime>[]}<compile_successful><compiler_output><source_found>void write_judge_result(const Judge_result &jr, Conf &conf, const char *section, const char *item){ Byteset_o bo; bo.write((unsigned long)jr.score.size()); for (vector<double>::size_type i = 0; i < jr.score.size(); i ++) bo.write(jr.score[i]).write(jr.time[i]).write(jr.memory[i]).write((bool)jr.overtime[i]); bo.write(jr.compile_successful).write(jr.compiler_output).write(jr.source_found); conf.write(section, item, bo.str());}bool read_judge_result(Judge_result &jr, const Conf &conf, const char *section, const char *item){ unsigned long int strlen = conf.item_len(section, item); if (strlen == 0) return false; char *str = new char[strlen + 1]; if (!conf.read(section, item, str, strlen)) { delete []str; return false; } Byteset_i bi(str); delete []str; if (!bi.good()) return false; unsigned long int npoints; bi.read(npoints); if (!bi.good()) return false; jr.score.resize(npoints); jr.time.resize(npoints); jr.memory.resize(npoints); jr.overtime.resize(npoints); for (unsigned long int i = 0; i < npoints; i ++) { bool tmp; bi.read(jr.score[i]).read(jr.time[i]).read(jr.memory[i]).read(tmp); jr.overtime[i] = tmp; } bi.read(jr.compile_successful).read(jr.compiler_output).read(jr.source_found); return bi.good();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -