# -*- ruby -*-

require 'fileutils'
module FileUtils
  def chdir(dir, options = {}, &block) # :yield: dir
    dir = File.expand_path(dir)
    fu_output_message "Entering directory `#{dir}'" if options[:verbose]
    Dir.chdir(dir, &block)
    fu_output_message "Leaving directory `#{dir}'" if options[:verbose] and block
  end
  module_function :chdir
end

task :default => [:houken]


$srcDir = 'src'
$objDir = 'obj'

houkenDir = 'houken'
sampleDir = 'sample'


#rule ".o" => [
#  proc {|tn| tn.sub(/\.o/, '.cpp').sub("#{$objDir}/", "#{$srcDir}/")}
#] do |t|
#  sh 'g++', '-O2', '-c', '-o', t.name, t.source
#end
  

def makeDepend (srcFile)
  depFile = srcFile.sub("#{$srcDir}/", "#{$objDir}/").sub(/\.cpp$/, '.d')
  puts "makind #{depFile}"
  target = dep = nil
  open("| g++ -MM #{srcFile}") do |fd|
    target,dep = fd.read.gsub(/\\\s/, '').split(':', 2)
  end
  depends = dep.split(/\s+/)
  depends.delete('')
  target = $objDir + '/' + target
  open(depFile, 'w') do |out|
    a = ([target] + depends).join(',')
    out.puts a
  end
  file target => depends do
    sh 'g++', '-Wall', '-g', '-c', '-o', target, srcFile
  end
end


def readDepend (srcFile)
  depFile = srcFile.sub("#{$srcDir}/", "#{$objDir}/").sub(/\.cpp$/, '.d')
  begin
    open(depFile) do |fd|
      depends = fd.read.chomp.split(',')
      target = depends.shift
      file target => depends do
        sh 'g++', '-Wall', '-g', '-c', '-o', target, srcFile
      end
    end
    return true
  rescue Errno::ENOENT
    return false
  end
end



srcs = FileList["src/*.cpp"]
objs = srcs.ext('.o').map{|x| x.sub("#{$srcDir}/", "#{$objDir}/")}
deps = srcs.ext('.d').map{|x| x.sub("#{$srcDir}/", "#{$objDir}/")}


task :depend do
  srcs.each do |src|
    readDepend(src) or makeDepend(src)
  end
end

desc "create PEG parser generator 'houken/houken' executable"
task :houken do
  chdir houkenDir, :verbose=>true do
    sh 'rake'
  end
end

desc "create sample calculator 'sample/calc' executable"
task :sample do
  chdir sampleDir, :verbose=>true do
    sh 'rake'
  end
end


desc "do unittest"
task :unittest do
  chdir 'unittest', :verbose=>true do
    sh 'rake'
  end
end

desc "do errortest"
task :errortest do
  chdir 'errortest', :verbose=>true do
    sh 'rake'
  end
end

desc "do unittest and errortest"
task :test => [:unittest, :errortest]
  

desc "cleanup all"
task :clean do
  chdir 'unittest', :verbose=>true do
    sh 'rake', 'clean'
  end
  chdir 'errortest', :verbose=>true do
    sh 'rake', 'clean'
  end
  chdir houkenDir, :verbose=>true do
    sh 'rake', 'clean'
  end
  chdir sampleDir, :verbose=>true do
    sh 'rake', 'clean'
  end
end
