#
# This file is automatically generated. DO NOT MODIFY!
#
# install.rb
#
#   Copyright (c) 2000-2002 Minero Aoki <aamine@loveruby.net>
#
#   This program is free software.
#   You can distribute/modify this program under the terms of
#   the GNU Lesser General Public License version 2.
#

### begin compat.rb

unless Enumerable.instance_methods.include? 'inject' then
module Enumerable
  def inject( result )
    each do |i|
      result = yield(result, i)
    end
    result
  end
end
end

def File.read_all( fname )
  File.open(fname, 'rb') {|f| return f.read }
end

def File.write( fname, str )
  File.open(fname, 'wb') {|f| f.write str }
end

### end compat.rb
### begin config.rb

if i = ARGV.index(/\A--rbconfig=/) then
  file = $'
  ARGV.delete_at(i)
  require file
else
  require 'rbconfig'
end


class ConfigTable

  c = ::Config::CONFIG

  rubypath = c['bindir'] + '/' + c['ruby_install_name']

  major = c['MAJOR'].to_i
  minor = c['MINOR'].to_i
  teeny = c['TEENY'].to_i
  version = "#{major}.#{minor}"

  # ruby ver. >= 1.4.4?
  newpath_p = ((major >= 2) or
               ((major == 1) and
                ((minor >= 5) or
                 ((minor == 4) and (teeny >= 4)))))
  
  re = Regexp.new('\A' + Regexp.quote(c['prefix']))
  subprefix = lambda {|path|
      re === path and path.sub(re, '$prefix')
  }

  if c['rubylibdir'] then
    # 1.6.3 < V
    stdruby    = subprefix.call(c['rubylibdir'])
    siteruby   = subprefix.call(c['sitedir'])
    versite    = subprefix.call(c['sitelibdir'])
    sodir      = subprefix.call(c['sitearchdir'])
  elsif newpath_p then
    # 1.4.4 <= V <= 1.6.3
    stdruby    = "$prefix/lib/ruby/#{version}"
    siteruby   = subprefix.call(c['sitedir'])
    versite    = siteruby + '/' + version
    sodir      = "$site-ruby/#{c['arch']}"
  else
    # V < 1.4.4
    stdruby    = "$prefix/lib/ruby/#{version}"
    siteruby   = "$prefix/lib/ruby/#{version}/site_ruby"
    versite    = siteruby
    sodir      = "$site-ruby/#{c['arch']}"
  end

  DESCRIPTER = [
    [ 'prefix',    [ c['prefix'],
                     'path',
                     'path prefix of target environment' ] ],
    [ 'std-ruby',  [ stdruby,
                     'path',
                     'the directory for standard ruby libraries' ] ],
    [ 'site-ruby-common', [ siteruby,
                     'path',
                     'the directory for version-independent non-standard ruby libraries' ] ],
    [ 'site-ruby', [ versite,
                     'path',
                     'the directory for non-standard ruby libraries' ] ],
    [ 'bin-dir',   [ '$prefix/bin',
                     'path',
                     'the directory for commands' ] ],
    [ 'rb-dir',    [ '$site-ruby',
                     'path',
                     'the directory for ruby scripts' ] ],
    [ 'so-dir',    [ sodir,
                     'path',
                     'the directory for ruby extentions' ] ],
    [ 'data-dir',  [ '$prefix/share',
                     'path',
                     'the directory for shared data' ] ],
    [ 'ruby-path', [ rubypath,
                     'path',
                     'path to set to #! line' ] ],
    [ 'ruby-prog', [ rubypath,
                     'name',
                     'the ruby program using for installation' ] ],
    [ 'make-prog', [ 'make',
                     'name',
                     'the make program to compile ruby extentions' ] ],
    [ 'without-ext', [ 'no',
                       'yes/no',
                       'does not compile/install ruby extentions' ] ]
  ]

  SAVE_FILE = 'config.save'

  def ConfigTable.each_name( &block )
    keys().each( &block )
  end

  def ConfigTable.keys
    DESCRIPTER.collect {|k,*dummy| k }
  end

  def ConfigTable.each_definition( &block )
    DESCRIPTER.each( &block )
  end

  def ConfigTable.get_entry( name )
    name, ent = DESCRIPTER.assoc(name)
    ent
  end

  def ConfigTable.get_entry!( name )
    get_entry(name) or raise ArgumentError, "no such config: #{name}"
  end

  def ConfigTable.add_entry( name, vals )
    ConfigTable::DESCRIPTER.push [name,vals]
  end

  def ConfigTable.remove_entry( name )
    get_entry name or raise ArgumentError, "no such config: #{name}"
    DESCRIPTER.delete_if {|n,arr| n == name }
  end

  def ConfigTable.config_key?( name )
    get_entry(name) ? true : false
  end

  def ConfigTable.bool_config?( name )
    ent = get_entry(name) or return false
    ent[1] == 'yes/no'
  end

  def ConfigTable.value_config?( name )
    ent = get_entry(name) or return false
    ent[1] != 'yes/no'
  end

  def ConfigTable.path_config?( name )
    ent = get_entry(name) or return false
    ent[1] == 'path'
  end


  class << self

    alias newobj new

    def new
      c = newobj()
      c.__send__ :init
      c
    end

    def load
      c = newobj()
      File.file? SAVE_FILE or
              raise InstallError, "#{File.basename $0} config first"
      File.foreach( SAVE_FILE ) do |line|
        k, v = line.split( '=', 2 )
        c.instance_eval {
            @table[k] = v.strip
        }
      end
      c
    end
  
  end

  def initialize
    @table = {}
  end

  def init
    DESCRIPTER.each do |k, (default, vname, desc, default2)|
      @table[k] = default
    end
  end
  private :init

  def save
    File.open( SAVE_FILE, 'w' ) {|f|
        @table.each do |k, v|
          f.printf "%s=%s\n", k, v if v
        end
    }
  end

  def []=( k, v )
    ConfigTable.config_key? k or raise InstallError, "unknown config option #{k}"
    if ConfigTable.path_config? k then
      @table[k] = (v[0,1] != '$') ? File.expand_path(v) : v
    else
      @table[k] = v
    end
  end
    
  def []( key )
    @table[key] or return nil
    @table[key].gsub( %r<\$([^/]+)> ) { self[$1] }
  end

  def set_raw( key, val )
    @table[key] = val
  end

  def get_raw( key )
    @table[key]
  end

