⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 judge.cpp

📁 linux 下 源代码测试系统 用 tar 打开
💻 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 + -