Description:
add haskell
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r219:00b316d6843e - - 2 files changed: 9 inserted, 0 deleted

@@ -1,88 +1,90
1 #!/usr/bin/env ruby
1 #!/usr/bin/env ruby
2
2
3 require 'fileutils'
3 require 'fileutils'
4
4
5 ##############################
5 ##############################
6 #
6 #
7 # Standard Compile Script
7 # Standard Compile Script
8 #
8 #
9 # Supported compilers:
9 # Supported compilers:
10 # gcc, g++, and fpc.
10 # gcc, g++, and fpc.
11 #
11 #
12 ##############################
12 ##############################
13
13
14 def talk(str='')
14 def talk(str='')
15 if ENV['TALKATIVE']!=nil
15 if ENV['TALKATIVE']!=nil
16 puts str
16 puts str
17 end
17 end
18 if ENV['GRADER_LOGGING']!=nil
18 if ENV['GRADER_LOGGING']!=nil
19 log_fname = ENV['GRADER_LOGGING']
19 log_fname = ENV['GRADER_LOGGING']
20 fp = File.open(log_fname,"a")
20 fp = File.open(log_fname,"a")
21 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
21 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
22 fp.close
22 fp.close
23 end
23 end
24 end
24 end
25
25
26 C_COMPILER = "/usr/bin/gcc"
26 C_COMPILER = "/usr/bin/gcc"
27 CPLUSPLUS_COMPILER = "/usr/bin/g++"
27 CPLUSPLUS_COMPILER = "/usr/bin/g++"
28 PASCAL_COMPILER = "/usr/bin/fpc"
28 PASCAL_COMPILER = "/usr/bin/fpc"
29 JAVA_COMPILER = "/usr/bin/javac"
29 JAVA_COMPILER = "/usr/bin/javac"
30 RUBY_INTERPRETER = "/usr/bin/ruby"
30 RUBY_INTERPRETER = "/usr/bin/ruby"
31 PYTHON_INTERPRETER = "/usr/bin/python3"
31 PYTHON_INTERPRETER = "/usr/bin/python3"
32 PYTHON_CHECKER = "/usr/bin/pyflakes"
32 PYTHON_CHECKER = "/usr/bin/pyflakes"
33 PHP_INTERPRETER = "/usr/bin/php"
33 PHP_INTERPRETER = "/usr/bin/php"
34 + HASKELL_COMPILER = "/usr/bin/ghc"
34
35
35 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
36 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
36 CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall"
37 CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall"
37 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
38 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
38 JAVA_OPTIONS = ""
39 JAVA_OPTIONS = ""
39 PYTHON_OPTIONS = ""
40 PYTHON_OPTIONS = ""
40 PHP_OPTIONS = "-l"
41 PHP_OPTIONS = "-l"
42 + HASKELL_OPTIONS = ""
41
43
42 # Check for the correct number of arguments. Otherwise, print usage.
44 # Check for the correct number of arguments. Otherwise, print usage.
43 if ARGV.length == 0 or ARGV.length > 4
45 if ARGV.length == 0 or ARGV.length > 4
44 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
46 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
45 puts
47 puts
46 puts "<source-file> is defaulted to \"source\"."
48 puts "<source-file> is defaulted to \"source\"."
47 puts "<output-file> is defaulted to \"a.out\"."
49 puts "<output-file> is defaulted to \"a.out\"."
48 puts "<message-file> is defaulted to \"compiler_message\"."
50 puts "<message-file> is defaulted to \"compiler_message\"."
49 puts
51 puts
50 exit(127)
52 exit(127)
51 end
53 end
52
54
53 PARAMS = {
55 PARAMS = {
54 :source_file => [1,'source'],
56 :source_file => [1,'source'],
55 :output_file => [2,'a.out'],
57 :output_file => [2,'a.out'],
56 :message_file => [3,'compiler_message']
58 :message_file => [3,'compiler_message']
57 }
59 }
58
60
59 params = {}
61 params = {}
60 params[:prog_lang] = ARGV[0]
62 params[:prog_lang] = ARGV[0]
61 PARAMS.each_key do |param_name|
63 PARAMS.each_key do |param_name|
62 index, default = PARAMS[param_name]
64 index, default = PARAMS[param_name]
63 if ARGV.length > index
65 if ARGV.length > index
64 params[param_name] = ARGV[index]
66 params[param_name] = ARGV[index]
65 else
67 else
66 params[param_name] = default
68 params[param_name] = default
67 end
69 end
68 talk "#{param_name}: #{params[param_name]}"
70 talk "#{param_name}: #{params[param_name]}"
69 end
71 end
70
72
71 # Remove any remaining output files or message files.
73 # Remove any remaining output files or message files.
72 if FileTest.exists? params[:output_file]
74 if FileTest.exists? params[:output_file]
73 FileUtils.rm(params[:output_file])
75 FileUtils.rm(params[:output_file])
74 end
76 end
75 if FileTest.exists? params[:message_file]
77 if FileTest.exists? params[:message_file]
76 FileUtils.rm(params[:message_file])
78 FileUtils.rm(params[:message_file])
77 end
79 end
78
80
79 # Check if the source file exists before attempt compiling.
81 # Check if the source file exists before attempt compiling.
80 if !FileTest.exists? params[:source_file]
82 if !FileTest.exists? params[:source_file]
81 talk("ERROR: The source file does not exist!")
83 talk("ERROR: The source file does not exist!")
82 open(params[:message_file],"w") do |f|
84 open(params[:message_file],"w") do |f|
83 f.puts "ERROR: The source file did not exist."
85 f.puts "ERROR: The source file did not exist."
84 end
86 end
85 exit(127)
87 exit(127)
86 end
88 end
87
89
88 if params[:prog_lang]=='cpp'
90 if params[:prog_lang]=='cpp'
@@ -127,62 +129,66
127 system(command, err: params[:message_file])
129 system(command, err: params[:message_file])
128 if File.exists?(classname + ".class")
130 if File.exists?(classname + ".class")
129 File.open(params[:output_file],"w") {|file| file.write("#{classname}")}
131 File.open(params[:output_file],"w") {|file| file.write("#{classname}")}
130 end
132 end
131 if classname == 'DUMMY'
133 if classname == 'DUMMY'
132 File.open(params[:message_file],"w") {|file| file.write("Cannot find any public class in the source code\n")}
134 File.open(params[:message_file],"w") {|file| file.write("Cannot find any public class in the source code\n")}
133 end
135 end
134
136
135 when "ruby"
137 when "ruby"
136 command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}"
138 command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}"
137 if system(command, err: params[:message_file])
139 if system(command, err: params[:message_file])
138 File.open(params[:output_file],"w") do |out_file|
140 File.open(params[:output_file],"w") do |out_file|
139 out_file.puts "#!#{RUBY_INTERPRETER}"
141 out_file.puts "#!#{RUBY_INTERPRETER}"
140 File.open(params[:source_file],"r").each do |line|
142 File.open(params[:source_file],"r").each do |line|
141 out_file.print line
143 out_file.print line
142 end
144 end
143 end
145 end
144 File.chmod(0755, params[:output_file])
146 File.chmod(0755, params[:output_file])
145 end
147 end
146
148
147 when "python"
149 when "python"
148 command = "#{PYTHON_CHECKER} #{params[:source_file]}"
150 command = "#{PYTHON_CHECKER} #{params[:source_file]}"
149 if system(command, out: params[:message_file])
151 if system(command, out: params[:message_file])
150 #compile to python bytecode
152 #compile to python bytecode
151 command = "#{PYTHON_INTERPRETER} -c \"import py_compile; py_compile.compile('#{params[:source_file]}','#{params[:source_file]}c');\""
153 command = "#{PYTHON_INTERPRETER} -c \"import py_compile; py_compile.compile('#{params[:source_file]}','#{params[:source_file]}c');\""
152 puts "compile: #{command}"
154 puts "compile: #{command}"
153 system(command)
155 system(command)
154 puts "pwd: " + Dir.pwd
156 puts "pwd: " + Dir.pwd
155 Dir.new('.').each {|file| puts file}
157 Dir.new('.').each {|file| puts file}
156 File.open(params[:output_file],"w") do |out_file|
158 File.open(params[:output_file],"w") do |out_file|
157 out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
159 out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
158 end
160 end
159 File.chmod(0755, params[:output_file])
161 File.chmod(0755, params[:output_file])
160 FileUtils.cp("#{params[:source_file]}c",params[:output_file])
162 FileUtils.cp("#{params[:source_file]}c",params[:output_file])
161 end
163 end
162
164
163 when "php"
165 when "php"
164 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
166 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
165 if system(command, err: params[:message_file])
167 if system(command, err: params[:message_file])
166 File.open(params[:output_file],"w") do |out_file|
168 File.open(params[:output_file],"w") do |out_file|
167 out_file.puts "#!#{PHP_INTERPRETER}"
169 out_file.puts "#!#{PHP_INTERPRETER}"
168 File.open(params[:source_file],"r").each do |line|
170 File.open(params[:source_file],"r").each do |line|
169 out_file.print line
171 out_file.print line
170 end
172 end
171 end
173 end
172 File.chmod(0755, params[:output_file])
174 File.chmod(0755, params[:output_file])
173 end
175 end
174
176
177 + when "haskell"
178 + command = "#{HASKELL_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{HASKELL_OPTIONS}"
179 + system(command, err: params[:message_file])
180 +
175 else
181 else
176 talk("ERROR: Invalid language specified!")
182 talk("ERROR: Invalid language specified!")
177 open(params[:message_file],"w") do |f|
183 open(params[:message_file],"w") do |f|
178 f.puts "ERROR: Invalid language specified!"
184 f.puts "ERROR: Invalid language specified!"
179 end
185 end
180 exit(127)
186 exit(127)
181 end
187 end
182
188
183 # Report success or failure.
189 # Report success or failure.
184 if FileTest.exists? params[:output_file]
190 if FileTest.exists? params[:output_file]
185 talk "Compilation was successful!"
191 talk "Compilation was successful!"
186 else
192 else
187 talk "ERROR: Something was wrong during the compilation!"
193 talk "ERROR: Something was wrong during the compilation!"
188 end
194 end
@@ -49,111 +49,114
49 problem = Problem.get_instance
49 problem = Problem.get_instance
50
50
51 sandbox_dir = Dir.getwd
51 sandbox_dir = Dir.getwd
52
52
53 if problem.well_formed? == false
53 if problem.well_formed? == false
54 log "The problem specification is not well formed."
54 log "The problem specification is not well formed."
55 exit(127)
55 exit(127)
56 end
56 end
57
57
58 # Check if the test number is okay.
58 # Check if the test number is okay.
59 if test_num <= 0 || test_num > problem.num_tests
59 if test_num <= 0 || test_num > problem.num_tests
60 log "You have specified a wrong test number."
60 log "You have specified a wrong test number."
61 exit(127)
61 exit(127)
62 end
62 end
63
63
64 #####################################
64 #####################################
65 # Set the relavant file names here. #
65 # Set the relavant file names here. #
66 #####################################
66 #####################################
67
67
68 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
68 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
69
69
70 #####################################
70 #####################################
71
71
72 time_limit = problem.get_time_limit test_num
72 time_limit = problem.get_time_limit test_num
73 mem_limit = problem.get_mem_limit(test_num) * 1024
73 mem_limit = problem.get_mem_limit(test_num) * 1024
74
74
75 # Copy the input file.
75 # Copy the input file.
76 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
76 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
77
77
78 # check if box is there, if not, compile it!
78 # check if box is there, if not, compile it!
79 if !File.exists?("#{problem_home}/script/box")
79 if !File.exists?("#{problem_home}/script/box")
80 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
80 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
81 compile_box("#{problem_home}/script/box.cc",
81 compile_box("#{problem_home}/script/box.cc",
82 "#{problem_home}/script/box")
82 "#{problem_home}/script/box")
83 end
83 end
84
84
85 # Hide PROBLEM_HOME
85 # Hide PROBLEM_HOME
86 ENV['PROBLEM_HOME'] = nil
86 ENV['PROBLEM_HOME'] = nil
87 ENV['SOURCE_NAME'] = nil
87 ENV['SOURCE_NAME'] = nil
88
88
89 # Run the program.
89 # Run the program.
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}"
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 JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
93 JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
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"
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/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 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"
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 + HASKELL_OPTION = "-s set_robust_list -s clock_gettime -s sysinfo -s timer_create -s timer_settime -s futex -s timer_delete"
97
98
98 case language
99 case language
99 when "java"
100 when "java"
100 # for java, extract the classname
101 # for java, extract the classname
101 # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
102 # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
102 classname = 'DUMMY'
103 classname = 'DUMMY'
103 File.open(program_name,"r").each do |line|
104 File.open(program_name,"r").each do |line|
104 classname = line
105 classname = line
105 end
106 end
106 #for java, we cannot really check the memory limit...
107 #for java, we cannot really check the memory limit...
107 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} "
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} "
108 when "ruby"
109 when "ruby"
109 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} "
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} "
110 when "python"
111 when "python"
111 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} "
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 + when "haskell"
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} "
112 when "php"
115 when "php"
113 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} "
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} "
114 else # for c++, pascal, we do the normal checking
117 else # for c++, pascal, we do the normal checking
115 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} "
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} "
116 end
119 end
117
120
118
121
119 log "Running test #{test_num}..."
122 log "Running test #{test_num}..."
120 log run_command
123 log run_command
121 log
124 log
122 system(run_command,err: 'run_result')
125 system(run_command,err: 'run_result')
123
126
124 # Restore PROBLEM_HOME
127 # Restore PROBLEM_HOME
125 ENV['PROBLEM_HOME'] = problem_home
128 ENV['PROBLEM_HOME'] = problem_home
126
129
127 # Create the result file.
130 # Create the result file.
128 result_file = File.new("result", "w")
131 result_file = File.new("result", "w")
129 comment_file = File.new("comment", "w")
132 comment_file = File.new("comment", "w")
130
133
131 # Check if the program actually produced any output.
134 # Check if the program actually produced any output.
132 run_result_file = File.new("run_result", "r")
135 run_result_file = File.new("run_result", "r")
133 run_result = run_result_file.readlines
136 run_result = run_result_file.readlines
134 run_result_file.close
137 run_result_file.close
135
138
136 run_stat = run_result[run_result.length-1]
139 run_stat = run_result[run_result.length-1]
137 running_time = extract_time(run_stat)
140 running_time = extract_time(run_stat)
138
141
139 report = lambda{ |status, points, comment|
142 report = lambda{ |status, points, comment|
140 result_file.write status.strip
143 result_file.write status.strip
141 result_file.write "\n"
144 result_file.write "\n"
142 result_file.write points.to_s.strip
145 result_file.write points.to_s.strip
143 result_file.write "\n"
146 result_file.write "\n"
144 result_file.write run_stat.strip
147 result_file.write run_stat.strip
145 result_file.write "\n"
148 result_file.write "\n"
146 result_file.close
149 result_file.close
147 FileUtils.rm "run_result"
150 FileUtils.rm "run_result"
148 # `rm output.txt` --- keep the output
151 # `rm output.txt` --- keep the output
149
152
150 comment_file.write comment
153 comment_file.write comment
151
154
152 # added for debuggin --- jittat
155 # added for debuggin --- jittat
153 comment_file.write "--run-result--\n"
156 comment_file.write "--run-result--\n"
154 run_result.each do |l|
157 run_result.each do |l|
155 comment_file.write l
158 comment_file.write l
156 end
159 end
157
160
158 comment_file.close
161 comment_file.close
159
162
You need to be logged in to leave comments. Login now