end


class MetaConfigEnvironment

  def self.eval_file( file )
    return unless File.file? file
    new.instance_eval File.read_all(file), file, 1
  end

  private

  def config_names
    ConfigTable.keys
  end

  def config?( name )
    ConfigTable.config_key? name
  end

  def bool_config?( name )
    ConfigTable.bool_config? name
  end

  def value_config?( name )
    ConfigTable.value_config? name
  end

  def path_config?( name )
    ConfigTable.path_config? name
  end

  def add_config( name, argname, default, desc )
    ConfigTable.add_entry name,[default,argname,desc]
  end

  def add_path_config( name, default, desc )
    add_config name, 'path', default, desc
  end

  def add_bool_config( name, default, desc )
    add_config name, 'yes/no', default ? 'yes' : 'no', desc
  end

  def set_config_default( name, default )
    if bool_config? name then
      ConfigTable.get_entry!(name)[0] = default ? 'yes' : 'no'
    else
      ConfigTable.get_entry!(name)[0] = default
    end
  end

  def remove_config( name )
    ent = ConfigTable.get_entry(name)
    ConfigTable.remove_entry name
    ent
  end

end

### end config.rb
### begin fileop.rb

module FileOperations

  def mkdir_p( dname, prefix = nil )
    dname = prefix + dname if prefix
    $stderr.puts "mkdir -p #{dname}" if verbose?
    return if no_harm?

    # does not check '/'... it's too abnormal case
    dirs = dname.split(%r_(?=/)_)
    if /\A[a-z]:\z/i === dirs[0] then
      disk = dirs.shift
      dirs[0] = disk + dirs[0]
    end
    dirs.each_index do |idx|
      path = dirs[0..idx].join('')
      Dir.mkdir path unless dir? path
    end
  end

  def rm_f( fname )
    $stderr.puts "rm -f #{fname}" if verbose?
    return if no_harm?

    if File.exist? fname or File.symlink? fname then
      File.chmod 0777, fname
      File.unlink fname
    end
  end

  def rm_rf( dn )
    $stderr.puts "rm -rf #{dn}" if verbose?
    return if no_harm?

    Dir.chdir dn
    Dir.foreach('.') do |fn|
      next if fn == '.'
      next if fn == '..'
      if dir? fn then
        verbose_off {
            rm_rf fn
        }
      else
        verbose_off {
            rm_f fn
        }
      end
    end
    Dir.chdir '..'
    Dir.rmdir dn
  end

  def mv( src, dest )
    rm_f dest
    begin
      File.link src, dest
    rescue
      File.write dest, File.read_all(src)
      File.chmod File.stat(src).mode, dest
    end
    rm_f src
  end

  def install( from, dest, mode, prefix = nil )
    $stderr.puts "install #{from} #{dest}" if verbose?
    return if no_harm?

    realdest = prefix + dest if prefix
    if dir? realdest then
      realdest += '/' + File.basename(from)
    end
    str = File.read_all(from)
    if diff? str, realdest then
      verbose_off {
          rm_f realdest if File.exist? realdest
      }
      File.write realdest, str
      File.chmod mode, realdest

      File.open( objdir + '/InstalledFiles', 'a' ) {|f| f.puts realdest }
    end
  end

  def diff?( orig, targ )
    return true unless File.exist? targ
    orig != File.read_all(targ)
  end

  def command( str )
    $stderr.puts str if verbose?
    system str or raise RuntimeError, "'system #{str}' failed"
  end

  def ruby( str )
    command config('ruby-prog') + ' ' + str
  end

  def dir?( dname )
    # for corrupted windows stat()
    File.directory?( (dname[-1,1] == '/') ? dname : dname + '/' )
  end

  def all_files( dname )
    Dir.open( dname ) {|d|
        return d.find_all {|n| File.file? "#{dname}/#{n}" }
    }
  end

  def all_dirs( dname )
    Dir.open( dname ) {|d|
        return d.find_all {|n| dir? "#{dname}/#{n}" } - %w(. ..)
    }
  end

