Description:
add more languages, java and ruby add bookmark algo-bm and branch algo
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r147:9e3cee7d454d - - 5 files changed: 54 inserted, 7 deleted

@@ -1,113 +1,142
1 1 #!/usr/bin/env ruby
2 2
3 3 require 'fileutils'
4 4
5 5 ##############################
6 6 #
7 7 # Standard Compile Script
8 8 #
9 9 # Supported compilers:
10 10 # gcc, g++, and fpc.
11 11 #
12 12 ##############################
13 13
14 14 def talk(msg)
15 15 if ENV['TALKATIVE']!=nil
16 16 puts str
17 17 end
18 18 if ENV['GRADER_LOGGING']!=nil
19 19 log_fname = ENV['GRADER_LOGGING']
20 20 fp = File.open(log_fname,"a")
21 21 fp.puts("run: #{Time.new.strftime("%H:%M")} #{msg}")
22 22 fp.close
23 23 end
24 24 end
25 25
26 26 C_COMPILER = "/usr/bin/gcc"
27 27 CPLUSPLUS_COMPILER = "/usr/bin/g++"
28 28 PASCAL_COMPILER = "/usr/bin/fpc"
29 + JAVA_COMPILER = "/usr/bin/javac"
30 + RUBY_INTEPRETER = "/home/dae/.rvm/rubies/ruby-1.9.2-p320/bin/ruby"
29 31
30 32 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
31 33 CPLUSPLUS_OPTIONS = "-O2 -s -static -DCONTEST -lm -Wall"
32 34 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
35 + JAVA_OPTIONS = ""
33 36
34 37 # Check for the correct number of arguments. Otherwise, print usage.
35 38 if ARGV.length == 0 or ARGV.length > 4
36 39 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
37 40 puts
38 41 puts "<source-file> is defaulted to \"source\"."
39 42 puts "<output-file> is defaulted to \"a.out\"."
40 43 puts "<message-file> is defaulted to \"compiler_message\"."
41 44 puts
42 45 exit(127)
43 46 end
44 47
45 48 PARAMS = {
46 49 :source_file => [1,'source'],
47 50 :output_file => [2,'a.out'],
48 51 :message_file => [3,'compiler_message']
49 52 }
50 53
51 54 params = {}
52 55 params[:prog_lang] = ARGV[0]
53 56 PARAMS.each_key do |param_name|
54 57 index, default = PARAMS[param_name]
55 58 if ARGV.length > index
56 59 params[param_name] = ARGV[index]
57 60 else
58 61 params[param_name] = default
59 62 end
60 63 talk "#{param_name}: #{params[param_name]}"
61 64 end
62 65
63 66 # Remove any remaining output files or message files.
64 67 if FileTest.exists? params[:output_file]
65 68 FileUtils.rm(params[:output_file])
66 69 end
67 70 if FileTest.exists? params[:message_file]
68 71 FileUtils.rm(params[:message_file])
69 72 end
70 73
71 74 # Check if the source file exists before attempt compiling.
72 75 if !FileTest.exists? params[:source_file]
73 76 talk("ERROR: The source file does not exist!")
74 77 open(params[:message_file],"w") do |f|
75 78 f.puts "ERROR: The source file did not exist."
76 79 end
77 80 exit(127)
78 81 end
79 82
80 83 if params[:prog_lang]=='cpp'
81 84 params[:prog_lang] = 'c++'
82 85 end
83 86
84 87 # Compile.
85 88 case params[:prog_lang]
86 89
87 90 when "c"
88 91 command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS} 2> #{params[:message_file]}"
89 92 system(command)
90 93
91 94 when "c++"
92 95 command = "#{CPLUSPLUS_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS} 2> #{params[:message_file]}"
93 96 system(command)
94 97
95 98 when "pas"
96 99 command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS} > #{params[:message_file]}"
97 100 system(command)
98 101 FileUtils.mv("output", params[:output_file])
102 +
103 + when "java"
104 + #rename the file to the public class name
105 +
106 + #get the class name
107 + classname = 'DUMMY'
108 + File.foreach(params[:source_file]) do |line|
109 + md = /\s*public\s*class\s*(\w*)/.match(line)
110 + classname=md[1] if md
111 + end
112 + system("cp #{params[:source_file]} #{classname}.java")
113 + command = "#{JAVA_COMPILER} #{classname}.java > #{params[:message_file]}"
114 + system(command)
115 + File.open(params[:output_file],"w") {|file| file.write("#!/bin/sh\n/usr/bin/java #{classname}\n")}
116 + File.chmod(0755, params[:output_file])
117 +
118 + when "ruby"
119 + command = "#{RUBY_INTEPRETER} -c #{params[:source_file]} > #{params[:message_file]}"
120 + system(command)
121 + File.open(params[:output_file],"w") do |out_file|
122 + out_file.puts "#!#{RUBY_INTEPRETER}"
123 + File.open(params[:source_file],"r").each do |line|
124 + out_file.print line
125 + end
126 + end
127 + File.chmod(0755, params[:output_file])
99 128
100 129 else
101 130 talk("ERROR: Invalid language specified!")
102 131 open(params[:message_file],"w") do |f|
103 132 f.puts "ERROR: Invalid language specified!"
104 133 end
105 134 exit(127)
106 135 end
107 136
108 137 # Report success or failure.
109 138 if FileTest.exists? params[:output_file]
110 139 talk "Compilation was successful!"
111 140 else
112 141 talk "ERROR: Something was wrong during the compilation!"
113 142 end
@@ -1,175 +1,177
1 1 #!/usr/bin/env ruby
2 2
3 3 require 'fileutils'
4 4
5 5 def log(str='')
6 6 if ENV['TALKATIVE']!=nil
7 7 puts str
8 8 end
9 9 if ENV['GRADER_LOGGING']!=nil
10 10 log_fname = ENV['GRADER_LOGGING']
11 11 fp = File.open(log_fname,"a")
12 12 fp.puts("judge: #{Time.new.strftime("%H:%M")} #{str}")
13 13 fp.close
14 14 end
15 15 end
16 16
17 17 problem_home = ENV['PROBLEM_HOME']
18 18
19 19 def execute(command, error_message="")
20 20 if not system(command)
21 21 msg = "ERROR: #{error_message}"
22 22 log msg
23 23 raise(msg)
24 24 end
25 25 end
26 26
27 27 def call_and_log(error_message)
28 28 begin
29 29 yield
30 30 rescue
31 31 msg = "ERROR: #{error_message}"
32 32 log msg
33 33 raise msg
34 34 end
35 35 end
36 36
37 37 def clear_and_create_empty_dir(dir)
38 38 FileUtils.rm_rf(dir, :secure => true)
39 39 call_and_log("Cannot make directory #{dir}.") { FileUtils.mkdir(dir) }
40 40 end
41 41
42 42 # ARGV[0] --- language
43 43 # ARGV[1] --- program source file
44 44 # ARGV[2] --- test result directory
45 45 # ARGV[3] --- sandbox directory
46 46
47 47 if ARGV.length < 2 || ARGV.length > 4
48 48 puts "Usage: judge <language> <program-source> [<test-result-directory>] [<sandbox-directory>]"
49 49 puts " <sandbox-directory> is defaulted to ./sandbox"
50 50 puts " <test-result-directory> is defaulted to ./test-result"
51 51 puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it."
52 52 exit(127)
53 53 end
54 54
55 55 language = ARGV[0]
56 - if language != "c" && language != "c++" && language != "pas"
56 + if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby"
57 57 log "You specified a language that is not supported: #{language}."
58 58 exit(127)
59 59 end
60 60
61 61 source_file = ARGV[1]
62 62 if File.exist?(source_file) == false
63 63 log "The source file does not exist."
64 64 exit(127)
65 65 end
66 66
67 67 log "Making test result and sandbox directories..."
68 68
69 69 current_dir = FileUtils.pwd
70 70 current_dir.strip!
71 71
72 72 if ARGV.length >= 3
73 73 test_result_dir = ARGV[2]
74 74 else
75 75 test_result_dir = "#{current_dir}/test-result"
76 76 end
77 77
78 78 log "Test result directory: #{test_result_dir}"
79 79 clear_and_create_empty_dir(test_result_dir)
80 80
81 81 if ARGV.length >= 4
82 82 sandbox_dir = ARGV[3]
83 83 else
84 84 sandbox_dir = "#{current_dir}/sandbox"
85 85 end
86 86 log "Sandbox directory: #{sandbox_dir}"
87 87 clear_and_create_empty_dir(sandbox_dir)
88 88
89 89 # Compile
90 90 log
91 91 log "Compiling..."
92 92 call_and_log("Cannot copy the source file to #{sandbox_dir}") {
93 93 FileUtils.cp(source_file, sandbox_dir)
94 94 }
95 95 begin
96 96 Dir.chdir sandbox_dir
97 97 rescue
98 98 log "ERROR: Cannot change directory to #{sandbox_dir}."
99 99 exit(127)
100 100 end
101 101 execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!")
102 102 compile_message = open("compiler_message").read
103 103 compile_message.strip!
104 104 call_and_log("Cannot move the compiler message to #{test_result_dir}.") {
105 105 FileUtils.mv("compiler_message", test_result_dir)
106 106 }
107 107 if !FileTest.exist?("a.out")
108 108 log "Cannot compile the source code. See message in #{test_result_dir}/compile_message"
109 109 exit(127)
110 110 else
111 111 call_and_log("Cannot move the compiled program to #{test_result_dir}") {
112 112 FileUtils.mv("a.out",test_result_dir)
113 + if language == "java" then Dir["*.class"].each { |file| FileUtils.mv(file,test_result_dir)} end
113 114 }
114 115 FileUtils.rm_rf("#{sandbox_dir}/.")
115 116 end
116 117
117 118 require "#{problem_home}/script/test_dsl.rb"
118 119 load "#{problem_home}/test_cases/all_tests.cfg"
119 120 problem = Problem.get_instance
120 121
121 122 if problem.well_formed? == false
122 123 log "The problem specification is not well formed."
123 124 exit(127)
124 125 end
125 126
126 127 # Doing the testing.
127 128 (1..(problem.num_tests)).each do |test_num|
128 129
129 130 $stdout.print "[#{test_num}]"
130 131 $stdout.flush
131 132
132 133 log "Test number: #{test_num}"
133 134
134 135 call_and_log("Cannot copy the compiled program into #{sandbox_dir}") {
135 136 FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true)
137 + if language == "java" then Dir["#{test_result_dir}/*.class"].each { |file| FileUtils.cp(file,sandbox_dir)} end
136 138 }
137 139
138 140 begin
139 141 execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script")
140 142 rescue
141 143 # do nothing
142 144 end
143 145
144 146 call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") {
145 147 FileUtils.mkdir "#{test_result_dir}/#{test_num}"
146 148 }
147 149 call_and_log("Cannot copy the result file into #{test_result_dir}/#{test_num}") {
148 150 FileUtils.mv "#{sandbox_dir}/result", "#{test_result_dir}/#{test_num}"
149 151 }
150 152 call_and_log("Cannot copy the comment file into #{test_result_dir}/#{test_num}") {
151 153 FileUtils.mv "#{sandbox_dir}/comment", "#{test_result_dir}/#{test_num}"
152 154 }
153 155 call_and_log("Cannot copy the output file into #{test_result_dir}/#{test_num}") {
154 156 FileUtils.mv "#{sandbox_dir}/output.txt", "#{test_result_dir}/#{test_num}"
155 157 }
156 158 call_and_log("Cannot clear #{sandbox_dir}") {
157 159 FileUtils.rm_rf(Dir.glob("#{sandbox_dir}/*"), :secure => true)
158 160 }
159 161 end
160 162
161 163 $stdout.print "[done]\n"
162 164
163 165 # Grade
164 166 log
165 167 log "Grading..."
166 168 begin
167 169 Dir.chdir test_result_dir
168 170 rescue
169 171 log "ERROR: Cannot change directory to #{test_result_dir}."
170 172 exit(127)
171 173 end
172 174 execute("#{problem_home}/script/grade", "An error occured during grading!")
173 175
174 176 log
175 177 log "All done!"
@@ -1,159 +1,175
1 1 #!/usr/bin/env ruby
2 2
3 3 require 'fileutils'
4 4
5 5 def log(str='')
6 6 if ENV['TALKATIVE']!=nil
7 7 puts str
8 8 end
9 9 if ENV['GRADER_LOGGING']!=nil
10 10 log_fname = ENV['GRADER_LOGGING']
11 11 fp = File.open(log_fname,"a")
12 12 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
13 13 fp.close
14 14 end
15 15 end
16 16
17 17 def extract_time(t)
18 - # puts "TIME: #{t}"
19 - if (result=/^(.*)r(.*)u(.*)s/.match(t))
18 + #puts "TIME: #{t}"
19 + #if (result=/^(.*)real(.*)wall(.*)s/.match(t))
20 + if (result=/^OK \((.*) sec real\, (.*) sec wall,.*MB, (.*) syscalls/.match(t))
20 21 {:real => result[1], :user => result[2], :sys => result[3]}
21 22 else
22 23 #{:real => 0, :user => 0, :sys => 0}
23 24 #puts "ERROR READING RUNNING TIME: #{t}"
24 25 raise "Error reading running time: #{t}"
25 26 end
26 27 end
27 28
28 29 def compile_box(source,bin)
29 30 system("g++ #{source} -o #{bin}")
30 31 end
31 32
32 33 if ARGV.length < 2 || ARGV.length > 3
33 34 puts "Usage: run <language> <test-num> [<program-name>]"
34 35 exit(127)
35 36 end
36 37
37 38 language = ARGV[0]
38 39 test_num = ARGV[1].to_i
39 40 if ARGV.length > 2
40 41 program_name = ARGV[2]
41 42 else
42 43 program_name = "a.out"
43 44 end
44 45
45 46 problem_home = ENV['PROBLEM_HOME']
46 47 require "#{problem_home}/script/test_dsl.rb"
47 48 load "#{problem_home}/test_cases/all_tests.cfg"
48 49 problem = Problem.get_instance
49 50
50 51 if problem.well_formed? == false
51 52 log "The problem specification is not well formed."
52 53 exit(127)
53 54 end
54 55
55 56 # Check if the test number is okay.
56 57 if test_num <= 0 || test_num > problem.num_tests
57 58 log "You have specified a wrong test number."
58 59 exit(127)
59 60 end
60 61
61 62 #####################################
62 63 # Set the relavant file names here. #
63 64 #####################################
64 65
65 66 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
66 67
67 68 #####################################
68 69
69 70 time_limit = problem.get_time_limit test_num
70 71 mem_limit = problem.get_mem_limit(test_num) * 1024
71 72
72 73 # Copy the input file.
73 74 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
74 75
75 76 # check if box is there, if not, compile it!
76 77 if !File.exists?("#{problem_home}/script/box")
77 78 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
78 79 compile_box("#{problem_home}/script/box.cc",
79 80 "#{problem_home}/script/box")
80 81 end
81 82
82 83 # Hide PROBLEM_HOME
83 84 ENV['PROBLEM_HOME'] = nil
84 85
85 86 # Run the program.
86 87 #run_command = "/usr/bin/time -f \"#{time_output_format}\" 2>run_result #{problem_home}/script/box_new -a 2 -f -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name}"
88 + #
87 89
88 - run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} 2>run_result"
90 +
91 +
92 +
93 + case language
94 + when "java"
95 + # for java, we have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
96 + run_command = "#{problem_home}/script/box -T -t #{time_limit} -s getppid -s clone -s wait4 -p /usr/bin/ -p ./ -i #{input_file_name} -o output.txt #{program_name} 2>run_result"
97 + when "ruby"
98 + run_command = "#{problem_home}/script/box -T -t #{time_limit} -s getppid -s wait4 -s clone -s set_robust_list -s futex -s sigaltstack -p /dev/urandom -p ./ -p /home/dae/.rvm/rubies/ruby-1.9.2-p320/ -p #{problem_home}/ -i #{input_file_name} -o output.txt #{program_name} 2>run_result"
99 + when "c++"
100 + run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} 2>run_result"
101 + else
102 + run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} 2>run_result"
103 + end
104 +
89 105
90 106 log "Running test #{test_num}..."
91 107 log run_command
92 108 log
93 109 system(run_command)
94 110
95 111 # Restore PROBLEM_HOME
96 112 ENV['PROBLEM_HOME'] = problem_home
97 113
98 114 # Create the result file.
99 115 result_file = File.new("result", "w")
100 116 comment_file = File.new("comment", "w")
101 117
102 118 # Check if the program actually produced any output.
103 119 run_result_file = File.new("run_result", "r")
104 120 run_result = run_result_file.readlines
105 121 run_result_file.close
106 122
107 123 run_stat = run_result[run_result.length-1]
108 124 running_time = extract_time(run_stat)
109 125
110 126 report = lambda{ |status, points, comment|
111 127 result_file.write status.strip
112 128 result_file.write "\n"
113 129 result_file.write points.to_s.strip
114 130 result_file.write "\n"
115 131 result_file.write run_stat.strip
116 132 result_file.write "\n"
117 133 result_file.close
118 134 FileUtils.rm "run_result"
119 135 # `rm output.txt` --- keep the output
120 136
121 137 comment_file.write comment
122 138
123 139 # added for debuggin --- jittat
124 140 comment_file.write "--run-result--\n"
125 141 run_result.each do |l|
126 142 comment_file.write l
127 143 end
128 144
129 145 comment_file.close
130 146
131 147 log "Done!"
132 148 exit(0)
133 149 }
134 150
135 151 if run_result[0][0,2] != "OK"
136 152 log "There was a runtime error."
137 153 report.call(run_result[0], 0, "No comment.\n")
138 154 end
139 155
140 - if running_time[:user].to_f + running_time[:sys].to_f > time_limit
156 + if running_time[:user].to_f > time_limit
141 157 log "Time limit exceeded."
142 158 report.call("Time limit exceeded", 0, "No comment.\n")
143 159 end
144 160
145 161 # Run 'check' to evaluate the output.
146 162 #puts "There was no runtime error. Proceed to checking the output."
147 163 check_command = "#{problem_home}/script/check #{language} #{test_num}"
148 164 log "Checking the output..."
149 165 log check_command
150 166 if not system(check_command)
151 167 log "Problem with check script"
152 168 report.call("Incorrect",0,"Check script error.\n")
153 169 exit(127)
154 170 end
155 171
156 172 check_file = File.new("check_result", "r")
157 173 check_file_lines = check_file.readlines
158 174
159 175 report.call(check_file_lines[0], check_file_lines[1], "No comment.\n")
@@ -1,64 +1,64
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2 2
3 3 problem_home = ENV['PROBLEM_HOME']
4 4 require "#{problem_home}/script/test_dsl.rb"
5 5
6 6 if ARGV.length < 2
7 7 puts "Usage: check <language> <test-number> [<output-file>]"
8 8 exit(0)
9 9 end
10 10
11 11 language = ARGV[0]
12 12 test_num = ARGV[1].to_i
13 13 if ARGV.length >= 3
14 14 output_file_name = ARGV[2]
15 15 else
16 16 output_file_name = "output.txt"
17 17 end
18 18
19 19 load "#{problem_home}/test_cases/all_tests.cfg"
20 20 problem = Problem.get_instance
21 21
22 22 output_file = File.new(output_file_name, "r")
23 23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 24 result_file = File.new("check_result", "w")
25 25
26 26 output_file_content = output_file.read
27 27 answer_file_content = answer_file.read
28 28
29 29 report_correct = lambda {
30 30 result_file.write "Correct\n"
31 31 result_file.write problem.get_score(test_num)
32 32 result_file.write "\n"
33 33 result_file.close
34 34 exit(0)
35 35 }
36 36
37 37 report_wrong = lambda {
38 38 result_file.write "Incorrect\n"
39 39 result_file.write "0\n"
40 40 result_file.close
41 41 exit(0)
42 42 }
43 43
44 44 ##################
45 45 # Your code here #
46 46 ##################
47 47
48 48 ########### THIS IS FOR CHECKING TEXT ##########
49 49
50 50 # check visible text
51 51
52 52 out_items = output_file_content.split
53 53 ans_items = answer_file_content.split
54 54
55 55 if out_items.length != ans_items.length
56 56 report_wrong.call
57 57 else
58 58 out_items.length.times do |i|
59 59 if out_items[i]!=ans_items[i]
60 60 report_wrong.call
61 61 end
62 62 end
63 63 report_correct.call
64 64 end
@@ -1,47 +1,47
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2 2
3 3 problem_home = ENV['PROBLEM_HOME']
4 4 require "#{problem_home}/script/test_dsl.rb"
5 5
6 6 if ARGV.length < 2
7 7 puts "Usage: check <language> <test-number> [<output-file>]"
8 8 exit(0)
9 9 end
10 10
11 11 language = ARGV[0]
12 12 test_num = ARGV[1].to_i
13 13 if ARGV.length >= 3
14 14 output_file_name = ARGV[2]
15 15 else
16 16 output_file_name = "output.txt"
17 17 end
18 18
19 19 load "#{problem_home}/test_cases/all_tests.cfg"
20 20 problem = Problem.get_instance
21 21
22 22 output_file = File.new(output_file_name, "r")
23 23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 24 result_file = File.new("check_result", "w")
25 25
26 26 output_file_content = output_file.read
27 27 answer_file_content = answer_file.read
28 28
29 29 report_correct = lambda {
30 30 result_file.write "Correct\n"
31 31 result_file.write problem.get_score(test_num)
32 32 result_file.write "\n"
33 33 result_file.close
34 34 exit(0)
35 35 }
36 36
37 37 report_wrong = lambda {
38 38 result_file.write "Incorrect\n"
39 39 result_file.write "0\n"
40 40 result_file.close
41 41 exit(0)
42 42 }
43 43
44 44 ##################
45 45 # Your code here #
46 46 ##################
47 47 report_correct.call
You need to be logged in to leave comments. Login now