Description:
remove pyflake; allow more syscall
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r221:59c4defa0c58 - - 2 files changed: 6 inserted, 4 deleted

@@ -1,194 +1,196
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(str='')
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")} #{str}")
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 29 JAVA_COMPILER = "/usr/bin/javac"
30 30 RUBY_INTERPRETER = "/usr/bin/ruby"
31 31 PYTHON_INTERPRETER = "/usr/bin/python3"
32 32 PYTHON_CHECKER = "/usr/bin/pyflakes"
33 33 PHP_INTERPRETER = "/usr/bin/php"
34 34 HASKELL_COMPILER = "/usr/bin/ghc"
35 35
36 36 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
37 37 CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall"
38 38 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
39 39 JAVA_OPTIONS = ""
40 40 PYTHON_OPTIONS = ""
41 41 PHP_OPTIONS = "-l"
42 42 HASKELL_OPTIONS = ""
43 43
44 44 # Check for the correct number of arguments. Otherwise, print usage.
45 45 if ARGV.length == 0 or ARGV.length > 4
46 46 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
47 47 puts
48 48 puts "<source-file> is defaulted to \"source\"."
49 49 puts "<output-file> is defaulted to \"a.out\"."
50 50 puts "<message-file> is defaulted to \"compiler_message\"."
51 51 puts
52 52 exit(127)
53 53 end
54 54
55 55 PARAMS = {
56 56 :source_file => [1,'source'],
57 57 :output_file => [2,'a.out'],
58 58 :message_file => [3,'compiler_message']
59 59 }
60 60
61 61 params = {}
62 62 params[:prog_lang] = ARGV[0]
63 63 PARAMS.each_key do |param_name|
64 64 index, default = PARAMS[param_name]
65 65 if ARGV.length > index
66 66 params[param_name] = ARGV[index]
67 67 else
68 68 params[param_name] = default
69 69 end
70 70 talk "#{param_name}: #{params[param_name]}"
71 71 end
72 72
73 73 # Remove any remaining output files or message files.
74 74 if FileTest.exists? params[:output_file]
75 75 FileUtils.rm(params[:output_file])
76 76 end
77 77 if FileTest.exists? params[:message_file]
78 78 FileUtils.rm(params[:message_file])
79 79 end
80 80
81 81 # Check if the source file exists before attempt compiling.
82 82 if !FileTest.exists? params[:source_file]
83 83 talk("ERROR: The source file does not exist!")
84 84 open(params[:message_file],"w") do |f|
85 85 f.puts "ERROR: The source file did not exist."
86 86 end
87 87 exit(127)
88 88 end
89 89
90 90 if params[:prog_lang]=='cpp'
91 91 params[:prog_lang] = 'c++'
92 92 end
93 93
94 94 # Compile.
95 95 case params[:prog_lang]
96 96
97 97 when "c"
98 98 command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS}"
99 99 system(command, err: params[:message_file])
100 100
101 101 when "c++"
102 102 command = "#{CPLUSPLUS_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS}"
103 103 system(command, err: params[:message_file])
104 104
105 105 when "pas"
106 106 command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS}"
107 107 system(command,out: params[:message_file])
108 108 FileUtils.mv("output", params[:output_file])
109 109
110 110 when "java"
111 111 #rename the file to the public class name
112 112
113 113 #get the class name
114 114 classname = 'DUMMY'
115 115 source = Array.new
116 116 File.foreach(params[:source_file],'r:UTF-8') do |line|
117 117 line.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
118 118 md = /\s*public\s*class\s*(\w*)/.match(line)
119 119 classname=md[1] if md
120 120 source << line unless line =~ /\s*package\s*\w+\s*\;/
121 121 end
122 122 File.open("#{classname}.java","w") do |file|
123 123 source.each do |s|
124 124 file.puts s
125 125 end
126 126 end
127 127 #system("cp #{params[:source_file]} #{classname}.java")
128 128 command = "#{JAVA_COMPILER} -encoding utf8 #{classname}.java"
129 129 system(command, err: params[:message_file])
130 130 if File.exists?(classname + ".class")
131 131 File.open(params[:output_file],"w") {|file| file.write("#{classname}")}
132 132 end
133 133 if classname == 'DUMMY'
134 134 File.open(params[:message_file],"w") {|file| file.write("Cannot find any public class in the source code\n")}
135 135 end
136 136
137 137 when "ruby"
138 138 command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}"
139 139 if system(command, err: params[:message_file])
140 140 File.open(params[:output_file],"w") do |out_file|
141 141 out_file.puts "#!#{RUBY_INTERPRETER}"
142 142 File.open(params[:source_file],"r").each do |line|
143 143 out_file.print line
144 144 end
145 145 end
146 146 File.chmod(0755, params[:output_file])
147 147 end
148 148
149 149 when "python"
150 - command = "#{PYTHON_CHECKER} #{params[:source_file]}"
151 - if system(command, out: params[:message_file])
150 + #command = "#{PYTHON_CHECKER} #{params[:source_file]}"
151 + #if system(command, out: params[:message_file])
152 152 #compile to python bytecode
153 153 command = "#{PYTHON_INTERPRETER} -c \"import py_compile; py_compile.compile('#{params[:source_file]}','#{params[:source_file]}c');\""
154 154 puts "compile: #{command}"
155 - system(command)
155 + system(command, err: params[:message_file])
156 + if FileTest.exists?("#{params[:source_file]}c")
156 157 puts "pwd: " + Dir.pwd
157 158 Dir.new('.').each {|file| puts file}
158 159 File.open(params[:output_file],"w") do |out_file|
159 160 out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
160 161 end
161 162 File.chmod(0755, params[:output_file])
162 163 FileUtils.cp("#{params[:source_file]}c",params[:output_file])
163 164 end
165 + #end
164 166
165 167 when "php"
166 168 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
167 169 if system(command, err: params[:message_file])
168 170 File.open(params[:output_file],"w") do |out_file|
169 171 out_file.puts "#!#{PHP_INTERPRETER}"
170 172 File.open(params[:source_file],"r").each do |line|
171 173 out_file.print line
172 174 end
173 175 end
174 176 File.chmod(0755, params[:output_file])
175 177 end
176 178
177 179 when "haskell"
178 180 command = "#{HASKELL_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{HASKELL_OPTIONS}"
179 181 system(command, err: params[:message_file])
180 182
181 183 else
182 184 talk("ERROR: Invalid language specified!")
183 185 open(params[:message_file],"w") do |f|
184 186 f.puts "ERROR: Invalid language specified!"
185 187 end
186 188 exit(127)
187 189 end
188 190
189 191 # Report success or failure.
190 192 if FileTest.exists? params[:output_file]
191 193 talk "Compilation was successful!"
192 194 else
193 195 talk "ERROR: Something was wrong during the compilation!"
194 196 end
@@ -1,192 +1,192
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 18 # puts "TIME: #{t}"
19 19 if (result=/^(.*)r(.*)u(.*)s/.match(t))
20 20 {:real => result[1], :user => result[2], :sys => result[3]}
21 21 else
22 22 #{:real => 0, :user => 0, :sys => 0}
23 23 #puts "ERROR READING RUNNING TIME: #{t}"
24 24 raise "Error reading running time: #{t}"
25 25 end
26 26 end
27 27
28 28 def compile_box(source,bin)
29 29 system("g++ #{source} -o #{bin}")
30 30 end
31 31
32 32 if ARGV.length < 2 || ARGV.length > 3
33 33 puts "Usage: run <language> <test-num> [<program-name>]"
34 34 exit(127)
35 35 end
36 36
37 37 language = ARGV[0]
38 38 test_num = ARGV[1].to_i
39 39 if ARGV.length > 2
40 40 program_name = ARGV[2]
41 41 else
42 42 program_name = "a.out"
43 43 end
44 44
45 45 problem_home = ENV['PROBLEM_HOME']
46 46 source_name = ENV['SOURCE_NAME']
47 47 require "#{problem_home}/script/test_dsl.rb"
48 48 load "#{problem_home}/test_cases/all_tests.cfg"
49 49 problem = Problem.get_instance
50 50
51 51 sandbox_dir = Dir.getwd
52 52
53 53 if problem.well_formed? == false
54 54 log "The problem specification is not well formed."
55 55 exit(127)
56 56 end
57 57
58 58 # Check if the test number is okay.
59 59 if test_num <= 0 || test_num > problem.num_tests
60 60 log "You have specified a wrong test number."
61 61 exit(127)
62 62 end
63 63
64 64 #####################################
65 65 # Set the relavant file names here. #
66 66 #####################################
67 67
68 68 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
69 69
70 70 #####################################
71 71
72 72 time_limit = problem.get_time_limit test_num
73 73 mem_limit = problem.get_mem_limit(test_num) * 1024
74 74
75 75 # Copy the input file.
76 76 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
77 77
78 78 # check if box is there, if not, compile it!
79 79 if !File.exists?("#{problem_home}/script/box")
80 80 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
81 81 compile_box("#{problem_home}/script/box.cc",
82 82 "#{problem_home}/script/box")
83 83 end
84 84
85 85 # Hide PROBLEM_HOME
86 86 ENV['PROBLEM_HOME'] = nil
87 87 ENV['SOURCE_NAME'] = nil
88 88
89 89 # Run the program.
90 90 #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}"
91 91 #
92 92
93 93 JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
94 94 RUBY_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /lib64/ -p /dev/urandom -p #{sandbox_dir}/#{program_name} -p #{sandbox_dir}/ -s set_robust_list -s sched_getaffinity -s clock_gettime -s sigaltstack -s pipe2 -s clone -s futex -s openat -s pipe"
95 - PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p /dev/urandom -p /usr/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -p /proc/sys/crypto/fips_enabled -p /proc/mounts -p /var/lib/dpkg/status -s statfs -s set_robust_list -s openat -s sysinfo -s recvmsg -s connect -s socket -s sendto -s futex -s sigaltstack -E PYTHONNOUSERSITE=yes"
95 + PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p /dev/urandom -p /usr/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -p /proc/sys/crypto/fips_enabled -p /proc/self/status -p /proc/mounts -p /var/lib/dpkg/status -s statfs -s set_robust_list -s openat -s sysinfo -s recvmsg -s connect -s socket -s sendto -s futex -s sigaltstack -E PYTHONNOUSERSITE=yes"
96 96 PHP_OPTION = "-p /usr/lib64/ -p/lib64/ -p /usr/bin/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p /usr/share/ -s setfsuid -s setfsgid -s openat -s set_robust_list -s futex -s clone -s socket -s connect"
97 97 HASKELL_OPTION = "-s set_robust_list -s clock_gettime -s sysinfo -s timer_create -s timer_settime -s futex -s timer_delete"
98 98
99 99 case language
100 100 when "java"
101 101 # for java, extract the classname
102 102 # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
103 103 classname = 'DUMMY'
104 104 File.open(program_name,"r").each do |line|
105 105 classname = line
106 106 end
107 107 #for java, we cannot really check the memory limit...
108 108 run_command = "#{problem_home}/script/box -a 3 -f -T -t #{time_limit} #{JAVA_OPTION} -i #{input_file_name} -o output.txt /usr/bin/java -A -Xmx#{mem_limit}k -A #{classname} "
109 109 when "ruby"
110 110 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{RUBY_OPTION} -i #{input_file_name} -o output.txt /usr/bin/ruby #{program_name} "
111 111 when "python"
112 112 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128 * 1024,mem_limit].max} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python3 #{program_name} "
113 113 when "haskell"
114 114 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{[512 * 1024,mem_limit].max} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt #{program_name} "
115 115 when "php"
116 116 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128 * 1024,mem_limit].max} #{PHP_OPTION} -i #{input_file_name} -o output.txt /usr/bin/php -A -d -A memory_limit=#{mem_limit}k -A #{program_name} "
117 117 else # for c++, pascal, we do the normal checking
118 118 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} "
119 119 end
120 120
121 121
122 122 log "Running test #{test_num}..."
123 123 log run_command
124 124 log
125 125 system(run_command,err: 'run_result')
126 126
127 127 # Restore PROBLEM_HOME
128 128 ENV['PROBLEM_HOME'] = problem_home
129 129
130 130 # Create the result file.
131 131 result_file = File.new("result", "w")
132 132 comment_file = File.new("comment", "w")
133 133
134 134 # Check if the program actually produced any output.
135 135 run_result_file = File.new("run_result", "r")
136 136 run_result = run_result_file.readlines
137 137 run_result_file.close
138 138
139 139 run_stat = run_result[run_result.length-1]
140 140 running_time = extract_time(run_stat)
141 141
142 142 report = lambda{ |status, points, comment|
143 143 result_file.write status.strip
144 144 result_file.write "\n"
145 145 result_file.write points.to_s.strip
146 146 result_file.write "\n"
147 147 result_file.write run_stat.strip
148 148 result_file.write "\n"
149 149 result_file.close
150 150 FileUtils.rm "run_result"
151 151 # `rm output.txt` --- keep the output
152 152
153 153 comment_file.write comment
154 154
155 155 # added for debuggin --- jittat
156 156 comment_file.write "--run-result--\n"
157 157 run_result.each do |l|
158 158 comment_file.write l
159 159 end
160 160
161 161 comment_file.close
162 162
163 163 log "Done!"
164 164 exit(0)
165 165 }
166 166
167 167
168 168 if run_result[0][0,2] != "OK"
169 169 log "There was a runtime error."
170 170 report.call(run_result[0], 0, "No comment.\n")
171 171 end
172 172
173 173 if running_time[:user].to_f > time_limit
174 174 log "Time limit exceeded."
175 175 report.call("Time limit exceeded", 0, "No comment.\n")
176 176 end
177 177
178 178 # Run 'check' to evaluate the output.
179 179 #puts "There was no runtime error. Proceed to checking the output."
180 180 check_command = "#{problem_home}/script/check #{language} #{test_num}"
181 181 log "Checking the output..."
182 182 log check_command
183 183 if not system(check_command)
184 184 log "Problem with check script"
185 185 report.call("Incorrect",0,"Check script error.\n")
186 186 exit(127)
187 187 end
188 188
189 189 check_file = File.new("check_result", "r")
190 190 check_file_lines = check_file.readlines
191 191
192 192 report.call(check_file_lines[0], check_file_lines[1], "No comment.\n")
You need to be logged in to leave comments. Login now