end

### end fileop.rb
### begin base.rb

class InstallError < StandardError; end


class Installer

  Version   = '3.1.2'
  Copyright = 'Copyright (c) 2000-2002 Minero Aoki'


  @toplevel = nil

  def self.declear_toplevel_installer( inst )
    @toplevel and
        raise ArgumentError, 'more than one toplevel installer decleared'
    @toplevel = inst
  end

  def self.toplevel_installer
    @toplevel
  end


  FILETYPES = %w( bin lib ext data )

  include FileOperations

  def initialize( config, opt, srcroot, objroot )
    @config = config
    @options = opt
    @srcdir = File.expand_path(srcroot)
    @objdir = File.expand_path(objroot)
    @currdir = '.'
  end

  def inspect
    "#<#{type} #{__id__}>"
  end

  #
  # configs/options
  #

  def get_config( key )
    @config[key]
  end

  alias config get_config

  def set_config( key, val )
    @config[key] = val
  end

  def no_harm?
    @options['no-harm']
  end

  def verbose?
    @options['verbose']
  end

  def verbose_off
    save, @options['verbose'] = @options['verbose'], false
    yield
    @options['verbose'] = save
  end

  #
  # srcdir/objdir
  #

  attr_reader :srcdir
  alias srcdir_root srcdir
  alias package_root srcdir

  def curr_srcdir
    "#{@srcdir}/#{@currdir}"
  end

  attr_reader :objdir
  alias objdir_root objdir

  def curr_objdir
    "#{@objdir}/#{@currdir}"
  end

  def srcfile( path )
    curr_srcdir + '/' + path
  end

  def srcexist?( path )
    File.exist? srcfile(path)
  end

  def srcdirectory?( path )
    dir? srcfile(path)
  end
  
  def srcfile?( path )
    File.file? srcfile(path)
  end

  def srcentries( path = '.' )
    Dir.open( curr_srcdir + '/' + path ) {|d|
        return d.to_a - %w(. ..) - hookfilenames
    }
  end

  def srcfiles( path = '.' )
    srcentries(path).find_all {|fname|
        File.file? File.join(curr_srcdir, path, fname)
    }
  end

  def srcdirectories( path = '.' )
    srcentries(path).find_all {|fname|
        dir? File.join(curr_srcdir, path, fname)
    }
  end

  def dive_into( rel )
    return unless dir? "#{@srcdir}/#{rel}"

    dir = File.basename(rel)
    Dir.mkdir dir unless dir? dir
    save = Dir.pwd
    Dir.chdir dir
    $stderr.puts '---> ' + rel if verbose?
    @currdir = rel
    yield
    Dir.chdir save
    $stderr.puts '<--- ' + rel if verbose?
    @currdir = File.dirname(rel)
  end

  #
  # config
  #

  def exec_config
    exec_task_traverse 'config'
  end

  def config_dir_bin( rel )
  end

  def config_dir_lib( rel )
  end

  def config_dir_ext( rel )
    extconf if extdir? curr_srcdir
  end

  def extconf
    opt = @options['config-opt'].join(' ')
    command "#{config('ruby-prog')} #{curr_srcdir}/extconf.rb #{opt}"
  end

  def config_dir_data( rel )
  end

  #
  # setup
  #

  def exec_setup
    exec_task_traverse 'setup'
  end

  def setup_dir_bin( relpath )
    all_files( curr_srcdir ).each do |fname|
      add_rubypath "#{curr_srcdir}/#{fname}"
    end
  end

  SHEBANG_RE = /\A\#!\s*\S*ruby\S*/

  def add_rubypath( path )
    $stderr.puts %Q<set #! line to "\#!#{config('ruby-path')}" for #{path} ...> if verbose?
    return if no_harm?

    tmpfile = File.basename(path) + '.tmp'
    begin
      File.open( path ) {|r|
      File.open( tmpfile, 'w' ) {|w|
          first = r.gets
          return unless SHEBANG_RE === first   # reject '/usr/bin/env ruby'

          w.print first.sub( SHEBANG_RE, '#!' + config('ruby-path') )
          w.write r.read
      } }
      mv tmpfile, File.basename(path)
    ensure
      rm_f tmpfile if File.exist? tmpfile
    end
  end

  def setup_dir_lib( relpath )
  end

  def setup_dir_ext( relpath )
    if extdir? curr_srcdir then
      make
    end
  end

  def make
    command config('make-prog')
  end

  def setup_dir_data( relpath )
  end

  #
  # install
  #

  def exec_install
    exec_task_traverse 'install'
  end

  def install_dir_bin( rel )
    install_files targfiles, config('bin-dir') + '/' + rel, 0755
  end

  def install_dir_lib( rel )
    install_files targfiles, config('rb-dir') + '/' + rel, 0644
  end

  def install_dir_ext( rel )
    if extdir? curr_srcdir then
      install_dir_ext_main File.dirname(rel)
    end
  end

  def install_dir_ext_main( rel )
    install_files allext('.'), config('so-dir') + '/' + rel, 0555
  end

  def install_dir_data( rel )
    install_files targfiles, config('data-dir') + '/' + rel, 0644
  end

  def install_files( list, dest, mode )
    mkdir_p dest, @options['install-prefix']
    list.each do |fname|
      install fname, dest, mode, @options['install-prefix']
    end
  end
  
  def targfiles
    (targfilenames() - hookfilenames()).collect {|fname|
        File.exist?(fname) ? fname : File.join(curr_srcdir(), fname)
    }
  end

  def targfilenames
    [ curr_srcdir(), '.' ].inject([]) {|ret, dir|
        ret | all_files(dir)
    }
  end

  def hookfilenames
    %w( pre-%s post-%s pre-%s.rb post-%s.rb ).collect {|fmt|
        %w( config setup install clean ).collect {|t| sprintf fmt, t }
    }.flatten
  end

  def allext( dir )
    _allext(dir) or raise InstallError,
        "no extention exists: Have you done 'ruby #{$0} setup' ?"
  end

  DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/

  def _allext( dir )
    Dir.open( dir ) {|d|
        return d.find_all {|fname| DLEXT === fname }
    }
  end

  #
  # clean
  #

  def exec_clean
    exec_task_traverse 'clean'
    rm_f 'config.save'
    rm_f 'InstalledFiles'
  end

  def clean_dir_bin( rel )
  end

  def clean_dir_lib( rel )
  end

  def clean_dir_ext( rel )
    clean
  end
  
  def clean
    command config('make-prog') + ' clean' if File.file? 'Makefile'
  end

  def clean_dir_data( rel )
  end

  #
  # lib
  #

  def exec_task_traverse( task )
    run_hook 'pre-' + task
    FILETYPES.each do |type|
      if config('without-ext') == 'yes' and type == 'ext' then
        $stderr.puts 'skipping ext/* by user option' if verbose?
        next
      end
      traverse task, type, task + '_dir_' + type
    end
    run_hook 'post-' + task
  end

  def traverse( task, rel, mid )
    dive_into( rel ) {
        run_hook 'pre-' + task
        __send__ mid, rel.sub( %r_\A.*?(?:/|\z)_, '' )
        all_dirs( curr_srcdir ).each do |d|
          traverse task, rel + '/' + d, mid
        end
        run_hook 'post-' + task
    }
  end

  def run_hook( name )
    try_run_hook curr_srcdir + '/' + name           or
    try_run_hook curr_srcdir + '/' + name + '.rb'
  end

  def try_run_hook( fname )
    return false unless File.file? fname

    env = self.dup
    begin
      env.instance_eval File.read_all(fname), fname, 1
    rescue
      raise InstallError, "hook #{fname} failed:\n" + $!.message
    end
    true
  end

  def extdir?( dir )
    File.exist? dir + '/MANIFEST'
  end

