|
|
#!/usr/bin/ruby
|
|
|
|
|
|
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
|
|
|
|
|
|
problem_home = ENV['PROBLEM_HOME']
|
|
|
|
|
|
def execute(command, error_message="")
|
|
|
if not system(command)
|
|
|
msg = "ERROR: #{error_message}"
|
|
|
log msg
|
|
|
raise msg
|
|
|
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 <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]
|
|
|
if language != "c" && language != "c++" && language != "pas"
|
|
|
log "You specified a language that is not supported: #{language}."
|
|
|
exit(127)
|
|
|
end
|
|
|
|
|
|
source_file = ARGV[1]
|
|
|
if File.exist?(source_file) == false
|
|
|
log "The source file does not exist."
|
|
|
exit(127)
|
|
|
end
|
|
|
|
|
|
log "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
|
|
|
log "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
|
|
|
log "Sandbox directory: #{sandbox_dir}"
|
|
|
system("rm -Rf #{sandbox_dir}")
|
|
|
execute("mkdir #{sandbox_dir}", "Cannot make directory #{sandbox_dir}")
|
|
|
|
|
|
# Compile
|
|
|
log
|
|
|
log "Compiling..."
|
|
|
execute("cp #{source_file} #{sandbox_dir}", "Cannot copy the source file to #{sandbox_dir}")
|
|
|
begin
|
|
|
Dir.chdir sandbox_dir
|
|
|
rescue
|
|
|
log "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 !FileTest.exist?("a.out")
|
|
|
log "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
|
|
|
log "The problem specification is not well formed."
|
|
|
exit(127)
|
|
|
end
|
|
|
|
|
|
# Doing the testing.
|
|
|
(1..(problem.num_tests)).each do |test_num|
|
|
|
|
|
|
$stdout.print "[#{test_num}]"
|
|
|
$stdout.flush
|
|
|
|
|
|
log "Test number: #{test_num}"
|
|
|
execute("cp #{test_result_dir}/a.out #{sandbox_dir}", "Cannot copy the compiled program into #{sandbox_dir}")
|
|
|
begin
|
|
|
execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script")
|
|
|
rescue
|
|
|
# do nothing
|
|
|
end
|
|
|
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("mv #{sandbox_dir}/output.txt #{test_result_dir}/#{test_num}", "Cannot copy the output file into #{test_result_dir}/#{test_num}")
|
|
|
execute("rm -Rf #{sandbox_dir}/*", "Cannot clear #{sandbox_dir}")
|
|
|
end
|
|
|
|
|
|
$stdout.print "[done]\n"
|
|
|
|
|
|
# Grade
|
|
|
log
|
|
|
log "Grading..."
|
|
|
begin
|
|
|
Dir.chdir test_result_dir
|
|
|
rescue
|
|
|
log "ERROR: Cannot change directory to #{test_result_dir}."
|
|
|
exit(127)
|
|
|
end
|
|
|
execute("#{problem_home}/script/grade", "An error occured during grading!")
|
|
|
|
|
|
log
|
|
|
log "All done!"
|
|
|
|