Show More
Commit Description:
add option -A <opt> to box. This options allow more argument to be explicitly passed to the program...
Commit Description:
add option -A <opt> to box. This options allow more argument to be explicitly passed to the program
We have to use this because if the argument we wish to pass to the program is option (in -? format),
box will intepret it as its option and failed accordingly.
be noted that, by the definition of getopt, these options will be put after original argument
(check the code for more info)
References:
File last commit:
Show/Diff file:
Action:
std-script/judge
| 180 lines
| 5.0 KiB
| text/plain
| TextLexer
|
|
r137 | #!/usr/bin/env ruby | ||
|
r0 | |||
|
r101 | require 'fileutils' | ||
|
r22 | def log(str='') | ||
if ENV['TALKATIVE']!=nil | ||||
puts str | ||||
end | ||||
if ENV['GRADER_LOGGING']!=nil | ||||
log_fname = ENV['GRADER_LOGGING'] | ||||
fp = File.open(log_fname,"a") | ||||
fp.puts("judge: #{Time.new.strftime("%H:%M")} #{str}") | ||||
fp.close | ||||
end | ||||
end | ||||
|
r0 | problem_home = ENV['PROBLEM_HOME'] | ||
def execute(command, error_message="") | ||||
if not system(command) | ||||
|
r31 | msg = "ERROR: #{error_message}" | ||
log msg | ||||
|
r137 | raise(msg) | ||
|
r0 | end | ||
end | ||||
|
r101 | def call_and_log(error_message) | ||
begin | ||||
yield | ||||
rescue | ||||
msg = "ERROR: #{error_message}" | ||||
log msg | ||||
raise msg | ||||
end | ||||
end | ||||
def clear_and_create_empty_dir(dir) | ||||
FileUtils.rm_rf(dir, :secure => true) | ||||
call_and_log("Cannot make directory #{dir}.") { FileUtils.mkdir(dir) } | ||||
end | ||||
|
r0 | # 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 <language> <program-source> [<test-result-directory>] [<sandbox-directory>]" | ||||
puts " <sandbox-directory> is defaulted to ./sandbox" | ||||
puts " <test-result-directory> 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] | ||||
r165 | if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby" && language != "python" && language != "php" | |||
|
r53 | log "You specified a language that is not supported: #{language}." | ||
|
r0 | exit(127) | ||
end | ||||
source_file = ARGV[1] | ||||
r161 | ENV['SOURCE_NAME'] = source_file | |||
|
r0 | if File.exist?(source_file) == false | ||
|
r22 | log "The source file does not exist." | ||
|
r0 | exit(127) | ||
end | ||||
|
r22 | log "Making test result and sandbox directories..." | ||
|
r0 | |||
|
r102 | current_dir = FileUtils.pwd | ||
|
r0 | current_dir.strip! | ||
if ARGV.length >= 3 | ||||
test_result_dir = ARGV[2] | ||||
else | ||||
test_result_dir = "#{current_dir}/test-result" | ||||
end | ||||
|
r101 | |||
|
r22 | log "Test result directory: #{test_result_dir}" | ||
|
r101 | clear_and_create_empty_dir(test_result_dir) | ||
|
r0 | |||
if ARGV.length >= 4 | ||||
sandbox_dir = ARGV[3] | ||||
else | ||||
sandbox_dir = "#{current_dir}/sandbox" | ||||
end | ||||
|
r22 | log "Sandbox directory: #{sandbox_dir}" | ||
|
r101 | clear_and_create_empty_dir(sandbox_dir) | ||
|
r0 | |||
# Compile | ||||
|
r22 | log | ||
log "Compiling..." | ||||
|
r101 | call_and_log("Cannot copy the source file to #{sandbox_dir}") { | ||
FileUtils.cp(source_file, sandbox_dir) | ||||
} | ||||
|
r0 | begin | ||
Dir.chdir sandbox_dir | ||||
rescue | ||||
|
r22 | log "ERROR: Cannot change directory to #{sandbox_dir}." | ||
|
r0 | exit(127) | ||
end | ||||
execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!") | ||||
|
r102 | compile_message = open("compiler_message").read | ||
|
r0 | compile_message.strip! | ||
|
r101 | call_and_log("Cannot move the compiler message to #{test_result_dir}.") { | ||
FileUtils.mv("compiler_message", test_result_dir) | ||||
} | ||||
|
r3 | if !FileTest.exist?("a.out") | ||
|
r22 | log "Cannot compile the source code. See message in #{test_result_dir}/compile_message" | ||
|
r0 | exit(127) | ||
else | ||||
|
r101 | call_and_log("Cannot move the compiled program to #{test_result_dir}") { | ||
FileUtils.mv("a.out",test_result_dir) | ||||
r147 | if language == "java" then Dir["*.class"].each { |file| FileUtils.mv(file,test_result_dir)} end | |||
r154 | if language == "python" then Dir["*.pyc"].each { |file| FileUtils.mv(file,test_result_dir)} end | |||
|
r101 | } | ||
FileUtils.rm_rf("#{sandbox_dir}/.") | ||||
|
r0 | 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 | ||||
|
r22 | log "The problem specification is not well formed." | ||
|
r0 | exit(127) | ||
end | ||||
# Doing the testing. | ||||
(1..(problem.num_tests)).each do |test_num| | ||||
|
r61 | |||
$stdout.print "[#{test_num}]" | ||||
$stdout.flush | ||||
|
r22 | log "Test number: #{test_num}" | ||
|
r137 | |||
|
r101 | call_and_log("Cannot copy the compiled program into #{sandbox_dir}") { | ||
|
r137 | FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true) | ||
r147 | if language == "java" then Dir["#{test_result_dir}/*.class"].each { |file| FileUtils.cp(file,sandbox_dir)} end | |||
r154 | if language == "python" then Dir["#{test_result_dir}/*.pyc"].each { |file| FileUtils.cp(file,sandbox_dir)} end | |||
|
r101 | } | ||
|
r137 | |||
|
r31 | begin | ||
r161 | execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script") | |||
|
r31 | rescue | ||
# do nothing | ||||
end | ||||
|
r137 | |||
|
r101 | call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") { | ||
FileUtils.mkdir "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot copy the result file into #{test_result_dir}/#{test_num}") { | ||||
FileUtils.mv "#{sandbox_dir}/result", "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot copy the comment file into #{test_result_dir}/#{test_num}") { | ||||
FileUtils.mv "#{sandbox_dir}/comment", "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot copy the output file into #{test_result_dir}/#{test_num}") { | ||||
FileUtils.mv "#{sandbox_dir}/output.txt", "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot clear #{sandbox_dir}") { | ||||
FileUtils.rm_rf(Dir.glob("#{sandbox_dir}/*"), :secure => true) | ||||
} | ||||
|
r0 | end | ||
|
r61 | $stdout.print "[done]\n" | ||
|
r0 | # Grade | ||
|
r22 | log | ||
log "Grading..." | ||||
|
r0 | begin | ||
Dir.chdir test_result_dir | ||||
rescue | ||||
|
r22 | log "ERROR: Cannot change directory to #{test_result_dir}." | ||
|
r0 | exit(127) | ||
end | ||||
execute("#{problem_home}/script/grade", "An error occured during grading!") | ||||
|
r22 | log | ||
log "All done!" | ||||