📄 manage_test_func2.cpp
字号:
/* * $File: manage_test_func2.cpp * $Author: Jiakai -- gy_jk2126.com * $Date: Thu Mar 26 20:19:35 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_func2.h"#include "../judge.h"#define NEED_LIST_DIR#include "../common.h"#include "interface.h"using namespace ncurses;#include <pthread.h>#include <cstring>#include <vector>#include <fstream>using namespace std;struct Contestants{ string name, srcdir;};typedef vector<Contestants> Cont_array;typedef vector<Problem> Prob_array;typedef vector<string> Str_array;//---------------------Function Statements------------------------------static bool init_prob(Prob_array &prob, const Conf &conf);static bool get_contestants(Cont_array &ca, const Conf &conf);static double file_compare(double fullmark, const char *standard, const char *contestant);static void print_msg(const char *msg, Problem::Msg_color color);static void deal_line(string &line);static void* watch_stop(void *);//----------------------------------------------------------------------static Window *msg_win;static bool stopped;void func2(const char *conf_path){ Conf conf(conf_path); Prob_array prob; if (!init_prob(prob, conf)) { report_err("Failed to initialize the configuration of the problems in the contest.", __PRETTY_FUNCTION__, __LINE__); return; } if (prob.size() == 0) { message_box("You have not chosen any problem."); return; } Cont_array contestants; if (!get_contestants(contestants, conf)) { report_err("Failed to get the contestants.", __PRETTY_FUNCTION__, __LINE__); return; } if (contestants.size() == 0) { message_box("No contestants to judge."); return; } Window main_win; static const char *OPERATION_REMINDER = "Press 's' to stop the judge process."; int opr_nlines = get_str_nlines(OPERATION_REMINDER); main_win.printf(OPERATION_REMINDER); main_win.draw_hline(opr_nlines ++); Window win_cont(1, 0, opr_nlines, 0, false); Window win_prob(1, 0, opr_nlines + 1, 0, false); msg_win = new Window(get_nlines() - opr_nlines - 2, 0, opr_nlines + 2, 0); msg_win->set_title("Details"); msg_win->set_scroll(true); stopped = false; pthread_t watch_stop_thread; if (pthread_create(&watch_stop_thread, NULL, &watch_stop, NULL) != 0) { report_err("pthread_create() failed.", __PRETTY_FUNCTION__, __LINE__); return; } for (Str_array::size_type i = 0; i < contestants.size(); i ++) { win_cont.clean(); win_cont.printf("Current contestant: %s (%d of %d)", contestants[i].name.c_str(), i + 1, contestants.size()); Conf result_conf((contestants[i].srcdir + "/result.cfg").c_str()); for (Prob_array::size_type j = 0; j < prob.size(); j ++) { win_prob.clean(); win_prob.printf("Current problem: %s (%d of %d)", prob[j].name.c_str(), j + 1, prob.size()); update(); Judge_result result; if (!judge_contestant(prob[j], conf, result, contestants[i].srcdir.c_str())) { pthread_cancel(watch_stop_thread); report_err("An unexpected error occurred, function aborted.", __PRETTY_FUNCTION__, __LINE__); stopped = true; break; } write_judge_result(result, result_conf, "result", prob[j].name.c_str()); if (stopped) { pthread_cancel(watch_stop_thread); message_box("Judge process has been stopped."); break; } } if (!result_conf.save()) { pthread_cancel(watch_stop_thread); report_err("Failed to save the result.", __PRETTY_FUNCTION__, __LINE__); stopped = true; break; } if (stopped) break; } if (!stopped) pthread_cancel(watch_stop_thread); delete msg_win;}bool get_contestants(Cont_array &ca, const Conf &conf){ ca.clear(); char tmp[STRING_MAX_LEN + 1]; if (!conf.read("general", "src", tmp, STRING_MAX_LEN)) return false; Str_array names_; string srcdir(tmp); if (!list_dir(srcdir.c_str(), names_)) return false; if (names_.size() == 0) return true; char **names = new char*[names_.size() + 1]; int maxwidth = 0; for (Str_array::size_type i = 0; i < names_.size(); i ++) { names[i] = new char[names_[i].length() + 2]; strcpy(names[i] + 1, names_[i].c_str()); names[i][0] = ' '; int tmp = names_[i].length() + 5; if (tmp > maxwidth) maxwidth = tmp; } names[names_.size()] = NULL; if (*srcdir.rbegin() != '/') srcdir.append("/"); bool *chosen = new bool[names_.size()]; static const int key_allowable[] = {' ', 'a', 'c', 0}; Window main_win; Menu menu; int ncols = main_win.get_ncols() / maxwidth; if (ncols < 0) ncols = 1; menu.set_arg(main_win, names, key_allowable, "Press SPACE to mark a contestant, 'a' to choose all, or 'c' to apply.", 0, 0, -1, -1, ncols); menu.multiple_choice(chosen, names); for (Str_array::size_type i = 0; i < names_.size(); i ++) { delete []names[i]; if (chosen[i]) { Contestants c; c.name = names_[i]; c.srcdir = srcdir + c.name; ca.push_back(c); } } delete []chosen; delete []names; return true;}bool init_prob(Prob_array &prob, const Conf &conf){ int nprob; if (!conf.read("general", "problems_num", nprob) || nprob == 0) return false; prob.resize(nprob); for (int i = 0; i < nprob; i ++) { char conf_item[STRING_MAX_LEN]; sprintf(conf_item, "problem_%d_name", i); char probname[STRING_MAX_LEN + 1]; if (!conf.read("general", conf_item, probname, STRING_MAX_LEN)) return false; prob[i].name = probname; char conf_section[STRING_MAX_LEN]; sprintf(conf_section, "%s.general", probname); char tmp[STRING_MAX_LEN + 1]; if (!conf.read(conf_section, "input", tmp, STRING_MAX_LEN)) return false; prob[i].input = tmp; if (!conf.read(conf_section, "output", tmp, STRING_MAX_LEN)) return false; prob[i].output = tmp; if (!conf.read(conf_section, "source", tmp, STRING_MAX_LEN)) return false; prob[i].source_file = tmp; int points_num; if (!conf.read(conf_section, "points_num", points_num)) return false; sprintf(conf_section, "%s.points", probname); prob[i].fc = &file_compare; prob[i].pm = &print_msg; prob[i].stop_flag = &stopped; prob[i].standard_input.resize(points_num); prob[i].standard_output.resize(points_num); prob[i].time_limit.resize(points_num); prob[i].score.resize(points_num); for (int j = 0; j < points_num; j ++) { sprintf(conf_item, "%d.input", j); if (!conf.read(conf_section, conf_item, tmp, STRING_MAX_LEN)) return false; prob[i].standard_input[j] = tmp; sprintf(conf_item, "%d.output", j); if (!conf.read(conf_section, conf_item, tmp, STRING_MAX_LEN)) return false; prob[i].standard_output[j] = tmp; sprintf(conf_item, "%d.time", j); int time; if (!conf.read(conf_section, conf_item, time)) return false; prob[i].time_limit[j] = time; sprintf(conf_item, "%d.score", j); if (!conf.read(conf_section, conf_item, prob[i].score[j])) return false; } } char **item_names = new char *[prob.size() + 1]; for (Prob_array::size_type i = 0; i < prob.size(); i ++) { item_names[i] = new char[prob[i].name.length() + 2]; strcpy(item_names[i] + 1, prob[i].name.c_str()); item_names[i][0] = ' '; } item_names[prob.size()] = NULL; static const int key_allowable[] = {' ', 'a', 'c', 0}; Window main_win; Menu menu; menu.set_arg(main_win, item_names, key_allowable, "Press SPACE to mark a problem, 'a' to choose all, or 'c' to apply."); bool *exist = new bool[prob.size()]; menu.multiple_choice(exist, item_names); int np = prob.size(); Prob_array::iterator pos = prob.begin(); for (int i = 0; i < np; i ++) { if (!exist[i]) pos = prob.erase(pos); else pos ++; delete []item_names[i]; } delete []item_names; delete []exist; return true;}double file_compare(double fullmark, const char *standard, const char *contestant){ ifstream f1(standard), f2(contestant); if (!f1 || !f2) return 0; string l1, l2; while (getline(f1, l1)) { if (!getline(f2, l2)) return 0; deal_line(l1); deal_line(l2); if (l1 != l2) return 0; } return fullmark;}void deal_line(string &line){ if (*line.rbegin() == '\r') line.erase(line.length() - 1); if (*line.rbegin() != ' ') line.append(" ");}void print_msg(const char *msg, Problem::Msg_color color){ msg_win->printf_color((Ncurses_color)(color + 1), "%s", msg); update();}void* watch_stop(void *){ while (true) { if (get_key() == 's') stopped = true; } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -