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:
lib/engine.rb
| 192 lines
| 5.0 KiB
| text/x-ruby
| RubyLexer
|
|
r23 | require 'fileutils' | ||
|
r78 | require File.join(File.dirname(__FILE__),'dir_init') | ||
|
r22 | |||
module Grader | ||||
|
r23 | # | ||
# A grader engine grades a submission, against anything: a test | ||||
# data, or a user submitted test data. It uses two helpers objects: | ||||
# room_maker and reporter. | ||||
# | ||||
|
r22 | class Engine | ||
|
r23 | |||
attr_writer :room_maker | ||||
attr_writer :reporter | ||||
|
r22 | |||
|
r92 | def initialize(options={}) | ||
# default options | ||||
if not options.include? :room_maker | ||||
options[:room_maker] = Grader::SubmissionRoomMaker.new | ||||
end | ||||
if not options.include? :reporter | ||||
options[:reporter] = Grader::SubmissionReporter.new | ||||
end | ||||
|
r22 | @config = Grader::Configuration.get_instance | ||
|
r23 | |||
|
r92 | @room_maker = options[:room_maker] | ||
@reporter = options[:reporter] | ||||
|
r22 | end | ||
|
r23 | |||
# takes a submission, asks room_maker to produce grading directories, | ||||
# calls grader scripts, and asks reporter to save the result | ||||
def grade(submission) | ||||
|
r102 | current_dir = FileUtils.pwd | ||
|
r22 | |||
|
r23 | user = submission.user | ||
problem = submission.problem | ||||
|
r22 | |||
r150 | begin | |||
# TODO: will have to create real exception for this | ||||
if user==nil or problem == nil | ||||
@reporter.report_error(submission,"Grading error: problem with submission") | ||||
raise "engine: user or problem is nil" | ||||
end | ||||
|
r50 | |||
r150 | # TODO: this is another hack so that output only task can be judged | |||
if submission.language!=nil | ||||
language = submission.language.name | ||||
lang_ext = submission.language.ext | ||||
else | ||||
language = 'c' | ||||
lang_ext = 'c' | ||||
end | ||||
|
r22 | |||
r150 | # This is needed because older version of std-scripts/compile | |||
# only look for c++. | ||||
if language == 'cpp' | ||||
language = 'c++' | ||||
end | ||||
|
r22 | |||
r150 | # COMMENT: should it be only source.ext? | |||
if problem!=nil | ||||
source_name = "#{problem.name}.#{lang_ext}" | ||||
else | ||||
source_name = "source.#{lang_ext}" | ||||
end | ||||
|
r23 | grading_dir = @room_maker.produce_grading_room(submission) | ||
@room_maker.save_source(submission,source_name) | ||||
problem_home = @room_maker.find_problem_home(submission) | ||||
# puts "GRADING DIR: #{grading_dir}" | ||||
# puts "PROBLEM DIR: #{problem_home}" | ||||
|
r22 | |||
|
r83 | if !FileTest.exist?(problem_home) | ||
r148 | puts "PROBLEM DIR: #{problem_home}" | |||
r150 | raise "engine: No test data." | |||
|
r83 | end | ||
|
r71 | dinit = DirInit::Manager.new(problem_home) | ||
dinit.setup do | ||||
copy_log = copy_script(problem_home) | ||||
save_copy_log(problem_home,copy_log) | ||||
end | ||||
|
r23 | |||
call_judge(problem_home,language,grading_dir,source_name) | ||||
@reporter.report(submission,"#{grading_dir}/test-result") | ||||
|
r22 | |||
|
r71 | dinit.teardown do | ||
copy_log = load_copy_log(problem_home) | ||||
clear_copy_log(problem_home) | ||||
|
r138 | clear_script(copy_log,problem_home) | ||
|
r71 | end | ||
|
r23 | |||
rescue RuntimeError => msg | ||||
|
r83 | @reporter.report_error(submission, msg) | ||
r150 | puts "ERROR: #{msg}" | |||
|
r23 | |||
ensure | ||||
@room_maker.clean_up(submission) | ||||
Dir.chdir(current_dir) # this is really important | ||||
|
r22 | end | ||
end | ||||
|
r23 | |||
|
r22 | protected | ||
def talk(str) | ||||
if @config.talkative | ||||
puts str | ||||
end | ||||
end | ||||
|
r23 | def call_judge(problem_home,language,grading_dir,fname) | ||
|
r22 | ENV['PROBLEM_HOME'] = problem_home | ||
|
r139 | ENV['RUBYOPT'] = '' | ||
|
r22 | |||
|
r23 | talk grading_dir | ||
Dir.chdir grading_dir | ||||
r174 | script_name = "#{problem_home}/script/judge" | |||
cmd = "#{script_name} #{language} #{fname}" | ||||
|
r22 | talk "CMD: #{cmd}" | ||
r174 | warn "ERROR: file does not exists #{script_name}" unless File.exists? script_name | |||
|
r22 | system(cmd) | ||
end | ||||
def get_std_script_dir | ||||
GRADER_ROOT + '/std-script' | ||||
end | ||||
def copy_script(problem_home) | ||||
script_dir = "#{problem_home}/script" | ||||
std_script_dir = get_std_script_dir | ||||
r150 | raise "engine: std-script directory not found" if !FileTest.exist?(std_script_dir) | |||
|
r22 | |||
scripts = Dir[std_script_dir + '/*'] | ||||
copied = [] | ||||
scripts.each do |s| | ||||
fname = File.basename(s) | ||||
|
r103 | next if FileTest.directory?(s) | ||
|
r22 | if !FileTest.exist?("#{script_dir}/#{fname}") | ||
copied << fname | ||||
|
r137 | FileUtils.cp(s, "#{script_dir}", :preserve => true) | ||
|
r22 | end | ||
end | ||||
return copied | ||||
end | ||||
|
r71 | |||
def copy_log_filename(problem_home) | ||||
return File.join(problem_home, '.scripts_copied') | ||||
end | ||||
def save_copy_log(problem_home, log) | ||||
f = File.new(copy_log_filename(problem_home),"w") | ||||
log.each do |fname| | ||||
f.write("#{fname}\n") | ||||
end | ||||
f.close | ||||
end | ||||
|
r22 | |||
|
r71 | def load_copy_log(problem_home) | ||
f = File.new(copy_log_filename(problem_home),"r") | ||||
log = [] | ||||
f.readlines.each do |line| | ||||
log << line.strip | ||||
end | ||||
f.close | ||||
log | ||||
end | ||||
def clear_copy_log(problem_home) | ||||
File.delete(copy_log_filename(problem_home)) | ||||
end | ||||
|
r22 | def clear_script(log,problem_home) | ||
log.each do |s| | ||||
|
r101 | FileUtils.rm("#{problem_home}/script/#{s}") | ||
|
r22 | end | ||
end | ||||
def mkdir_if_does_not_exist(dirname) | ||||
Dir.mkdir(dirname) if !FileTest.exist?(dirname) | ||||
end | ||||
end | ||||
end | ||||