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

📄 manage_test.cpp

📁 linux 下 源代码测试系统 用 tar 打开
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * $File: manage_test.cpp * $Author: Jiakai -- gy_jk@126.com * $Date: Thu Mar 26 20:30:31 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 "manage_test.h"#include "auto_add_points.h"#define NEED_LIST_DIR#include "../common.h"#include "../conf.h"#include "manage_test_func2.h"#include "../judge.h"#include "interface.h"using namespace ncurses;#include <sys/types.h>#include <unistd.h>#include <errno.h>#include <cstring>#include <cstdio>#include <vector>#include <iostream>#include <sstream>#include <iomanip>#include <algorithm>using namespace std;#define DEFAULT_DATA_DIR	"data"#define DEFAULT_DATA_DIR_S	"data/%s/"typedef void (*Func_t) (const char *);typedef vector<string> Str_array;struct Test_point{	int time;	double score;	char input[STRING_MAX_LEN + 1], output[STRING_MAX_LEN + 1];	Test_point& operator = (const Test_point &a)	{		time = a.time;		score = a.score;		strcpy(input, a.input);		strcpy(output, a.output);	}};typedef vector<Test_point> Test_point_array;struct Contest_option{	Str_array compiler_ext, compiler_command;	char source_path[STRING_MAX_LEN + 1], contest_name[STRING_MAX_LEN + 1];	Contest_option(const Conf &conf);	void write_conf(Conf &conf);};struct Problem_conf{	char name[STRING_MAX_LEN + 1], input[STRING_MAX_LEN + 1], output[STRING_MAX_LEN + 1], source[STRING_MAX_LEN + 1];	Test_point_array points;	Problem_conf(const Conf &conf, int prob_num);	Problem_conf(const char *probname);	void write_conf(Conf &conf);};struct Contestant_result{	string name;	double total_score;	unsigned long total_time;	typedef vector<Judge_result> Jr_array;	Jr_array result;	vector<bool> judged;};bool operator < (const Contestant_result &n1, const Contestant_result &n2);typedef vector<Contestant_result> Conr_array;//----------------------Function Statements-----------------------------------static void func1(const char *path);static void func3(const char *path);static void create_problem(Conf &conf);static void delete_problem(Conf &conf, int prob);static void modify_problem(Conf &conf, int prob);static void add_new_test_points(Test_point_array &tpa, const char *probname);static void modify_test_point(Test_point &tp);static void modify_contest_opt(Contest_option &co);static void init_contestant_result(Str_array &probnames, Conr_array &conr, const Conf &conf, const char *conf_path);static void show_contestant_detail(const Str_array &probnames, const Contestant_result &cre);static void output_problem_detail(ostream &outstr, const Judge_result &result);static bool save_html(const char *path, const Conr_array &result, const Conf &conf, const Str_array &probnames);static void auto_conf_prob(Conf &conf);static bool auto_add_prob_points(Problem_conf &conf, const char *conf_path);//----------------------------------------------------------------------------Contest_option::Contest_option(const Conf &conf){	int ncp;	if (!conf.read("compiler", "num", ncp))	{		compiler_ext.push_back("cpp");		compiler_command.push_back("g++ %s.cpp -O2 -o %s");		compiler_ext.push_back("c");		compiler_command.push_back("gcc %s.c -O2 -o %s");		compiler_ext.push_back("pas");		compiler_command.push_back("fpc %s.pas");	} else	{		for (int i = 0; i < ncp; i ++)		{			char tmp[STRING_MAX_LEN + 1], conf_item[STRING_MAX_LEN];			sprintf(conf_item, "%d.ext", i);			if (!conf.read("compiler", conf_item, tmp, STRING_MAX_LEN))				report_err("Fail to read @%d.ext .\n", __PRETTY_FUNCTION__, __LINE__);			compiler_ext.push_back(tmp);			sprintf(conf_item, "%d.command", i);			if (!conf.read("compiler", conf_item, tmp, STRING_MAX_LEN))				report_err("Fail to read @%d.command .\n", __PRETTY_FUNCTION__, __LINE__);			compiler_command.push_back(tmp);		}	}	if (!conf.read("general", "src", source_path, STRING_MAX_LEN))		strcpy(source_path, "src/");	if (!conf.read("general", "name", contest_name, STRING_MAX_LEN))		read_input("Please enter the name of contest: ", contest_name, "Contest");}void Contest_option::write_conf(Conf &conf){	conf.delsection("compiler");	conf.delsection("compiler.command");	if (compiler_ext.size() != compiler_command.size())		report_err("An strange error occurred...\n", __PRETTY_FUNCTION__, __LINE__);	else	{		conf.write("compiler", "num", int(compiler_ext.size()));		for (vector<string>::size_type i = 0; i < compiler_ext.size(); i ++)		{			char conf_item[STRING_MAX_LEN];			sprintf(conf_item, "%d.ext", i);			conf.write("compiler", conf_item, compiler_ext[i].c_str());			sprintf(conf_item, "%d.command", i);			conf.write("compiler", conf_item, compiler_command[i].c_str());			conf.write("compiler.command", compiler_ext[i].c_str(), compiler_command[i].c_str());		}	}	conf.delitem("general", "src");	conf.delitem("general", "name");	conf.write("general", "src", source_path);	conf.write("general", "name", contest_name);}void manage_test(const char *path){	if (seteuid(getuid()) != 0 || setegid(getuid()) != 0)	{		perror("manage_test : seteuid || setegid ");		return;	}	do	{		string tmp(path);		int pos = tmp.length() - 1;		while (pos >= 0 && tmp[pos] != '/')			pos --;		if (pos < 0)			break;		if (chdir(tmp.substr(0, pos + 1).c_str()))		{			perror("manage_test : chdir ");			return;		}		path += pos + 1;	} while(0);	char tmp[STRING_MAX_LEN];	sprintf(tmp, "Welcome to %s .\nPlease use UP and DOWN keys to select a task and press ENTER to start it.\nThe current configuration file is: %s \n", VERSION_INF, path);	static const char * const menu_items[] = {"Modify the contest", "OK, judge now!", "View Reports", "Exit", NULL};	static const int key_allowable[] = {ENTER, 0};	init();	Window main_win;	Menu menu;	menu.set_arg(main_win, menu_items, key_allowable, tmp, 6, 30);	try	{		while (true)		{			menu.wait_key();			int ch = menu.get_choice();			static const Func_t func[] = {&func1, &func2, &func3};			if (ch != 3)				func[ch](path);			else break;		}	} catch (Error err)	{		menu.free();		end();		cerr << "An error occurred: \n" << err.msg << endl;		delete []err.msg;		return;	}	menu.free();	end();}void func1(const char *path){	Conf conf(path);	const char * OPERATION_REMINDER = "Press 'c' to create a new problem, 'd' to delete a subsistent problem, ENTER to modify a subsistent problem or general options, 'a' to automatically configure the problems, or 'r' to return to the main menu.\n";	Contest_option conopt(conf);	static const int key_allowable[] = {'c', 'd', ENTER, 'a', 'r', 0};	int nproblems = 0;	char **probnames = NULL;#define FREE_PROBNAMES() \	do \	{ \		if (probnames == NULL) \			break; \		for (int i = 0; i < nproblems + 2; i ++) \			delete []probnames[i]; \		delete []probnames; \		probnames = NULL; \	} \	while (false)	Window main_win;	Menu menu;	bool changed = true;	while (true)	{		if (changed)		{			FREE_PROBNAMES();			if (!conf.read("general", "problems_num", nproblems))				nproblems = 0;			probnames = new char *[nproblems + 2];			probnames[0] = new char[STRING_MAX_LEN];			strcpy(probnames[0], "general options");			for (int i = 1; i <= nproblems; i ++)			{				char str[STRING_MAX_LEN];				sprintf(str, "problem_%d_name", i - 1);				probnames[i] = new char[STRING_MAX_LEN + 1];				if (!conf.read("general", str, probnames[i], STRING_MAX_LEN))					report_err("Fail to read @prbname.\n", __PRETTY_FUNCTION__, __LINE__);			}			probnames[nproblems + 1] = NULL;			menu.set_arg(main_win, probnames, key_allowable, OPERATION_REMINDER);			changed = false;		}		int key_pressed = menu.wait_key();		if (key_pressed == 'r')			break;		int choice = menu.get_choice();		switch (key_pressed)		{			case 'c' : create_problem(conf); changed = true; break;			case 'd' : delete_problem(conf, choice - 1); changed = true; break;			case ENTER : 				if (choice == 0)					modify_contest_opt(conopt);				else modify_problem(conf, choice - 1);				break;			case 'a': auto_conf_prob(conf); changed = true; break;		}	}	menu.free();	FREE_PROBNAMES();#undef FREE_PROBNAME	conopt.write_conf(conf);	if (!conf.save())		report_err("Fail to save the configuration file.\n", __PRETTY_FUNCTION__, __LINE__);}void create_problem(Conf &conf){	int np;	if (!conf.read("general", "problems_num", np))		np = 0;	np ++;	conf.write("general", "problems_num", np);	char problem_name[STRING_MAX_LEN];	problem_name[0] = 0;	while (problem_name[0] == 0)		read_input("Please enter the name of the problem(you can not modify it later unless you modify the configuration file manually): ", problem_name);	char conf_item[STRING_MAX_LEN];	while (true)	{		for (int i = 0; i < np - 1; i ++)		{			sprintf(conf_item, "problem_%d_name", i);			char tmp[STRING_MAX_LEN + 1];			if (conf.read("general", conf_item, tmp, STRING_MAX_LEN) && strcmp(tmp, problem_name) == 0)			{				read_input("The name of the problem has already existed, please choose another: ", problem_name);				i = -1;			}		}		break;	}	sprintf(conf_item, "problem_%d_name", np - 1);	conf.write("general", conf_item, problem_name);	modify_problem(conf, np - 1);}void delete_problem(Conf &conf, int prob){	if (prob < 0)	{		message_box("Oh, you can not do so...");		return;	}	char conf_item[STRING_MAX_LEN];	sprintf(conf_item, "problem_%d_name", prob);	char probname[STRING_MAX_LEN + 1];	if (!conf.read("general", conf_item, probname, STRING_MAX_LEN))	{		report_err("Fail to read @probname.\n", __PRETTY_FUNCTION__, __LINE__);		return;	}	char msg[STRING_MAX_LEN];	sprintf(msg, "Are you sure to delete problem \"%s\" ? All information and judge results about this problem will be deleted. (y/n)", probname);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -