judge_result testcase_impl::run(env &env, compiler::result &cr) { judge_result result = {0}; shared_ptr<temp_dir> dir = _prepare_dir(env.pool(), cr); env.grant_access(dir->path()); path_a executable_path; if (cr.compiler->target_executable_path().empty()) { executable_path = dir->path(); executable_path.push(cr.compiler->target_filename().c_str()); } else { executable_path = cr.compiler->target_executable_path(); } shared_ptr<testcase_impl::context> context(new testcase_impl::context(*this)); judge::bunny bunny(env, false, executable_path.c_str(), cr.compiler->target_command_line(), dir->path(), context->stdin_pipe.read_handle(), context->stdout_pipe.write_handle(), context->stderr_pipe.write_handle(), limit_); context->stdin_pipe.close_read(); context->stdout_pipe.close_write(); context->stderr_pipe.close_write(); // stdin thread env.pool().thread_pool().queue([context]()->void { try { istream in(&context->stdin_buf); os_filebuf out_buf(context->stdin_pipe.write_handle(), false); ostream out(&out_buf); const size_t buffer_size = 4096; util::stream_copy<buffer_size>(in, out); } catch (...) { } context->stdin_pipe.close_write(); context->stdin_event.set(); }); // stderr thread env.pool().thread_pool().queue([context]()->void { try { os_filebuf in_buf(context->stderr_pipe.read_handle(), false); istream in(&in_buf); const size_t buffer_size = 4096; util::stream_copy_n<buffer_size>(in, context->stderr_stream, context->stderr_output_limit); } catch (...) { } context->stderr_pipe.close_read(); context->stderr_event.set(); }); bunny.start(); // judge { istream model_in(&context->stdout_buf); os_filebuf user_buf(context->stdout_pipe.read_handle(), false); istream user_in(&user_buf); pair<bool, string> compare_result = compare_stream(model_in, user_in); if (compare_result.first) { result.flag = max(result.flag, JUDGE_ACCEPTED); } else { result.flag = max(result.flag, JUDGE_WRONG_ANSWER); } judge_output_ = move(compare_result.second); // read all user output const size_t buffer_size = 4096; util::stream_copy<buffer_size>(user_in, onullstream()); } bunny::result bunny_result = bunny.wait(); DWORD wait_result = winstl::wait_for_multiple_objects(context->stdin_event, context->stderr_event, true, INFINITE); if (wait_result == WAIT_FAILED) { throw win32_exception(::GetLastError()); } result.flag = max(result.flag, bunny_result.flag); result.time_usage_ms = bunny_result.time_usage_ms; result.memory_usage_kb = bunny_result.memory_usage_kb; result.runtime_error = bunny_result.runtime_error; result.judge_output = judge_output_.c_str(); user_output_ = context->stderr_stream.str(); result.user_output = user_output_.c_str(); return result; }
int compare_toc(toc_smart_ptr& pattern, info_base* base_ptr) { char pattern_buf[LARGE_BUFSIZ]; ostringstream pattern_out(pattern_buf, LARGE_BUFSIZ, ios::out); print_toc(pattern, pattern_out); toc_smart_ptr x(base_ptr, pattern.toc_node_oid()); char db_buf[LARGE_BUFSIZ]; ostringstream db_out(db_buf, LARGE_BUFSIZ, ios::out); print_toc(x, db_out); return compare_stream(pattern_out, db_out); }
int compare_graphic(graphic_smart_ptr& pattern, info_base* base_ptr) { char pattern_buf[LARGE_BUFSIZ]; ostrstream pattern_out(pattern_buf, LARGE_BUFSIZ, ios::out); print_graphic(pattern, pattern_out, false); char loc[BUFSIZ]; strcpy(loc, pattern.locator()); graphic_smart_ptr x( base_ptr, loc ); char db_buf[LARGE_BUFSIZ]; ostrstream db_out(db_buf, LARGE_BUFSIZ, ios::out); print_graphic(x, db_out, false); return compare_stream(pattern_out, db_out); }
int compare_stylesheet(stylesheet_smart_ptr& pattern, info_base* base_ptr) { char pattern_buf[LARGE_BUFSIZ]; ostringstream pattern_out(pattern_buf, LARGE_BUFSIZ, ios::out); print_stylesheet(pattern, pattern_out); char loc[BUFSIZ]; int len = MIN(strlen(pattern.name()), BUFSIZ - 1); *((char *) memcpy(loc, pattern.name(), len) + len) = '\0'; stylesheet_smart_ptr x( base_ptr, loc ); char db_buf[LARGE_BUFSIZ]; ostringstream db_out(db_buf, LARGE_BUFSIZ, ios::out); print_stylesheet(x, db_out); return compare_stream(pattern_out, db_out); }