
require 'mkmf'


def main
  if create_rubynode_h()
    create_makefile 'nodedump'
  else
    $stderr.puts 'detect unknown node: abort'
    exit 1
  end
end


def create_rubynode_h
  nodenames = []

  File.open(node_h_path()) {|r|
      while line = r.gets
        break if /enum node_type/ === line
      end
      File.open('rubynode.h', 'w') {|f|
          f.puts 'const char *node_names[] = {'
          while line = r.gets
            break if /\};/ === line
            case line
            when /\A\#/
              f.print line
            when /\A\s*(\w+)(,)?/
              name = $1
              comma = $2
              f.puts %Q<\t"#{name}"#{comma}>
              f.puts "#define #{name} #{name}"
              nodenames.push name
            end
          end
          f.puts '};'
      }
  }

  check_node_names nodenames
end


def node_h_path
  header_dir() + '/node.h'
end

def header_dir
  ruby_header_dir('$libdir/ruby/$MAJOR.$MINOR/$arch') or
  ruby_header_dir('$srcdir') or
  ($stderr.puts 'archdir not exist: abort.'; exit 1)
end

require 'rbconfig'

def ruby_header_dir( fmt )
  dir = expand_params(fmt, Config::CONFIG)
  if File.exist? dir + '/ruby.h'
    dir
  else
    nil
  end
end

def expand_params( fmt, params )
  fmt.gsub(/\$(\w+)/) { params[$1] }
end


DUMMY_NODES = %w(
    NODE_MEMO
    NODE_LAST
    NODE_ALLOCA
    NODE_CNAME
    NODE_CFUNC
    NODE_IFUNC
)

def check_node_names( exist_nodes )
  handle_nodes = in_nodedump_c()
  # report 'we know but not in ruby', handle_nodes - exist_nodes
  report 'unknown nodes', exist_nodes - handle_nodes - DUMMY_NODES
end

def report( desc, list )
  if list.empty?
    true
  else
    $stderr.print desc, ': ', list.join(', '), "\n"
    false
  end
end

NODEDUMP_C = 'nodedump.c'

def in_nodedump_c
  File.open(File.join(File.dirname($0), NODEDUMP_C)) {|f|
      return f.grep(/case\s+(NODE_\w+):/) { $1 }
  }
end


main
