Description:
Merge pull request #14 from nattee/master upgrade to current working snapshot
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r263:7950cf0bb006 - - 12 files changed: 448 inserted, 40 deleted

@@ -0,0 +1,93
1 + #!/usr/bin/env ruby
2 +
3 + def config
4 + Grader::Configuration.get_instance
5 + end
6 +
7 + def display_manual
8 + puts <<USAGE
9 + Check similarity between submission
10 + using: check_similar sub1 sub2
11 + -- or --
12 + check_similar problem_name
13 + sub1 and sub2 are submission IDs to be checked
14 + problem_name will check all submissions of the problem wit problem short name is 'problem_name'
15 +
16 + The output are given as
17 + sub1.login, sub1.id, sub1.point, sub2.login, sub2.id, sub2.point, similarity
18 +
19 + USAGE
20 + end
21 +
22 + def process_options_and_stop_file
23 +
24 + # Process 'help' option
25 + if (ARGV.length == 0) or ((ARGV.length==1) and (/help/.match(ARGV[0])))
26 + display_manual
27 + exit(0)
28 + end
29 +
30 + #default options
31 + options = {
32 + :dry_run => false,
33 + }
34 +
35 +
36 + if ARGV.length == 2
37 + options[:sub1] = ARGV[0].to_i
38 + options[:sub2] = ARGV[1].to_i
39 + elsif ARGV.length == 1
40 + options[:problem] = ARGV[0]
41 + end
42 +
43 +
44 + return options
45 + end
46 +
47 + def compare(sub1,sub2,full = sub1.problem.full_score)
48 + dis = @jarow.getDistance(sub1.source, sub2.source)
49 + puts [sub1.user.login,"##{sub1.id}",(sub1.points * 100.0 / full).to_i,
50 + sub2.user.login,"##{sub2.id}",(sub2.points * 100.0 / full).to_i,
51 + "#{dis * 100}%"].join(',')
52 + end
53 +
54 + #########################################
55 + # main program
56 + #########################################
57 +
58 + options = process_options_and_stop_file
59 +
60 + # load grader environment
61 + GRADER_ENV = 'grading'
62 + require File.join(File.dirname(__FILE__),'config/environment')
63 +
64 + # boot rails, to be able to use the active record
65 + RAILS_ENV = config.rails_env
66 + require RAILS_ROOT + '/config/environment'
67 +
68 + # load comparator
69 + require 'fuzzystringmatch'
70 + @jarow = FuzzyStringMatch::JaroWinkler.create( :native )
71 +
72 + if options[:problem]
73 + p = Problem.where(name: options[:problem]).first
74 + unless p
75 + puts "cannot find problem #{options[:problem]}"
76 + exit(0)
77 + end
78 + subs = Submission.where(problem: p)
79 + full_score = p.full_score.to_i
80 + subs.each.with_index do |s1,i|
81 + puts "processing #{i+1} out of #{subs.length}"
82 + subs.each do |s2|
83 + if s1.user != s2.user
84 + compare(s1,s2,full_score)
85 + end
86 + end
87 + end
88 + else
89 + sub1 = Submission.find(options[:sub1])
90 + sub2 = Submission.find(options[:sub2])
91 + compare(sub1,sub2)
92 + end
93 +
@@ -0,0 +1,6
1 + #!/bin/bash
2 + count=`ps aux | grep "cafe_grader" | grep "grader grading queue" | wc -l`
3 + if [ $count -lt 1 ]; then
4 + cd /home/dae/cafe_grader/judge
5 + /home/dae/.rvm/wrappers/ruby-2.3.0/ruby /home/dae/cafe_grader/judge/scripts/grader grading queue > /home/dae/grading.log &
6 + fi
@@ -0,0 +1,179
1 + #!/bin/sh
2 +
3 + echo "This script will install and configure Cafe grader."
4 +
5 + RUBY_VERSION=2.1.2
6 + echo "This will install Ruby $RUBY_VERSION under RVM"
7 +
8 + echo "Installing required apts"
9 +
10 + sudo zypper install \
11 + g++ gcc libmysqlclient18 build-essential \
12 + git-core openssl libreadline6 libreadline6-devel \
13 + zlib1g zlib1g-devel libssl37 libyaml-devel sqlite3-devel \
14 + sqlite3 libxml2-devel libxslt-devel autoconf libc6-devel \
15 + ncurses-devel automake libtool bison subversion \
16 + pkg-config curl nodejs unzip pyflakes java-1_8_0-openjdk \
17 + libmysqld-devel mercurial python-setuptools python-devel
18 +
19 +
20 + echo "Installing Ruby $RUBY_VERSION in RVM"
21 +
22 + rvm install $RUBY_VERSION
23 + rvm use $RUBY_VERSION
24 +
25 + echo "Fetching Cafe Grader from Git repositories"
26 +
27 + echo "Fetching web interface"
28 +
29 + mkdir cafe_grader
30 + cd cafe_grader
31 + #git clone -q git://github.com/jittat/cafe-grader-web.git web
32 + hg clone git+ssh://git@github.com/nattee/cafe-grader-web.git web
33 +
34 + echo "Configuring rails app"
35 +
36 + cp web/config/application.rb.SAMPLE web/config/application.rb
37 + cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
38 +
39 + #replace UTC in application.rb with the system timezone
40 + timezone='UTC'
41 + if [ -f '/etc/timezone' ]; then
42 + timezone=\"`cat /etc/timezone`\"
43 + else
44 + if [ -f '/etc/sysconfig/clock' ]; then
45 + timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
46 + fi
47 + fi
48 + replace="s!'UTC'!$timezone!g"
49 + sed -i $replace web/config/application.rb
50 +
51 + echo "At this point we will need MySQL user and database."
52 + echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
53 + read ch
54 +
55 + if [ "$ch" = "n" -o "$ch" = "N" ]
56 + then
57 + echo "Please open another terminal and create the user and database for Cafe grader."
58 + echo "Don't forget to grant access to that database for the user."
59 + echo "Please have username, password, and database name ready before continue."
60 + echo
61 + echo "The following are instructions:"
62 + echo "1. Run mysql:"
63 + echo
64 + echo " mysql -u root -p"
65 + echo
66 + echo " if you have just installed mysql, the root password is the one that you have just entered"
67 + echo "2. Create a new database, a new user, and grant access to grader database:"
68 + echo
69 + echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
70 + echo " create database \`DATABASENEME\`;"
71 + echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
72 + echo
73 + echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
74 + echo
75 + echo "Hit enter when ready..."
76 + read dummy
77 + fi
78 +
79 + CAFE_PATH=`pwd`
80 +
81 + cd web
82 +
83 + echo "Please provide grader database:"
84 + read database
85 +
86 + echo "Please provide grader username:"
87 + read username
88 +
89 + echo "Please provide $username password:"
90 + read password
91 +
92 + echo "development:" > config/database.yml
93 + echo " adapter: mysql2" >> config/database.yml
94 + echo " encoding: utf8" >> config/database.yml
95 + echo " reconnect: false" >> config/database.yml
96 + echo " database: $database" >> config/database.yml
97 + echo " pool: 5" >> config/database.yml
98 + echo " username: $username" >> config/database.yml
99 + echo " password: $password" >> config/database.yml
100 + echo " host: localhost" >> config/database.yml
101 + echo " socket: /run/mysql/mysql.sock" >> config/database.yml
102 + echo "" >> config/database.yml
103 + echo "production:" >> config/database.yml
104 + echo " adapter: mysql2" >> config/database.yml
105 + echo " encoding: utf8" >> config/database.yml
106 + echo " reconnect: false" >> config/database.yml
107 + echo " database: $database" >> config/database.yml
108 + echo " pool: 5" >> config/database.yml
109 + echo " username: $username" >> config/database.yml
110 + echo " password: $password" >> config/database.yml
111 + echo " host: localhost" >> config/database.yml
112 + echo " socket: /run/mysql/mysql.sock" >> config/database.yml
113 +
114 + echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
115 + echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
116 + echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
117 + echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
118 +
119 + echo "Installing required gems"
120 + gem install bundler
121 + bundle install
122 +
123 + echo "Running rake tasks to initialize database"
124 +
125 + rake db:migrate
126 + rake db:seed
127 +
128 + echo "Running rake tasks to precompile the assets"
129 +
130 + rake assets:precompile
131 +
132 + echo "Intalling web interface complete..."
133 + echo
134 + echo "Fetching grader"
135 +
136 + cd ..
137 +
138 + mkdir judge
139 + cd judge
140 + #git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
141 + hg clone git+ssh://git@github.com/nattee/cafe-grader-judge-scripts.git scripts
142 + mkdir raw
143 + mkdir ev-exam
144 + mkdir ev
145 + mkdir result
146 + mkdir log
147 +
148 + echo "Configuring grader"
149 +
150 + cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
151 + cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
152 +
153 + # create new environment.rb file
154 + echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
155 + echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
156 + echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
157 + echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
158 +
159 + # compiling box
160 + MACHINE_TYPE=`uname -m`
161 + if [ ${MACHINE_TYPE} == 'x86_64' ]; then
162 + gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
163 + else
164 + g++ -o scripts/std-script/box scripts/std-script/box.cc
165 + fi
166 +
167 +
168 + cd ..
169 +
170 + echo "Now you are ready to run cafe grader...."
171 + echo
172 + echo "Try:"
173 + echo
174 + echo " cd web"
175 + echo " rails s"
176 + echo
177 + echo "and access web at http://localhost:3000/"
178 + echo "The root username is 'root', its password is 'ioionrails'."
179 +
@@ -0,0 +1,85
1 + #!/usr/bin/env ruby
2 +
3 + def config
4 + Grader::Configuration.get_instance
5 + end
6 +
7 + def display_manual
8 + puts <<USAGE
9 + load_testcases
10 + using: load_testcases [problem_name ...]
11 + problem_name are list of "short name" of the problems
12 +
13 + options:
14 + --dry-run do nothing, just simulate the run
15 + --all import all problem. This might take several minutes
16 +
17 + USAGE
18 + end
19 +
20 + def process_options_and_stop_file
21 +
22 + # Process 'help' option
23 + if (ARGV.length == 0) or ((ARGV.length==1) and (/help/.match(ARGV[0])))
24 + display_manual
25 + exit(0)
26 + end
27 +
28 + #default options
29 + options = {
30 + :dry_run => false,
31 + }
32 +
33 + options[:dry_run] = (ARGV.delete('--dry') != nil)
34 + options[:all] = (ARGV.delete('--all') != nil)
35 +
36 + return options
37 + end
38 +
39 + def process_problem(prob,dry_run = false)
40 + prob.testcases.destroy_all
41 + testcases_root = File.expand_path(GRADER_ROOT+"/../ev/#{prob.name}/test_cases/")
42 + num = 1
43 + puts "Processing problem #{prob.name}"
44 + loop do
45 + file_root = testcases_root + "/#{num}/"
46 + puts " checking file #{file_root}"
47 + break unless File.exists? file_root
48 + input = File.read(file_root + "/input-#{num}.txt")
49 + answer = File.read(file_root + "/answer-#{num}.txt")
50 + puts " got test case ##{num} of size #{input.size} and #{answer.size}"
51 +
52 + #THIS IS JUST A PLACE HOLDER
53 + group = num #this is wrong!!! fix it!!
54 + score = 10
55 + #BEWARE
56 +
57 + prob.testcases.create(input: input,sol: answer, num: num, score:score,group: group) unless dry_run
58 + num += 1
59 + end
60 + end
61 +
62 + #########################################
63 + # main program
64 + #########################################
65 +
66 + options = process_options_and_stop_file
67 +
68 + # load grader environment
69 + GRADER_ENV = 'grading'
70 + require File.join(File.dirname(__FILE__),'config/environment')
71 +
72 + # boot rails, to be able to use the active record
73 + RAILS_ENV = config.rails_env
74 + require RAILS_ROOT + '/config/environment'
75 +
76 + if options[:all]
77 + Problem.all.each { |prob| process_problem(prob,options[:dry_run]) }
78 + else
79 + ARGV.each do |name|
80 + prob = Problem.find_by(name: name)
81 + process_problem(prob,options[:dry_run]) if prob
82 + puts "Cannot find the problem #{name}" unless prob
83 + end
84 + end
85 +
@@ -132,29 +132,35
132 testrun_info.each do |testrun|
132 testrun_info.each do |testrun|
133 tr_num += 1
133 tr_num += 1
134 puts "testrun: #{tr_num}"
134 puts "testrun: #{tr_num}"
135 -
135 +
136 testrun.each do |testcase_info|
136 testrun.each do |testcase_info|
137 testcase_num, testcase_fname = testcase_info
137 testcase_num, testcase_fname = testcase_info
138 -
138 +
139 puts "copy #{testcase_fname} to #{testcase_num}"
139 puts "copy #{testcase_fname} to #{testcase_num}"
140 -
140 +
141 create_dir_if_not_exists("#{problem_dir}/test_cases/#{testcase_num}")
141 create_dir_if_not_exists("#{problem_dir}/test_cases/#{testcase_num}")
142 copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num)
142 copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num)
143 -
143 +
144 num_testcases += 1
144 num_testcases += 1
145 end
145 end
146 end
146 end
147 -
147 +
148 + #also include any .txt files
149 + Dir.glob("#{testcase_dir}/*.txt") do |file|
150 + puts "copy data file #{file}"
151 + FileUtils.cp(file,"#{problem_dir}")
152 + end
153 +
148 # generating all_tests.cfg
154 # generating all_tests.cfg
149 puts "generating testcase config file"
155 puts "generating testcase config file"
150 -
156 +
151 template = File.open(SCRIPT_DIR + "/templates/all_tests.cfg.erb").read
157 template = File.open(SCRIPT_DIR + "/templates/all_tests.cfg.erb").read
152 all_test_cfg = ERB.new(template)
158 all_test_cfg = ERB.new(template)
153 -
159 +
154 cfg_file = File.open("#{problem_dir}/test_cases/all_tests.cfg","w")
160 cfg_file = File.open("#{problem_dir}/test_cases/all_tests.cfg","w")
155 cfg_file.puts all_test_cfg.result binding
161 cfg_file.puts all_test_cfg.result binding
156 cfg_file.close
162 cfg_file.close
157 -
163 +
158 # copy check script
164 # copy check script
159 if res = /^wrapper:(.*)$/.match(check_script)
165 if res = /^wrapper:(.*)$/.match(check_script)
160 # wrapper script
166 # wrapper script
@@ -162,13 +168,13
162 script_name = File.basename(check_script_fname)
168 script_name = File.basename(check_script_fname)
163 check_wrapper_template = File.open(SCRIPT_DIR + "/templates/check_wrapper").read
169 check_wrapper_template = File.open(SCRIPT_DIR + "/templates/check_wrapper").read
164 check_wrapper = ERB.new(check_wrapper_template)
170 check_wrapper = ERB.new(check_wrapper_template)
165 -
171 +
166 check_file = File.open("#{problem_dir}/script/check","w")
172 check_file = File.open("#{problem_dir}/script/check","w")
167 check_file.puts check_wrapper.result binding
173 check_file.puts check_wrapper.result binding
168 check_file.close
174 check_file.close
169 -
175 +
170 File.chmod(0755,"#{problem_dir}/script/check")
176 File.chmod(0755,"#{problem_dir}/script/check")
171 -
177 +
172 FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/#{script_name}")
178 FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/#{script_name}")
173 else
179 else
174 if File.exists?(SCRIPT_DIR + "/templates/check.#{check_script}")
180 if File.exists?(SCRIPT_DIR + "/templates/check.#{check_script}")
@@ -178,24 +184,24
178 end
184 end
179 FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/check", :preserve => true)
185 FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/check", :preserve => true)
180 end
186 end
181 -
187 +
182 # generating test_request directory
188 # generating test_request directory
183 puts "generating test_request template"
189 puts "generating test_request template"
184 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/script")
190 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/script")
185 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/test_cases/1")
191 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/test_cases/1")
186 -
192 +
187 template = File.open(SCRIPT_DIR + "/templates/test_request_all_tests.cfg.erb").read
193 template = File.open(SCRIPT_DIR + "/templates/test_request_all_tests.cfg.erb").read
188 test_request_all_test_cfg = ERB.new(template)
194 test_request_all_test_cfg = ERB.new(template)
189 -
195 +
190 cfg_file = File.open("#{ev_dir}/test_request/#{problem}/test_cases/all_tests.cfg","w")
196 cfg_file = File.open("#{ev_dir}/test_request/#{problem}/test_cases/all_tests.cfg","w")
191 cfg_file.puts test_request_all_test_cfg.result
197 cfg_file.puts test_request_all_test_cfg.result
192 cfg_file.close
198 cfg_file.close
193 -
199 +
194 FileUtils.cp("#{SCRIPT_DIR}/templates/check_empty",
200 FileUtils.cp("#{SCRIPT_DIR}/templates/check_empty",
195 "#{ev_dir}/test_request/#{problem}/script/check")
201 "#{ev_dir}/test_request/#{problem}/script/check")
196 FileUtils.cp("#{SCRIPT_DIR}/templates/answer-1.txt",
202 FileUtils.cp("#{SCRIPT_DIR}/templates/answer-1.txt",
197 "#{ev_dir}/test_request/#{problem}/test_cases/1")
203 "#{ev_dir}/test_request/#{problem}/test_cases/1")
198 -
204 +
199 puts "done"
205 puts "done"
200 end
206 end
201
207
@@ -9,12 +9,13
9
9
10 sudo apt-get update
10 sudo apt-get update
11 sudo apt-get install mysql-server mysql-client \
11 sudo apt-get install mysql-server mysql-client \
12 - g++ gcc apache2 libmysqlclient15-dev build-essential \
12 + g++ gcc apache2 libmysqlclient20 build-essential \
13 git-core openssl libreadline6 libreadline6-dev \
13 git-core openssl libreadline6 libreadline6-dev \
14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
16 ncurses-dev automake libtool bison subversion \
16 ncurses-dev automake libtool bison subversion \
17 - pkg-config curl nodejs unzip pyflakes ruby default-jdk
17 + pkg-config curl nodejs unzip pyflakes ruby default-jdk \
18 + libmysqld-dev mercurial python-setuptools python-dev python3-numpy
18
19
19 echo "Installing RVM"
20 echo "Installing RVM"
20 curl -k -L https://get.rvm.io | bash -s stable
21 curl -k -L https://get.rvm.io | bash -s stable
@@ -8,7 +8,7
8
8
9 def rename_problem(old_problem_name, new_problem_name)
9 def rename_problem(old_problem_name, new_problem_name)
10
10
11 - if valid_problem_name(new_problem_name)
11 + unless valid_problem_name(new_problem_name)
12 puts "Bad new problem name: #{new_problem_name}"
12 puts "Bad new problem name: #{new_problem_name}"
13 return
13 return
14 end
14 end
@@ -60,7 +60,7
60 if name.length==0:
60 if name.length==0:
61 return false
61 return false
62 else
62 else
63 - return !(/^[a-zA-Z0-9_\-]+$/ === name)
63 + return (/^[a-zA-Z0-9_\-]+$/ === name)
64 end
64 end
65 end
65 end
66
66
@@ -603,6 +603,18
603 /* 311 */ [ __NR_process_vm_writev ] = "process_vm_writev",
603 /* 311 */ [ __NR_process_vm_writev ] = "process_vm_writev",
604 /* 312 */ [ __NR_kcmp ] = "kcmp",
604 /* 312 */ [ __NR_kcmp ] = "kcmp",
605 /* 313 */ [ __NR_finit_module ] = "finit_module",
605 /* 313 */ [ __NR_finit_module ] = "finit_module",
606 + /* 314 */ [ __NR_sched_setattr ] = "sched_setattr",
607 + /* 315 */ [ __NR_sched_getattr ] = "sched_getattr",
608 + /* 316 */ [ __NR_renameat2 ] = "renameat2",
609 + /* 317 */ [ __NR_seccomp ] = "seccomp",
610 + /* 318 */ [ __NR_getrandom ] = "getrandom",
611 + /* 319 */ [ __NR_memfd_create ] = "memfd_create",
612 + /* 320 */ [ __NR_kexec_file_load ] = "kexec_file_load",
613 + /* 321 */ [ __NR_bpf ] = "bpf",
614 + /* 322 */ [ __NR_execveat ] = "execveat",
615 + /* 323 */ [ __NR_userfaultfd ] = "userfaultfd",
616 + /* 324 */ [ __NR_membarrier ] = "membarrier",
617 + /* 325 */ [ __NR_mlock2 ] = "mlock2",
606 };
618 };
607 #define NUM_SYSCALLS ARRAY_SIZE(syscall_names)
619 #define NUM_SYSCALLS ARRAY_SIZE(syscall_names)
608 #define NUM_ACTIONS (NUM_SYSCALLS+64)
620 #define NUM_ACTIONS (NUM_SYSCALLS+64)
@@ -28,9 +28,10
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/python"
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"
@@ -38,6 +39,7
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
@@ -145,20 +147,22
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} -m py_compile #{params[:source_file]}"
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, err: params[:message_file])
154 - puts "pwd: " + Dir.pwd
156 + if FileTest.exists?("#{params[:source_file]}c")
155 - Dir.new('.').each {|file| puts file}
157 + puts "pwd: " + Dir.pwd
156 - File.open(params[:output_file],"w") do |out_file|
158 + Dir.new('.').each {|file| puts file}
157 - out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
159 + File.open(params[:output_file],"w") do |out_file|
160 + out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
161 + end
162 + File.chmod(0755, params[:output_file])
163 + FileUtils.cp("#{params[:source_file]}c",params[:output_file])
158 end
164 end
159 - File.chmod(0755, params[:output_file])
165 + #end
160 - FileUtils.cp("#{params[:source_file]}c",params[:output_file])
161 - end
162
166
163 when "php"
167 when "php"
164 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
168 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
@@ -172,6 +176,10
172 File.chmod(0755, params[:output_file])
176 File.chmod(0755, params[:output_file])
173 end
177 end
174
178
179 + when "haskell"
180 + command = "#{HASKELL_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{HASKELL_OPTIONS}"
181 + system(command, err: params[:message_file])
182 +
175 else
183 else
176 talk("ERROR: Invalid language specified!")
184 talk("ERROR: Invalid language specified!")
177 open(params[:message_file],"w") do |f|
185 open(params[:message_file],"w") do |f|
@@ -53,7 +53,7
53 end
53 end
54
54
55 language = ARGV[0]
55 language = ARGV[0]
56 - if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby" && language != "python" && language != "php"
56 + if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby" && language != "python" && language != "php" && language != "haskell"
57 log "You specified a language that is not supported: #{language}."
57 log "You specified a language that is not supported: #{language}."
58 exit(127)
58 exit(127)
59 end
59 end
@@ -140,6 +140,12
140 if language == "python" then Dir["#{test_result_dir}/*.pyc"].each { |file| FileUtils.cp(file,sandbox_dir)} end
140 if language == "python" then Dir["#{test_result_dir}/*.pyc"].each { |file| FileUtils.cp(file,sandbox_dir)} end
141 }
141 }
142
142
143 + #additionally copy any extra .txt file
144 + data_files = Dir[problem_home + '/*.txt']
145 + data_files.each do |file|
146 + FileUtils.cp(file,sandbox_dir)
147 + end
148 +
143 begin
149 begin
144 execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script")
150 execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script")
145 rescue
151 rescue
@@ -92,8 +92,9
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 #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -s set_robust_list -s openat -s recvmsg -s connect -s socket -s sendto -s futex -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 -s getrandom -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"
@@ -108,9 +109,11
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 #{mem_limit} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python #{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} #{HASKELL_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
@@ -47,6 +47,11
47
47
48 ########### THIS IS FOR CHECKING FLOAT with EPSILON error ##########
48 ########### THIS IS FOR CHECKING FLOAT with EPSILON error ##########
49
49
50 +
51 + def is_float?(fl)
52 + !!Float(fl) rescue false
53 + end
54 +
50 EPSILON = 0.000001
55 EPSILON = 0.000001
51
56
52 out_items = output_file_content.split
57 out_items = output_file_content.split
@@ -56,10 +61,14
56 report_wrong.call
61 report_wrong.call
57 else
62 else
58 out_items.length.times do |i|
63 out_items.length.times do |i|
59 - out_value = out_items[i].to_f
64 + if is_float?(out_items[i]) && is_float?(ans_items[i])
60 - ans_value = ans_items[i].to_f
65 + out_value = out_items[i].to_f
61 - if (out_value - ans_value).abs > EPSILON * [out_value.abs,ans_value.abs].max
66 + ans_value = ans_items[i].to_f
62 - report_wrong.call
67 + if (out_value - ans_value).abs > EPSILON * [out_value.abs,ans_value.abs].max
68 + report_wrong.call
69 + end
70 + else
71 + report_wrong.call if out_items[i] != ans_items[i]
63 end
72 end
64 end
73 end
65 report_correct.call
74 report_correct.call
You need to be logged in to leave comments. Login now