Description:
autonew skips submissions with bad problems, forbids getch, better compiler msg when preprocessing fails, reports compile error when the executable is too large (100MB)
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r132:ca6ce454fda9 - - 2 files changed: 24 inserted, 10 deleted

@@ -204,96 +204,99
204 grader_general_loop(engine, grader_proc, options) do |runner|
204 grader_general_loop(engine, grader_proc, options) do |runner|
205 runner.grade_oldest_test_request
205 runner.grade_oldest_test_request
206 end
206 end
207 end
207 end
208
208
209 def grader_autonew_loop(grader_proc, options)
209 def grader_autonew_loop(grader_proc, options)
210 log "Grader: autonew"
210 log "Grader: autonew"
211
211
212 if options[:report]
212 if options[:report]
213 result_collector = ResultCollector.new
213 result_collector = ResultCollector.new
214 else
214 else
215 result_collector = nil
215 result_collector = nil
216 end
216 end
217
217
218 if options[:dry_run]
218 if options[:dry_run]
219 puts "Running in dry mode"
219 puts "Running in dry mode"
220 end
220 end
221
221
222 prob_reporter = Grader::SubmissionReporter.new(:dry_run => options[:dry_run],
222 prob_reporter = Grader::SubmissionReporter.new(:dry_run => options[:dry_run],
223 :result_collector => result_collector)
223 :result_collector => result_collector)
224
224
225 engine = Grader::Engine.new(:reporter => prob_reporter)
225 engine = Grader::Engine.new(:reporter => prob_reporter)
226 runner = Grader::Runner.new(engine, grader_proc)
226 runner = Grader::Runner.new(engine, grader_proc)
227
227
228 grader_proc.report_active if grader_proc!=nil
228 grader_proc.report_active if grader_proc!=nil
229
229
230 latest_submitted_at = nil
230 latest_submitted_at = nil
231 graded_submission_ids = {}
231 graded_submission_ids = {}
232
232
233 while true
233 while true
234
234
235 if check_stopfile # created by calling grader stop
235 if check_stopfile # created by calling grader stop
236 clear_stopfile
236 clear_stopfile
237 log "stopped (with stop file)"
237 log "stopped (with stop file)"
238 break
238 break
239 end
239 end
240
240
241 if latest_submitted_at==nil
241 if latest_submitted_at==nil
242 submissions = Submission.all
242 submissions = Submission.all
243 else
243 else
244 submissions = Submission.all(:conditions => ["submitted_at >= :latest",
244 submissions = Submission.all(:conditions => ["submitted_at >= :latest",
245 {:latest => latest_submitted_at}])
245 {:latest => latest_submitted_at}])
246 end
246 end
247
247
248 graded_any = false
248 graded_any = false
249
249
250 if submissions.length != 0
250 if submissions.length != 0
251 submissions.each do |submission|
251 submissions.each do |submission|
252 + if (submission.problem == nil) or (!submission.problem.available)
253 + next
254 + end
252 if ! graded_submission_ids[submission.id]
255 if ! graded_submission_ids[submission.id]
253 runner.grade_submission(submission)
256 runner.grade_submission(submission)
254 graded_submission_ids[submission.id] = true
257 graded_submission_ids[submission.id] = true
255 if (!latest_submitted_at or
258 if (!latest_submitted_at or
256 latest_submitted_at < submission.submitted_at)
259 latest_submitted_at < submission.submitted_at)
257 latest_submitted_at = submission.submitted_at
260 latest_submitted_at = submission.submitted_at
258 end
261 end
259 puts "graded: #{submission.id}"
262 puts "graded: #{submission.id}"
260 puts "latest: #{latest_submitted_at}"
263 puts "latest: #{latest_submitted_at}"
261 graded_any = true
264 graded_any = true
262 end
265 end
263 end
266 end
264 end
267 end
265
268
266 if ! graded_any
269 if ! graded_any
267 sleep(1)
270 sleep(1)
268 end
271 end
269 end
272 end
270 end
273 end
271
274
272 def grader_grade_problems(grader_proc, options)
275 def grader_grade_problems(grader_proc, options)
273 if options[:report]
276 if options[:report]
274 result_collector = ResultCollector.new
277 result_collector = ResultCollector.new
275 else
278 else
276 result_collector = nil
279 result_collector = nil
277 end
280 end
278
281
279 if options[:dry_run]
282 if options[:dry_run]
280 puts "Running in dry mode"
283 puts "Running in dry mode"
281 end
284 end
282
285
283 prob_reporter = Grader::SubmissionReporter.new(:dry_run => options[:dry_run],
286 prob_reporter = Grader::SubmissionReporter.new(:dry_run => options[:dry_run],
284 :result_collector => result_collector)
287 :result_collector => result_collector)
285 engine = Grader::Engine.new(:reporter => prob_reporter)
288 engine = Grader::Engine.new(:reporter => prob_reporter)
286 runner = Grader::Runner.new(engine, grader_proc)
289 runner = Grader::Runner.new(engine, grader_proc)
287
290
288 grader_proc.report_active if grader_proc!=nil
291 grader_proc.report_active if grader_proc!=nil
289
292
290 ARGV.each do |prob_name|
293 ARGV.each do |prob_name|
291 prob = Problem.find_by_name(prob_name)
294 prob = Problem.find_by_name(prob_name)
292 if prob==nil
295 if prob==nil
293 puts "cannot find problem: #{prob_name}"
296 puts "cannot find problem: #{prob_name}"
294 else
297 else
295 runner.grade_problem(prob)
298 runner.grade_problem(prob)
296 end
299 end
297 end
300 end
298
301
299 if options[:report]
302 if options[:report]
@@ -37,94 +37,105
37 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
37 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
38 puts
38 puts
39 puts "<source-file> is defaulted to \"source\"."
39 puts "<source-file> is defaulted to \"source\"."
40 puts "<output-file> is defaulted to \"a.out\"."
40 puts "<output-file> is defaulted to \"a.out\"."
41 puts "<message-file> is defaulted to \"compiler_message\"."
41 puts "<message-file> is defaulted to \"compiler_message\"."
42 puts
42 puts
43 exit(127)
43 exit(127)
44 end
44 end
45
45
46 PARAMS = {
46 PARAMS = {
47 :source_file => [1,'source'],
47 :source_file => [1,'source'],
48 :output_file => [2,'a.out'],
48 :output_file => [2,'a.out'],
49 :message_file => [3,'compiler_message']
49 :message_file => [3,'compiler_message']
50 }
50 }
51
51
52 params = {}
52 params = {}
53 params[:prog_lang] = ARGV[0]
53 params[:prog_lang] = ARGV[0]
54 PARAMS.each_key do |param_name|
54 PARAMS.each_key do |param_name|
55 index, default = PARAMS[param_name]
55 index, default = PARAMS[param_name]
56 if ARGV.length > index
56 if ARGV.length > index
57 params[param_name] = ARGV[index]
57 params[param_name] = ARGV[index]
58 else
58 else
59 params[param_name] = default
59 params[param_name] = default
60 end
60 end
61 talk "#{param_name}: #{params[param_name]}"
61 talk "#{param_name}: #{params[param_name]}"
62 end
62 end
63
63
64 # Remove any remaining output files or message files.
64 # Remove any remaining output files or message files.
65 if FileTest.exists? params[:output_file]
65 if FileTest.exists? params[:output_file]
66 FileUtils.rm(params[:output_file])
66 FileUtils.rm(params[:output_file])
67 end
67 end
68 if FileTest.exists? params[:message_file]
68 if FileTest.exists? params[:message_file]
69 FileUtils.rm(params[:message_file])
69 FileUtils.rm(params[:message_file])
70 end
70 end
71
71
72 # Check if the source file exists before attempt compiling.
72 # Check if the source file exists before attempt compiling.
73 if !FileTest.exists? params[:source_file]
73 if !FileTest.exists? params[:source_file]
74 talk("ERROR: The source file does not exist!")
74 talk("ERROR: The source file does not exist!")
75 open(params[:message_file],"w") do |f|
75 open(params[:message_file],"w") do |f|
76 f.puts "ERROR: The source file did not exist."
76 f.puts "ERROR: The source file did not exist."
77 end
77 end
78 exit(127)
78 exit(127)
79 end
79 end
80
80
81 if params[:prog_lang]=='cpp':
81 if params[:prog_lang]=='cpp':
82 params[:prog_lang] = 'c++'
82 params[:prog_lang] = 'c++'
83 end
83 end
84
84
85 - forbidden_functions = ['system', 'fopen', 'freopen', 'open', 'remove', 'rename']
85 + forbidden_functions = ['system', 'fopen', 'freopen', 'open', 'remove', 'rename', 'getch']
86 redefine_list = []
86 redefine_list = []
87 forbidden_count = 0
87 forbidden_count = 0
88 forbidden_key = (rand(8999) + 1000).to_s
88 forbidden_key = (rand(8999) + 1000).to_s
89 forbidden_functions.each do |f|
89 forbidden_functions.each do |f|
90 redefine_list << "-D#{f}=forbidden#{forbidden_key}#{forbidden_count}"
90 redefine_list << "-D#{f}=forbidden#{forbidden_key}#{forbidden_count}"
91 forbidden_count += 1
91 forbidden_count += 1
92 end
92 end
93 redefine_str = redefine_list.join ' '
93 redefine_str = redefine_list.join ' '
94 puts redefine_str
94 puts redefine_str
95
95
96 # Compile.
96 # Compile.
97 case params[:prog_lang]
97 case params[:prog_lang]
98
98
99 when "c"
99 when "c"
100 - command = "#{C_COMPILER} -E #{params[:source_file]} -o source_prep.c"
100 + command = "#{C_COMPILER} -E #{params[:source_file]} -o source_prep.c 2> #{params[:message_file]}"
101 system(command)
101 system(command)
102 - command = "#{C_COMPILER} source_prep.c #{redefine_str} -o #{params[:output_file]} #{C_OPTIONS} 2> #{params[:message_file]}"
102 + if FileTest.exist? "source_prep.c"
103 - puts command
103 + command = "#{C_COMPILER} source_prep.c #{redefine_str} -o #{params[:output_file]} #{C_OPTIONS} 2> #{params[:message_file]}"
104 - system(command)
104 + system(command)
105 + end
105
106
106 when "c++"
107 when "c++"
107 - command = "#{CPLUSPLUS_COMPILER} -E #{params[:source_file]} -o source_prep.cpp"
108 + command = "#{CPLUSPLUS_COMPILER} -E #{params[:source_file]} -o source_prep.cpp 2> #{params[:message_file]}"
108 system(command)
109 system(command)
109 - command = "#{CPLUSPLUS_COMPILER} #{redefine_str} source_prep.cpp -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS} 2> #{params[:message_file]}"
110 + if FileTest.exist? "source_prep.cpp"
110 - system(command)
111 + command = "#{CPLUSPLUS_COMPILER} #{redefine_str} source_prep.cpp -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS} 2> #{params[:message_file]}"
111 -
112 + system(command)
113 + end
114 +
112 when "pas"
115 when "pas"
113 command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS} > #{params[:message_file]}"
116 command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS} > #{params[:message_file]}"
114 system(command)
117 system(command)
115 FileUtils.mv("output", params[:output_file])
118 FileUtils.mv("output", params[:output_file])
116
119
117 else
120 else
118 talk("ERROR: Invalid language specified!")
121 talk("ERROR: Invalid language specified!")
119 open(params[:message_file],"w") do |f|
122 open(params[:message_file],"w") do |f|
120 f.puts "ERROR: Invalid language specified!"
123 f.puts "ERROR: Invalid language specified!"
121 end
124 end
122 exit(127)
125 exit(127)
123 end
126 end
124
127
125 # Report success or failure.
128 # Report success or failure.
126 if FileTest.exists? params[:output_file]
129 if FileTest.exists? params[:output_file]
127 - talk "Compilation was successful!"
130 + talk "Compilation was successful!"
131 +
132 + if File.size(params[:output_file]) > 100000000
133 + talk "But the executable is too big."
134 + open(params[:message_file],"w+") do |f|
135 + f.puts "Executable is too large."
136 + end
137 + File.delete(params[:output_file])
138 + end
128 else
139 else
129 talk "ERROR: Something was wrong during the compilation!"
140 talk "ERROR: Something was wrong during the compilation!"
130 end
141 end
You need to be logged in to leave comments. Login now