Show More
Commit Description:
update sample of grader-process-check
Commit Description:
update sample of grader-process-check
References:
File last commit:
Show/Diff file:
Action:
std-script/compile
| 196 lines
| 5.7 KiB
| text/plain
| TextLexer
|
|
r137 | #!/usr/bin/env ruby | ||
|
r107 | |||
require 'fileutils' | ||||
|
r0 | |||
############################## | ||||
# | ||||
# Standard Compile Script | ||||
# | ||||
# Supported compilers: | ||||
|
r53 | # gcc, g++, and fpc. | ||
|
r0 | # | ||
############################## | ||||
r148 | def talk(str='') | |||
|
r107 | if ENV['TALKATIVE']!=nil | ||
puts str | ||||
end | ||||
if ENV['GRADER_LOGGING']!=nil | ||||
log_fname = ENV['GRADER_LOGGING'] | ||||
fp = File.open(log_fname,"a") | ||||
r148 | fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}") | |||
|
r107 | fp.close | ||
end | ||||
end | ||||
|
r22 | |||
|
r107 | C_COMPILER = "/usr/bin/gcc" | ||
CPLUSPLUS_COMPILER = "/usr/bin/g++" | ||||
PASCAL_COMPILER = "/usr/bin/fpc" | ||||
r147 | JAVA_COMPILER = "/usr/bin/javac" | |||
r155 | RUBY_INTERPRETER = "/usr/bin/ruby" | |||
r215 | PYTHON_INTERPRETER = "/usr/bin/python3" | |||
r154 | PYTHON_CHECKER = "/usr/bin/pyflakes" | |||
r165 | PHP_INTERPRETER = "/usr/bin/php" | |||
r219 | HASKELL_COMPILER = "/usr/bin/ghc" | |||
|
r0 | |||
|
r107 | C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall" | ||
r162 | CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall" | |||
|
r107 | PASCAL_OPTIONS = "-O1 -XS -dCONTEST" | ||
r147 | JAVA_OPTIONS = "" | |||
r154 | PYTHON_OPTIONS = "" | |||
r165 | PHP_OPTIONS = "-l" | |||
r219 | HASKELL_OPTIONS = "" | |||
|
r0 | |||
# Check for the correct number of arguments. Otherwise, print usage. | ||||
|
r107 | if ARGV.length == 0 or ARGV.length > 4 | ||
puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]" | ||||
puts | ||||
puts "<source-file> is defaulted to \"source\"." | ||||
puts "<output-file> is defaulted to \"a.out\"." | ||||
puts "<message-file> is defaulted to \"compiler_message\"." | ||||
puts | ||||
exit(127) | ||||
end | ||||
|
r0 | |||
|
r107 | PARAMS = { | ||
:source_file => [1,'source'], | ||||
:output_file => [2,'a.out'], | ||||
:message_file => [3,'compiler_message'] | ||||
} | ||||
|
r0 | |||
|
r107 | params = {} | ||
params[:prog_lang] = ARGV[0] | ||||
PARAMS.each_key do |param_name| | ||||
index, default = PARAMS[param_name] | ||||
if ARGV.length > index | ||||
params[param_name] = ARGV[index] | ||||
else | ||||
params[param_name] = default | ||||
end | ||||
talk "#{param_name}: #{params[param_name]}" | ||||
end | ||||
|
r0 | |||
# Remove any remaining output files or message files. | ||||
|
r107 | if FileTest.exists? params[:output_file] | ||
FileUtils.rm(params[:output_file]) | ||||
end | ||||
if FileTest.exists? params[:message_file] | ||||
FileUtils.rm(params[:message_file]) | ||||
end | ||||
|
r0 | |||
# Check if the source file exists before attempt compiling. | ||||
|
r107 | if !FileTest.exists? params[:source_file] | ||
talk("ERROR: The source file does not exist!") | ||||
open(params[:message_file],"w") do |f| | ||||
f.puts "ERROR: The source file did not exist." | ||||
end | ||||
exit(127) | ||||
end | ||||
|
r0 | |||
|
r137 | if params[:prog_lang]=='cpp' | ||
params[:prog_lang] = 'c++' | ||||
|
r119 | end | ||
|
r0 | # Compile. | ||
|
r107 | case params[:prog_lang] | ||
r154 | when "c" | |||
r178 | command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS}" | |||
system(command, err: params[:message_file]) | ||||
|
r107 | |||
r154 | when "c++" | |||
r178 | command = "#{CPLUSPLUS_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS}" | |||
system(command, err: params[:message_file]) | ||||
|
r107 | |||
r154 | when "pas" | |||
r178 | command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS}" | |||
system(command,out: params[:message_file]) | ||||
|
r107 | FileUtils.mv("output", params[:output_file]) | ||
r147 | ||||
r154 | when "java" | |||
r147 | #rename the file to the public class name | |||
#get the class name | ||||
classname = 'DUMMY' | ||||
r167 | source = Array.new | |||
r180 | File.foreach(params[:source_file],'r:UTF-8') do |line| | |||
line.encode!('UTF-8','UTF-8',invalid: :replace, replace: '') | ||||
r147 | md = /\s*public\s*class\s*(\w*)/.match(line) | |||
classname=md[1] if md | ||||
r167 | source << line unless line =~ /\s*package\s*\w+\s*\;/ | |||
r147 | end | |||
r167 | File.open("#{classname}.java","w") do |file| | |||
source.each do |s| | ||||
file.puts s | ||||
end | ||||
end | ||||
#system("cp #{params[:source_file]} #{classname}.java") | ||||
r180 | command = "#{JAVA_COMPILER} -encoding utf8 #{classname}.java" | |||
r178 | system(command, err: params[:message_file]) | |||
r152 | if File.exists?(classname + ".class") | |||
r158 | File.open(params[:output_file],"w") {|file| file.write("#{classname}")} | |||
end | ||||
if classname == 'DUMMY' | ||||
File.open(params[:message_file],"w") {|file| file.write("Cannot find any public class in the source code\n")} | ||||
r151 | end | |||
r147 | ||||
r154 | when "ruby" | |||
r178 | command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}" | |||
if system(command, err: params[:message_file]) | ||||
r155 | File.open(params[:output_file],"w") do |out_file| | |||
out_file.puts "#!#{RUBY_INTERPRETER}" | ||||
File.open(params[:source_file],"r").each do |line| | ||||
out_file.print line | ||||
end | ||||
r147 | end | |||
r155 | File.chmod(0755, params[:output_file]) | |||
r147 | end | |||
r154 | ||||
when "python" | ||||
r221 | #command = "#{PYTHON_CHECKER} #{params[:source_file]}" | |||
#if system(command, out: params[:message_file]) | ||||
r154 | #compile to python bytecode | |||
r215 | command = "#{PYTHON_INTERPRETER} -c \"import py_compile; py_compile.compile('#{params[:source_file]}','#{params[:source_file]}c');\"" | |||
r154 | puts "compile: #{command}" | |||
r221 | system(command, err: params[:message_file]) | |||
if FileTest.exists?("#{params[:source_file]}c") | ||||
puts "pwd: " + Dir.pwd | ||||
Dir.new('.').each {|file| puts file} | ||||
File.open(params[:output_file],"w") do |out_file| | ||||
out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c" | ||||
end | ||||
File.chmod(0755, params[:output_file]) | ||||
FileUtils.cp("#{params[:source_file]}c",params[:output_file]) | ||||
r154 | end | |||
r221 | #end | |||
r165 | ||||
when "php" | ||||
r178 | command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}" | |||
if system(command, err: params[:message_file]) | ||||
r165 | File.open(params[:output_file],"w") do |out_file| | |||
out_file.puts "#!#{PHP_INTERPRETER}" | ||||
File.open(params[:source_file],"r").each do |line| | ||||
out_file.print line | ||||
end | ||||
end | ||||
File.chmod(0755, params[:output_file]) | ||||
end | ||||
r219 | when "haskell" | |||
command = "#{HASKELL_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{HASKELL_OPTIONS}" | ||||
system(command, err: params[:message_file]) | ||||
r154 | else | |||
|
r107 | talk("ERROR: Invalid language specified!") | ||
open(params[:message_file],"w") do |f| | ||||
f.puts "ERROR: Invalid language specified!" | ||||
end | ||||
exit(127) | ||||
end | ||||
|
r0 | |||
# Report success or failure. | ||||
|
r107 | if FileTest.exists? params[:output_file] | ||
talk "Compilation was successful!" | ||||
|
r0 | else | ||
|
r107 | talk "ERROR: Something was wrong during the compilation!" | ||
end | ||||