end

### end base.rb
### begin toplevel.rb

class ToplevelInstaller < Installer

  TASKS = [
    [ 'config',   'saves your configurations' ],
    [ 'show',     'shows current configuration' ],
    [ 'setup',    'compiles extention or else' ],
    [ 'install',  'installs files' ],
    [ 'clean',    "does `make clean' for each extention" ]
  ]


  def initialize( root )
    super nil, {'verbose' => true}, root, '.'
    Installer.declear_toplevel_installer self
  end


  def execute
    run_metaconfigs

    case task = parsearg_global()
    when 'config'
      @config = ConfigTable.new
    else
      @config = ConfigTable.load
    end
    parsearg_TASK task

    exectask task
  end


  def run_metaconfigs
    MetaConfigEnvironment.eval_file "#{srcdir_root}/#{metaconfig}"
  end

  def metaconfig
    'metaconfig'
  end


  def exectask( task )
    if task == 'show' then
      exec_show
    else
      try task
    end
  end

  def try( task )
    $stderr.printf "#{File.basename $0}: entering %s phase...\n", task if verbose?
    begin
      __send__ 'exec_' + task
    rescue
      $stderr.printf "%s failed\n", task
      raise
    end
    $stderr.printf "#{File.basename $0}: %s done.\n", task if verbose?
  end

  #
  # processing arguments
  #

  def parsearg_global
    task_re = /\A(?:#{TASKS.collect {|i| i[0] }.join '|'})\z/

    while arg = ARGV.shift do
      case arg
      when /\A\w+\z/
        task_re === arg or raise InstallError, "wrong task: #{arg}"
        return arg

      when '-q', '--quiet'
        @options['verbose'] = false

      when       '--verbose'
        @options['verbose'] = true

      when '-h', '--help'
        print_usage $stdout
        exit 0

      when '-v', '--version'
        puts "#{File.basename $0} version #{Version}"
        exit 0
      
      when '--copyright'
        puts Copyright
        exit 0

      else
        raise InstallError, "unknown global option '#{arg}'"
      end
    end

    raise InstallError, 'no task or global option given'
  end


  def parsearg_TASK( task )
    mid = "parsearg_#{task}"
    if respond_to? mid, true then
      __send__ mid
    else
      ARGV.empty? or
          raise InstallError, "#{task}:  unknown options: #{ARGV.join ' '}"
    end
  end

  def parsearg_config
    re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
    @options['config-opt'] = []

    while i = ARGV.shift do
      if /\A--?\z/ === i then
        @options['config-opt'] = ARGV.dup
        break
      end
      m = re.match(i) or raise InstallError, "config: unknown option #{i}"
      name, value = m.to_a[1,2]
      if value then
        if ConfigTable.bool_config?(name) then
          /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i === value or raise InstallError, "config: --#{name} allows only yes/no for argument"
          value = (/\Ay(es)?|\At(rue)/i === value) ? 'yes' : 'no'
        end
      else
        ConfigTable.bool_config?(name) or raise InstallError, "config: --#{name} requires argument"
        value = 'yes'
      end
      @config[name] = value
    end
  end

  def parsearg_install
    @options['no-harm'] = false
    @options['install-prefix'] = ''
    while a = ARGV.shift do
      case a
      when /\A--no-harm\z/
        @options['no-harm'] = true
      when /\A--prefix=(.*)\z/
        path = $1
        path = File.expand_path(path) unless path[0,1] == '/'
        @options['install-prefix'] = path
      else
        raise InstallError, "install: unknown option #{a}"
      end
    end
  end


  def print_usage( out )
    out.puts
    out.puts 'Usage:'
    out.puts "  ruby #{File.basename $0} <global option>"
    out.puts "  ruby #{File.basename $0} [<global options>] <task> [<task options>]"

    fmt = "  %-20s %s\n"
    out.puts
    out.puts 'Global options:'
    out.printf fmt, '-q,--quiet',   'suppress message outputs'
    out.printf fmt, '   --verbose', 'output messages verbosely'
    out.printf fmt, '-h,--help',    'print this message'
    out.printf fmt, '-v,--version', 'print version and quit'
    out.printf fmt, '--copyright',  'print copyright and quit'

    out.puts
    out.puts 'Tasks:'
    TASKS.each do |name, desc|
      out.printf "  %-10s  %s\n", name, desc
    end

    out.puts
    out.puts 'Options for config:'
    ConfigTable.each_definition do |name, (default, arg, desc, default2)|
      out.printf "  %-20s %s [%s]\n",
                 '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
                 desc,
                 default2 || default
    end
    out.printf "  %-20s %s [%s]\n",
        '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"

    out.puts
    out.puts 'Options for install:'
    out.printf "  %-20s %s [%s]\n",
        '--no-harm', 'only display what to do if given', 'off'

    out.puts
  end

  #
  # config
  #

  def exec_config
    super
    @config.save
  end

  #
  # show
  #

  def exec_show
    ConfigTable.each_name do |k|
      v = @config.get_raw(k)
      if not v or v.empty? then
        v = '(not specified)'
      end
      printf "%-10s %s\n", k, v
    end
  end

end

### end toplevel.rb

if $0 == __FILE__ then
  begin
    installer = ToplevelInstaller.new( File.dirname($0) )
    installer.execute
  rescue
    raise if $DEBUG
    $stderr.puts $!.message
    $stderr.puts "try 'ruby #{$0} --help' for usage"
    exit 1
  end
end
