diff --git a/std-script/judge b/std-script/judge new file mode 100755 --- /dev/null +++ b/std-script/judge @@ -0,0 +1,114 @@ +#!/usr/bin/ruby + +problem_home = ENV['PROBLEM_HOME'] + +def execute(command, error_message="") + if not system(command) + puts "ERROR: #{error_message}" + exit(127) + end +end + +# ARGV[0] --- language +# ARGV[1] --- program source file +# ARGV[2] --- test result directory +# ARGV[3] --- sandbox directory + +if ARGV.length < 2 || ARGV.length > 4 + puts "Usage: judge [] []" + puts " is defaulted to ./sandbox" + puts " is defaulted to ./test-result" + puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it." + exit(127) +end + +language = ARGV[0] +if language != "c" && language != "c++" && language != "pascal" + puts "You specified a language that is not supported." + exit(127) +end + +source_file = ARGV[1] +if File.exist?(source_file) == false + puts "The source file does not exist." + exit(127) +end + +puts "Making test result and sandbox directories..." + +current_dir = `pwd` +current_dir.strip! + +if ARGV.length >= 3 + test_result_dir = ARGV[2] +else + test_result_dir = "#{current_dir}/test-result" +end +puts "Test result directory: #{test_result_dir}" +system("rm -Rf #{test_result_dir}") +execute("mkdir #{test_result_dir}", "Cannot make directory #{test_result_dir}.") + +if ARGV.length >= 4 + sandbox_dir = ARGV[3] +else + sandbox_dir = "#{current_dir}/sandbox" +end +puts "Sandbox directory: #{sandbox_dir}" +system("rm -Rf #{sandbox_dir}") +execute("mkdir #{sandbox_dir}", "Cannot make directory #{sandbox_dir}") + +# Compile +puts +puts "Compiling..." +execute("cp #{source_file} #{sandbox_dir}", "Cannot copy the source file to #{sandbox_dir}") +begin + Dir.chdir sandbox_dir +rescue + puts "ERROR: Cannot change directory to #{sandbox_dir}." + exit(127) +end +execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!") +compile_message = `cat compiler_message` +compile_message.strip! +execute("mv compiler_message #{test_result_dir}", "Cannot move the compiler message to #{test_result_dir}.") +if compile_message != "" + puts "Cannot compile the source code. See message in #{test_result_dir}/compile_message" + exit(127) +else + execute("mv a.out #{test_result_dir}", "Cannot move the compiled program to #{test_result_dir}") + system("rm -Rf #{sandbox_dir}/*") +end + +require "#{problem_home}/script/test_dsl.rb" +load "#{problem_home}/test_cases/all_tests.cfg" +problem = Problem.get_instance + +if problem.well_formed? == false + puts "The problem specification is not well formed." + exit(127) +end + +# Doing the testing. +(1..(problem.num_tests)).each do |test_num| + puts + execute("cp #{test_result_dir}/a.out #{sandbox_dir}", "Cannot copy the compiled program into #{sandbox_dir}") + execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script") + execute("mkdir #{test_result_dir}/#{test_num}", "Cannot create directory #{test_result_dir}/#{test_num}") + execute("mv #{sandbox_dir}/result #{test_result_dir}/#{test_num}", "Cannot copy the result file into #{test_result_dir}/#{test_num}") + execute("mv #{sandbox_dir}/comment #{test_result_dir}/#{test_num}", "Cannot copy the comment file into #{test_result_dir}/#{test_num}") + execute("rm -Rf #{sandbox_dir}/*", "Cannot clear #{sandbox_dir}") +end + +# Grade +puts +puts "Grading..." +begin + Dir.chdir test_result_dir +rescue + puts "ERROR: Cannot change directory to #{test_result_dir}." + exit(127) +end +execute("#{problem_home}/script/grade", "An error occured during grading!") + +puts +puts "All done!"