From 52f8b9c0b1e1606a4260ef2e0df4d525497691b1 Mon Sep 17 00:00:00 2001
From: Ralph Amissah <ralph@amissah.com>
Date: Sat, 7 Jul 2007 09:21:47 +0100
Subject: cgi-sample search form; texinfo fix; xml scaffold; help, man pages
 etc. visited; screen output, color set to true; docbook entries removed

* cgi generated sample search form
  * order results on files of the same title, in multiple files (with
    different filenames)
  * postgresql, character case sensitivity, control, on/off
  * tail decoration, gplv3 & sisu info

* texinfo/info (pinfo) module starts to do something vaguely useful again
  [not a much used module, testing required]

* print XML rendition of document structure to screen -T

* sisurc.yml default, color set to true
  [apologies if this causes anyone any inconvenience, it is configurable in
  sisurc.yml]

* help, man pages, README (man(8) related and env, 'sisu -V')

* docbook entries removed for the present time

* sisu-install (install ruby rant script renamed) and permissions set to
  executable
---
 install | 3088 ---------------------------------------------------------------
 1 file changed, 3088 deletions(-)
 delete mode 100644 install

(limited to 'install')

diff --git a/install b/install
deleted file mode 100644
index 78ad16a4..00000000
--- a/install
+++ /dev/null
@@ -1,3088 +0,0 @@
-#!/usr/bin/env ruby
-
-# install - Monolithic rant script, autogenerated by rant-import 0.5.8.
-#
-# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
-#
-# This program is free software.
-# You can distribute/modify this program under the terms of
-# the GNU LGPL, Lesser General Public License version 2.1.
-
-
-require 'getoptlong'
-
-
-require 'rbconfig'
-
-unless Process::Status.method_defined?(:success?) # new in 1.8.2
-    class Process::Status
-        def success?; exitstatus == 0; end
-    end
-end
-unless Regexp.respond_to? :union # new in 1.8.1
-    def Regexp.union(*patterns)
-        return /(?!)/ if patterns.empty?
-        Regexp.new(patterns.join("|"))
-    end
-end
-if RUBY_VERSION < "1.8.2"
-    class Array
-        undef_method :flatten, :flatten!
-        def flatten
-            cp = self.dup
-            cp.flatten!
-            cp
-        end
-        def flatten!
-            res = []
-            flattened = false
-            self.each { |e|
-                if e.respond_to? :to_ary
-                    res.concat(e.to_ary)
-                    flattened = true
-                else
-                    res << e
-                end
-            }
-            if flattened
-                replace(res)
-                flatten!
-                self
-            end
-        end
-    end
-end
-
-class String
-    def _rant_sub_ext(ext, new_ext = nil)
-        if new_ext
-            self.sub(/#{Regexp.escape ext}$/, new_ext)
-        else
-            self.sub(/(\.[^.]*$)|$/, ".#{ext}")
-        end
-    end
-end
-
-module Rant
-    VERSION = '0.5.8'
-
-    @__rant_no_value__ = Object.new.freeze
-    def self.__rant_no_value__
-	@__rant_no_value__
-    end
-
-    module Env
-        OS = ::Config::CONFIG['target']
-        RUBY = ::Config::CONFIG['ruby_install_name']
-        RUBY_BINDIR = ::Config::CONFIG['bindir']
-        RUBY_EXE = File.join(RUBY_BINDIR, RUBY + ::Config::CONFIG["EXEEXT"])
-
-        @@zip_bin = false
-        @@tar_bin = false
-
-        if OS =~ /mswin/i
-            def on_windows?; true; end
-        else
-            def on_windows?; false; end
-        end
-
-        def have_zip?
-            if @@zip_bin == false
-                @@zip_bin = find_bin "zip"
-            end
-            !@@zip_bin.nil?
-        end
-        def have_tar?
-            if @@tar_bin == false
-                @@tar_bin = find_bin "tar"
-            end
-            !@@tar_bin.nil?
-        end
-        def pathes
-            path = ENV[on_windows? ? "Path" : "PATH"]
-            return [] unless path
-            path.split(on_windows? ? ";" : ":")
-        end
-        def find_bin bin_name
-            if on_windows?
-                bin_name_exe = nil
-                if bin_name !~ /\.[^\.]{1,3}$/i
-                    bin_name_exe = bin_name + ".exe"
-                end
-                pathes.each { |dir|
-                    file = File.join(dir, bin_name)
-                    return file if test(?f, file)
-                    if bin_name_exe
-                        file = File.join(dir, bin_name_exe)
-                        return file if test(?f, file)
-                    end
-                }
-            else
-                pathes.each { |dir|
-                    file = File.join(dir, bin_name)
-                    return file if test(?x, file)
-                }
-            end
-            nil
-        end
-        def shell_path path
-            if on_windows?
-                path = path.tr("/", "\\")
-                if path.include? ' '
-                    '"' + path + '"'
-                else
-                    path
-                end
-            else
-                if path.include? ' '
-                    "'" + path + "'"
-                else
-                    path
-                end
-            end
-        end
-        extend self
-    end # module Env
-
-    module Sys
-	def sp(arg)
-            if arg.respond_to? :to_ary
-                arg.to_ary.map{ |e| sp e }.join(' ')
-            else
-                _escaped_path arg
-            end
-	end
-        def escape(arg)
-            if arg.respond_to? :to_ary
-                arg.to_ary.map{ |e| escape e }.join(' ')
-            else
-                _escaped arg
-            end
-        end
-        if Env.on_windows?
-            def _escaped_path(path)
-		_escaped(path.to_s.tr("/", "\\"))
-            end
-            def _escaped(arg)
-		sarg = arg.to_s
-		return sarg unless sarg.include?(" ")
-		sarg << "\\" if sarg[-1].chr == "\\"
-                "\"#{sarg}\""
-            end
-            def regular_filename(fn)
-                fn.to_str.tr("\\", "/").gsub(%r{/{2,}}, "/")
-            end
-        else
-            def _escaped_path(path)
-                path.to_s.gsub(/(?=\s)/, "\\")
-            end
-            alias _escaped _escaped_path
-            def regular_filename(fn)
-                fn.to_str.gsub(%r{/{2,}}, "/")
-            end
-        end
-        private :_escaped_path
-        private :_escaped
-	def split_all(path)
-            names = regular_filename(path).split(%r{/})
-            names[0] = "/" if names[0] && names[0].empty?
-            names
-	end
-        extend self
-    end # module Sys
-
-
-    ROOT_RANTFILE = "root.rant"
-    SUB_RANTFILE = "sub.rant"
-    RANTFILES = [ "Rantfile", "rantfile", ROOT_RANTFILE ]
-    
-    CODE_IMPORTS = []
-    
-    class RantAbortException < StandardError
-    end
-
-    class RantDoneException < StandardError
-    end
-
-    class Error < StandardError
-    end
-
-    module Generators
-    end
-
-    module RantVar
-
-	class Error < Rant::Error
-	end
-
-	class ConstraintError < Error
-
-	    attr_reader :constraint, :val
-
-	    def initialize(constraint, val, msg = nil)
-		@msg = msg
-		@constraint = constraint
-		@val = val
-	    end
-
-	    def message
-		val_desc = @val.inspect
-		val_desc[7..-1] = "..." if val_desc.length > 10
-		"#{val_desc} doesn't match constraint: #@constraint"
-	    end
-	end
-
-	class NotAConstraintFactoryError < Error
-	    attr_reader :obj
-	    def initialize(obj, msg = nil)
-		@msg = msg
-		@obj = obj
-	    end
-	    def message
-		obj_desc = @obj.inspect
-		obj_desc[7..-1] = "..." if obj_desc.length > 10
-		"#{obj_desc} is not a valid constraint factory"
-	    end
-	end
-
-	class InvalidVidError < Error
-	    def initialize(vid, msg = nil)
-		@msg = msg
-		@vid = vid
-	    end
-	    def message
-		vid_desc = @vid.inspect
-		vid_desc[7..-1] = "..." if vid_desc.length > 10
-		"#{vid_desc} is not a valid var identifier"
-	    end
-	end
-
-	class InvalidConstraintError < Error
-	end
-
-	class QueryError < Error
-	end
-
-	class Space
-
-	    @@env_ref = Object.new
-
-	    def initialize
-		@store = {}
-		@constraints = {}
-	    end
-
-	    def query(*args, &block)
-		case args.size
-		when 0
-		    raise QueryError, "no arguments", caller
-		when 1
-		    arg = args.first
-		    if Hash === arg
-			if arg.size == 1
-			    arg.each { |k,v|
-				self[k] = v if self[k].nil?
-			    }
-			    self
-			else
-			    init_all arg
-			end
-		    else
-			self[arg]
-		    end
-		when 2, 3
-		    vid, cf, val = *args
-                    constrain vid,
-                        get_factory(cf).rant_constraint
-		    self[vid] = val if val
-		else
-		    raise QueryError, "too many arguments"
-		end
-	    end
-
-	    def restrict vid, ct, *ct_args
-		if vid.respond_to? :to_ary
-		    vid.to_ary.each { |v| restrict(v, ct, *ct_args) }
-		else
-		    constrain vid,
-			get_factory(ct).rant_constraint(*ct_args)
-		end
-		self
-	    end
-
-	    def get_factory id
-		if String === id || Symbol === id
-                    id = Constraints.const_get(id) rescue nil
-		end
-		unless id.respond_to? :rant_constraint
-                    raise NotAConstraintFactoryError.new(id), caller
-		end
-		id
-	    end
-	    private :get_factory
-
-	    def [](vid)
-		vid = RantVar.valid_vid vid
-		val = @store[vid]
-		val.equal?(@@env_ref) ? ENV[vid] : val
-	    end
-
-	    def []=(vid, val)
-		vid = RantVar.valid_vid(vid)
-		c = @constraints[vid]
-		if @store[vid] == @@env_ref
-		    ENV[vid] = c ? c.filter(val) : val
-		else
-		    @store[vid] = c ? c.filter(val) : val
-		end
-	    end
-
-	    def env(*vars)
-		vars.flatten.each { |var|
-		    vid = RantVar.valid_vid(var)
-		    cur_val = @store[vid]
-		    next if cur_val == @@env_ref
-		    ENV[vid] = cur_val unless cur_val.nil?
-		    @store[vid] = @@env_ref
-		}
-		nil
-	    end
-
-	    def set_all hash
-		unless Hash === hash
-		    raise QueryError,
-			"set_all argument has to be a hash"
-		end
-		hash.each_pair { |k, v|
-		    self[k] = v
-		}
-	    end
-
-	    def init_all hash
-		unless Hash === hash
-		    raise QueryError,
-			"init_all argument has to be a hash"
-		end
-		hash.each_pair { |k, v|
-		    self[k] = v if self[k].nil?
-		}
-	    end
-
-	    def constrain vid, constraint
-		vid = RantVar.valid_vid(vid)
-		unless RantVar.valid_constraint? constraint
-		    raise InvalidConstraintError, constraint
-		end
-		@constraints[vid] = constraint
-		if @store.member? vid
-		    begin
-			val = @store[vid]
-			@store[vid] = constraint.filter(@store[vid])
-		    rescue
-			@store[vid] = constraint.default
-			raise ConstraintError.new(constraint, val)
-		    end
-		else
-		    @store[vid] = constraint.default
-		end
-	    end
-
-	    def has_var?(vid)
-		!self[vid].nil?
-	    end
-
-            def _set(vid, val) #:nodoc:
-                @store[vid] = val
-            end
-
-            def _get(vid) #:nodoc:
-                @store[vid]
-            end
-
-            def _init(vid, val) #:nodoc:
-                @store[vid] ||= val
-            end
-
-	end	# class Space
-
-	module Constraint
-	    def matches? val
-		filter val
-		true
-	    rescue
-		return false
-	    end
-	end
-
-	def valid_vid(obj)
-	    case obj
-	    when String; obj
-	    when Symbol; obj.to_s
-	    else
-		if obj.respond_to? :to_str
-		    obj.to_str
-		else
-		    raise InvalidVidError.new(obj)
-		end
-	    end
-	end
-	
-	def valid_constraint?(obj)
-	    obj.respond_to?(:filter) &&
-		obj.respond_to?(:matches?) &&
-		obj.respond_to?(:default)
-	end
-
-	module_function :valid_constraint?, :valid_vid
-
-	module Constraints
-	    class AutoList
-		include Constraint
-		class << self
-		    alias rant_constraint new
-		end
-		def filter(val)
-		    if val.respond_to? :to_ary
-			val.to_ary
-		    elsif val.nil?
-			raise ConstraintError.new(self, val)
-		    else
-			[val]
-		    end
-		end
-		def default
-		    []
-		end
-		def to_s
-		    "list or single, non-nil value"
-		end
-	    end
-        end # module Constraints
-    end # module RantVar
-end # module Rant
-
-
-require 'fileutils'
-
-
-module Rant
-    def FileList(arg)
-        if arg.respond_to?(:to_rant_filelist)
-            arg.to_rant_filelist
-        elsif arg.respond_to?(:to_ary)
-            FileList.new(arg.to_ary)
-        else
-            raise TypeError,
-                "cannot convert #{arg.class} into Rant::FileList"
-        end
-    end
-    module_function :FileList
-    class FileList
-        include Enumerable
-
-        ESC_SEPARATOR = Regexp.escape(File::SEPARATOR)
-        ESC_ALT_SEPARATOR = File::ALT_SEPARATOR ?
-            Regexp.escape(File::ALT_SEPARATOR) : nil
-
-        class << self
-            def [](*patterns)
-                new.hide_dotfiles.include(*patterns)
-            end
-            def glob(*patterns)
-                fl = new.hide_dotfiles.ignore(".", "..").include(*patterns)
-                if block_given? then yield fl else fl end
-            end
-            def glob_all(*patterns)
-                fl = new.ignore(".", "..").include(*patterns)
-                if block_given? then yield fl else fl end
-            end
-        end
-
-        def initialize(store = [])
-            @pending = false
-            @def_glob_dotfiles = true
-            @items = store
-            @ignore_rx = nil
-            @keep = {}
-            @actions = []
-        end
-        alias _object_dup dup
-        private :_object_dup
-        def dup
-            c = _object_dup
-            c.items = @items.dup
-            c.actions = @actions.dup
-            c.ignore_rx = @ignore_rx.dup if @ignore_rx
-            c.instance_variable_set(:@keep, @keep.dup)
-            c
-        end
-        def copy
-            c = _object_dup
-            c.items = @items.map { |entry| entry.dup }
-            c.actions = @actions.dup
-            c.ignore_rx = @ignore_rx.dup if @ignore_rx
-            h_keep = {}
-            @keep.each_key { |entry| h_keep[entry] = true }
-            c.instance_variable_set(:@keep, h_keep)
-            c
-        end
-        def glob_dotfiles?
-            @def_glob_dotfiles
-        end
-        def glob_dotfiles=(flag)
-            @def_glob_dotfiles = flag ? true : false
-        end
-        def hide_dotfiles
-            @def_glob_dotfiles = false
-            self
-        end
-        def glob_dotfiles
-            @def_glob_dotfiles = true
-            self
-        end
-
-        protected
-        attr_accessor :actions, :items
-        attr_accessor :pending
-        attr_accessor :ignore_rx
-
-        public
-        def each(&block)
-            resolve if @pending
-            @items.each(&block)
-            self
-        end
-        def to_ary
-            resolve if @pending
-            @items
-        end
-        alias to_a to_ary
-        alias entries to_ary    # entries: defined in Enumerable
-        def to_rant_filelist
-            self
-        end
-        def +(other)
-            if other.respond_to? :to_rant_filelist
-                c = other.to_rant_filelist.dup
-                c.actions.concat(@actions)
-                c.items.concat(@items)
-                c.pending = !c.actions.empty?
-                c
-            elsif other.respond_to? :to_ary
-                c = dup
-                c.actions <<
-                    [:apply_ary_method_1, :concat, other.to_ary.dup]
-                c.pending = true
-                c
-            else
-                raise TypeError,
-                    "cannot add #{other.class} to Rant::FileList"
-            end
-        end
-        def <<(file)
-            @actions << [:apply_ary_method_1, :push, file]
-            @keep[file] = true
-            @pending = true
-            self
-        end
-        def keep(entry)
-            @keep[entry] = true
-            @items << entry
-            self
-        end
-        def concat(ary)
-            if @pending
-                ary = ary.to_ary.dup
-                @actions << [:apply_ary_method_1, :concat, ary]
-            else
-                ix = ignore_rx and ary = ary.to_ary.reject { |f| f =~ ix }
-                @items.concat(ary)
-            end
-            self
-        end
-        def size
-            resolve if @pending
-            @items.size
-        end
-        alias length size
-        def empty?
-            resolve if @pending
-            @items.empty?
-        end
-        def join(sep = ' ')
-            resolve if @pending
-            @items.join(sep)
-        end
-        def pop
-            resolve if @pending
-            @items.pop
-        end
-        def push(entry)
-            resolve if @pending
-            @items.push(entry) if entry !~ ignore_rx
-            self
-        end
-        def shift
-            resolve if @pending
-            @items.shift
-        end
-        def unshift(entry)
-            resolve if @pending
-            @items.unshift(entry) if entry !~ ignore_rx
-            self
-        end
-if Object.method_defined?(:fcall) || Object.method_defined?(:funcall) # in Ruby 1.9 like __send__
-        @@__send_private__ = Object.method_defined?(:fcall) ? :fcall : :funcall
-        def resolve
-            @pending = false
-            @actions.each{ |action| self.__send__(@@__send_private__, *action) }.clear
-            ix = ignore_rx
-            if ix
-                @items.reject! { |f| f =~ ix && !@keep[f] }
-            end
-            self
-        end
-else
-        def resolve
-            @pending = false
-            @actions.each{ |action| self.__send__(*action) }.clear
-            ix = ignore_rx
-            if ix
-                @items.reject! { |f| f =~ ix && !@keep[f] }
-            end
-            self
-        end
-end
-        def include(*pats)
-            @def_glob_dotfiles ? glob_all(*pats) : glob_unix(*pats)
-        end
-        alias glob include
-        def glob_unix(*patterns)
-            patterns.flatten.each { |pat|
-                @actions << [:apply_glob_unix, pat]
-            }
-            @pending = true
-            self
-        end
-        def glob_all(*patterns)
-            patterns.flatten.each { |pat|
-                @actions << [:apply_glob_all, pat]
-            }
-            @pending = true
-            self
-        end
-        if RUBY_VERSION < "1.8.2"
-            FN_DOTFILE_RX_ = ESC_ALT_SEPARATOR ?
-                /(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)\..*
-                    ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x :
-                /(^|#{ESC_SEPARATOR}+)\..* (#{ESC_SEPARATOR}+|$)/x
-            def apply_glob_unix(pattern)
-                inc_files = Dir.glob(pattern)
-                unless pattern =~ /(^|\/)\./
-                    inc_files.reject! { |fn| fn =~ FN_DOTFILE_RX_ }
-                end
-                @items.concat(inc_files)
-            end
-        else
-            def apply_glob_unix(pattern)
-                @items.concat(Dir.glob(pattern))
-            end
-        end
-        private :apply_glob_unix
-        def apply_glob_all(pattern)
-            @items.concat(Dir.glob(pattern, File::FNM_DOTMATCH))
-        end
-        private :apply_glob_all
-        def exclude(*patterns)
-            patterns.each { |pat|
-                if Regexp === pat
-                    @actions << [:apply_exclude_rx, pat]
-                else
-                    @actions << [:apply_exclude, pat]
-                end
-            }
-            @pending = true
-            self
-        end
-        def ignore(*patterns)
-            patterns.each { |pat|
-                add_ignore_rx(Regexp === pat ? pat : mk_all_rx(pat))
-            }
-            @pending = true
-            self
-        end
-        def add_ignore_rx(rx)
-            @ignore_rx =
-            if @ignore_rx
-                Regexp.union(@ignore_rx, rx)
-            else
-                rx
-            end
-        end
-        private :add_ignore_rx
-        def apply_exclude(pattern)
-            @items.reject! { |elem|
-                File.fnmatch?(pattern, elem, File::FNM_DOTMATCH) && !@keep[elem]
-            }
-        end
-        private :apply_exclude
-        def apply_exclude_rx(rx)
-            @items.reject! { |elem|
-                elem =~ rx && !@keep[elem]
-            }
-        end
-        private :apply_exclude_rx
-        def exclude_name(*names)
-            names.each { |name|
-                @actions << [:apply_exclude_rx, mk_all_rx(name)]
-            }
-            @pending = true
-            self
-        end
-        alias shun exclude_name
-        if File::ALT_SEPARATOR
-            def mk_all_rx(file)
-                /(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)#{Regexp.escape(file)}
-                    ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x
-            end
-        else
-            def mk_all_rx(file)
-                /(^|#{ESC_SEPARATOR}+)#{Regexp.escape(file)}
-                    (#{ESC_SEPARATOR}+|$)/x
-            end
-        end
-        private :mk_all_rx
-        def exclude_path(*patterns)
-            patterns.each { |pat|
-                @actions << [:apply_exclude_path, pat]
-            }
-            @pending = true
-            self
-        end
-        def apply_exclude_path(pattern)
-            flags = File::FNM_DOTMATCH|File::FNM_PATHNAME
-            @items.reject! { |elem|
-                File.fnmatch?(pattern, elem, flags) && !@keep[elem]
-            }
-        end
-        private :apply_exclude
-        def select(&block)
-            d = dup
-            d.actions << [:apply_select, block]
-            d.pending = true
-            d
-        end
-        alias find_all select
-        def apply_select blk
-            @items = @items.select(&blk)
-        end
-        private :apply_select
-        def map(&block)
-            d = dup
-            d.actions << [:apply_ary_method, :map!, block]
-            d.pending = true
-            d
-        end
-        alias collect map
-        def sub_ext(ext, new_ext=nil)
-            map { |f| f._rant_sub_ext ext, new_ext }
-        end
-        def ext(ext_str)
-            sub_ext(ext_str)
-        end
-        def arglist
-            Rant::Sys.sp to_ary
-        end
-        alias to_s arglist
-        alias object_inspect inspect
-        def uniq!
-            @actions << [:apply_ary_method, :uniq!]
-            @pending = true
-            self
-        end
-        def sort!
-            @actions << [:apply_ary_method, :sort!]
-            @pending = true
-            self
-        end
-        def map!(&block)
-            @actions << [:apply_ary_method, :map!, block]
-            @pending = true
-            self
-        end
-        def reject!(&block)
-            @actions << [:apply_ary_method, :reject!, block]
-            @pending = true
-            self
-        end
-        private
-        def apply_ary_method(meth, block=nil)
-            @items.send meth, &block
-        end
-        def apply_ary_method_1(meth, arg1, block=nil)
-            @items.send meth, arg1, &block
-        end
-    end # class FileList
-end # module Rant
-
-if RUBY_VERSION == "1.8.3"
-    module FileUtils
-        METHODS = singleton_methods - %w(private_module_function
-            commands options have_option? options_of collect_method)
-        module Verbose
-            class << self
-                public(*::FileUtils::METHODS)
-            end
-            public(*::FileUtils::METHODS)
-        end
-    end
-end
-
-if RUBY_VERSION < "1.8.1"
-    module FileUtils
-        undef_method :fu_list
-        def fu_list(arg)
-            arg.respond_to?(:to_ary) ? arg.to_ary : [arg]
-        end
-    end
-end
-
-module Rant
-    class RacFileList < FileList
-
-	attr_reader :subdir
-	attr_reader :basedir
-
-	def initialize(rac, store = [])
-	    super(store)
-	    @rac = rac
-	    @subdir = @rac.current_subdir
-	    @basedir = Dir.pwd
-	    @ignore_hash = nil
-            @add_ignore_args = []
-	    update_ignore_rx
-	end
-        def dup
-            c = super
-            c.instance_variable_set(
-                :@add_ignore_args, @add_ignore_args.dup)
-            c
-        end
-        def copy
-            c = super
-            c.instance_variable_set(
-                :@add_ignore_args, @add_ignore_args.map { |e| e.dup })
-            c
-        end
-        alias filelist_ignore ignore
-        def ignore(*patterns)
-            @add_ignore_args.concat patterns
-            self
-        end
-	def ignore_rx
-	    update_ignore_rx
-	    @ignore_rx
-	end
-	alias filelist_resolve resolve
-	def resolve
-	    Sys.cd(@basedir) { filelist_resolve }
-	end
-	def each_cd(&block)
-	    old_pwd = Dir.pwd
-	    Sys.cd(@basedir)
-	    filelist_resolve if @pending
-	    @items.each(&block)
-	ensure
-	    Sys.cd(old_pwd)
-	end
-	private
-	def update_ignore_rx
-	    ri = @rac.var[:ignore]
-            ri = ri ? (ri + @add_ignore_args) : @add_ignore_args
-	    rh = ri.hash
-	    unless rh == @ignore_hash
-		@ignore_rx = nil
-		filelist_ignore(*ri)
-		@ignore_hash = rh
-	    end
-	end
-    end	# class RacFileList
-
-    class MultiFileList
-
-	attr_reader :cur_list
-	
-	def initialize(rac)
-	    @rac = rac
-	    @cur_list = RacFileList.new(@rac)
-	    @lists = [@cur_list]
-	end
-
-	def each_entry(&block)
-	    @lists.each { |list|
-		list.each_cd(&block)
-	    }
-	end
-
-	def add(filelist)
-	    @cur_list = filelist
-	    @lists << filelist
-	    self
-	end
-
-	def method_missing(sym, *args, &block)
-	    if @cur_list && @cur_list.respond_to?(sym)
-		if @cur_list.subdir == @rac.current_subdir
-		    @cur_list.send(sym, *args, &block)
-		else
-		    add(RacFileList.new(@rac))
-		    @cur_list.send(sym, *args, &block)
-		end
-	    else
-		super
-	    end
-	end
-    end	# class MultiFileList
-
-    class CommandError < StandardError
-	attr_reader :cmd
-	attr_reader :status
-	def initialize(cmd, status=nil, msg=nil)
-	    @msg = msg
-	    @cmd = cmd
-	    @status = status
-	end
-	def message
-	    if !@msg && cmd
-		if status
-		    "Command failed with status #{status.exitstatus}:\n" +
-		    "[#{cmd}]"
-		else
-		    "Command failed:\n[#{cmd}]"
-		end
-	    else
-		@msg
-	    end
-	end
-    end
-
-    module Sys
-	include ::FileUtils::Verbose
-
-	@symlink_supported = true
-	class << self
-	    attr_accessor :symlink_supported
-	end
-
-	def fu_output_message(msg)	#:nodoc:
-	end
-        private :fu_output_message
-
-        def fu_each_src_dest(src, *rest)
-            src = src.to_ary if src.respond_to? :to_ary
-            super(src, *rest)
-        end
-        private :fu_each_src_dest
-
-	def sh(*cmd_args, &block)
-	    cmd_args.flatten!
-	    cmd = cmd_args.join(" ")
-	    fu_output_message cmd
-            success = system(*cmd_args)
-	    if block_given?
-                block[$?]
-            elsif !success
-		raise CommandError.new(cmd, $?)
-	    end
-	end
-
-	def ruby(*args, &block)
-            if args.empty?
-                sh(Env::RUBY_EXE, '', &block)
-            else
-                sh(args.unshift(Env::RUBY_EXE), &block)
-            end
-	end
-        def cd(dir, &block)
-            fu_output_message "cd #{dir}"
-            orig_pwd = Dir.pwd
-            Dir.chdir dir
-            if block
-                begin
-                    block.arity == 0 ? block.call : block.call(Dir.pwd)
-                ensure
-                    fu_output_message "cd -"
-                    Dir.chdir orig_pwd
-                end
-            else
-                self
-            end
-        end
-
-	def safe_ln(src, dest)
-            dest = dest.to_str
-            src = src.respond_to?(:to_ary) ? src.to_ary : src.to_str
-	    unless Sys.symlink_supported
-		cp(src, dest)
-	    else
-		begin
-		    ln(src, dest)
-		rescue Exception # SystemCallError # Errno::EOPNOTSUPP
-		    Sys.symlink_supported = false
-		    cp(src, dest)
-		end
-	    end
-	end
-
-        def ln_f(src, dest)
-            ln(src, dest, :force => true)
-        end
-
-        def split_path(str)
-            str.split(Env.on_windows? ? ";" : ":")
-        end
-
-        if Env.on_windows?
-            def root_dir?(path)
-                path == "/" || path == "\\" ||
-                    path =~ %r{\A[a-zA-Z]+:(\\|/)\Z}
-            end
-            def absolute_path?(path)
-                path =~ %r{\A([a-zA-Z]+:)?(/|\\)}
-            end
-        else
-            def root_dir?(path)
-                path == "/"
-            end
-            def absolute_path?(path)
-                path =~ %r{\A/}
-            end
-        end
-
-        extend self
-
-        if RUBY_VERSION >= "1.8.4"  # needed by 1.9.0, too
-            class << self
-                public(*::FileUtils::METHODS)
-            end
-            public(*::FileUtils::METHODS)
-        end
-
-    end	# module Sys
-
-    class SysObject
-	include Sys
-	def initialize(rant)
-	    @rant = rant or
-		raise ArgumentError, "rant application required"
-	end
-        def ignore(*patterns)
-            @rant.var[:ignore].concat(patterns)
-            nil
-        end
-        def filelist(arg = Rant.__rant_no_value__)
-            if Rant.__rant_no_value__.equal?(arg)
-                RacFileList.new(@rant)
-            elsif arg.respond_to?(:to_rant_filelist)
-                arg.to_rant_filelist
-            elsif arg.respond_to?(:to_ary)
-                RacFileList.new(@rant, arg.to_ary)
-            else
-                raise TypeError,
-                    "cannot convert #{arg.class} into Rant::FileList"
-            end
-        end
-	def [](*patterns)
-	    RacFileList.new(@rant).hide_dotfiles.include(*patterns)
-	end
-	def glob(*patterns, &block)
-	    fl = RacFileList.new(@rant).hide_dotfiles.include(*patterns)
-            fl.ignore(".", "..")
-            if block_given? then yield fl else fl end
-	end
-        def glob_all(*patterns, &block)
-	    fl = RacFileList.new(@rant).include(*patterns)
-            fl.ignore(".", "..") # use case: "*.*" as pattern
-            if block_given? then yield fl else fl end
-        end
-        def expand_path(path)
-            File.expand_path(@rant.project_to_fs_path(path))
-        end
-	private
-	def fu_output_message(cmd)
-	    @rant.cmd_msg cmd
-	end
-    end
-
-
-    class TaskFail < StandardError
-	def initialize(task, orig, msg)
-	    @task = task
-	    @orig = orig
-            @msg = msg
-	end
-        def exception
-            self
-        end
-	def task
-	    @task
-	end
-	def tname
-	    @task ? @task.name : nil
-	end
-	def orig
-	    @orig
-	end
-        def msg
-            @msg
-        end
-    end
-
-    class Rantfile
-	attr_reader :tasks, :path
-	attr_accessor :project_subdir
-	def initialize(path)
-	    @path = path or raise ArgumentError, "path required"
-	    @tasks = []
-	    @project_subdir = nil
-	end
-        alias to_s path
-        alias to_str path
-    end	# class Rantfile
-
-    module Node
-
-	INVOKE_OPT = {}.freeze
-
-	T0 = Time.at(0).freeze
-
-	attr_reader :name
-	attr_reader :rac
-	attr_accessor :description
-	attr_accessor :rantfile
-	attr_accessor :line_number
-        attr_accessor :project_subdir
-	
-	def initialize
-	    @description = nil
-	    @rantfile = nil
-	    @line_number = nil
-	    @run = false
-            @project_subdir = ""
-	    @success = nil
-	end
-
-        def reference_name
-            sd = rac.current_subdir
-            case sd
-            when ""; full_name
-            when project_subdir; name
-            else "@#{full_name}".sub(/^@#{Regexp.escape sd}\//, '')
-            end
-        end
-
-        alias to_s reference_name
-        alias to_rant_target name
-
-	def full_name
-	    sd = project_subdir
-	    sd.empty? ? name : File.join(sd, name)
-	end
-
-        def ch
-            {:file => rantfile.to_str, :ln => line_number}
-        end
-
-	def goto_task_home
-	    @rac.goto_project_dir project_subdir
-	end
-
-        def file_target?
-            false
-        end
-
-	def done?
-	    @success
-	end
-
-	def needed?
-            invoke(:needed? => true)
-	end
-
-	def run?
-	    @run
-	end
-
-	def invoke(opt = INVOKE_OPT)
-	    return circular_dep if run?
-	    @run = true
-	    begin
-		return !done? if opt[:needed?]
-		self.run if !done?
-                @success = true
-	    ensure
-		@run = false
-	    end
-	end
-
-	def fail msg = nil, orig = nil
-            raise TaskFail.new(self, orig, msg)
-	end
-
-	def each_target
-	end
-
-        def has_actions?
-            defined? @block and @block
-        end
-
-        def dry_run
-            text = "Executing #{name.dump}"
-            text << " [NOOP]" unless has_actions?
-            @rac.cmd_msg text
-            action_descs.each { |ad|
-                @rac.cmd_print "  - "
-                @rac.cmd_msg ad.sub(/\n$/, '').gsub(/\n/, "\n    ")
-            }
-        end
-
-        private
-	def run
-	    goto_task_home
-            return if @rac.running_task(self)
-	    return unless has_actions?
-            @receiver.pre_run(self) if defined? @receiver and @receiver
-	    @block.arity == 0 ? @block.call : @block[self] if @block
-	end
-
-        def action_descs
-            descs = []
-            if defined? @receiver and @receiver
-                descs.concat(@receiver.pre_action_descs)
-            end
-            @block ? descs << action_block_desc : descs
-        end
-
-        def action_block_desc
-            @block.inspect =~ /^#<Proc:[\da-z]+@(.+):(\d+)>$/i
-            fn, ln = $1, $2
-            "Ruby Proc at #{fn.sub(/^#{Regexp.escape @rac.rootdir}\//, '')}:#{ln}"
-        end
-
-	def circular_dep
-	    rac.warn_msg "Circular dependency on task `#{full_name}'."
-	    false
-	end
-    end	# module Node
-
-
-    def self.init_import_nodes__default(rac, *rest)
-        rac.node_factory = DefaultNodeFactory.new
-    end
-
-    class DefaultNodeFactory
-        def new_task(rac, name, pre, blk)
-            Task.new(rac, name, pre, &blk)
-        end
-        def new_file(rac, name, pre, blk)
-            FileTask.new(rac, name, pre, &blk)
-        end
-        def new_dir(rac, name, pre, blk)
-            DirTask.new(rac, name, pre, &blk)
-        end
-        def new_source(rac, name, pre, blk)
-            SourceNode.new(rac, name, pre, &blk)
-        end
-        def new_custom(rac, name, pre, blk)
-            UserTask.new(rac, name, pre, &blk)
-        end
-        def new_auto_subfile(rac, name, pre, blk)
-            AutoSubFileTask.new(rac, name, pre, &blk)
-        end
-    end
-
-    class Task
-	include Node
-
-        attr_accessor :receiver
-
-	def initialize(rac, name, prerequisites = [], &block)
-	    super()
-	    @rac = rac or raise ArgumentError, "rac not given"
-            @name = name or raise ArgumentError, "name not given"
-	    @pre = prerequisites || []
-	    @pre_resolved = false
-	    @block = block
-	    @run = false
-            @receiver = nil
-	end
-
-	def prerequisites
-	    @pre.collect { |pre| pre.to_s }
-	end
-	alias deps prerequisites
-
-	def source
-	    @pre.first.to_s
-	end
-
-	def has_actions?
-            @block or @receiver && @receiver.has_pre_action?
-	end
-
-	def <<(pre)
-	    @pre_resolved = false
-	    @pre << pre
-	end
-
-	def invoked?
-	    !@success.nil?
-	end
-
-	def fail?
-	    @success == false
-	end
-
-	def enhance(deps = nil, &blk)
-	    if deps
-		@pre_resolved = false
-		@pre.concat deps
-	    end
-	    if @block
-		if blk
-		    first_block = @block
-		    @block = lambda { |t|
-			first_block[t]
-			blk[t]
-		    }
-		end
-	    else
-		@block = blk
-	    end
-	end
-
-	def invoke(opt = INVOKE_OPT)
-	    return circular_dep if @run
-	    @run = true
-	    begin
-		return if done?
-		internal_invoke opt
-	    ensure
-		@run = false
-	    end
-	end
-
-	def internal_invoke(opt, ud_init = true)
-	    goto_task_home
-	    update = ud_init || opt[:force]
-	    dep = nil
-	    uf = false
-	    each_dep { |dep|
-		if dep.respond_to? :timestamp
-		    handle_timestamped(dep, opt) && update = true
-		elsif Node === dep
-		    handle_node(dep, opt) && update = true
-		else
-		    dep, uf = handle_non_node(dep, opt)
-		    uf && update = true
-		    dep
-		end
-	    }
-            if @receiver
-                goto_task_home
-                update = true if @receiver.update?(self)
-            end
-	    return update if opt[:needed?]
-            run if update
-	    @success = true
-	    update
-	rescue StandardError => e
-	    @success = false
-	    self.fail(nil, e)
-	end
-	private :internal_invoke
-
-	def handle_node(dep, opt)
-	    dep.invoke opt
-	end
-
-	def handle_timestamped(dep, opt)
-	    dep.invoke opt
-	end
-
-	def handle_non_node(dep, opt)
-	    @rac.err_msg "Unknown task `#{dep}',",
-		"referenced in `#{rantfile.path}', line #{@line_number}!"
-	    self.fail
-	end
-
-	def each_dep
-	    t = nil
-	    if @pre_resolved
-		return @pre.each { |t| yield(t) }
-	    end
-	    my_full_name = full_name
-	    my_project_subdir = project_subdir
-	    @pre.map! { |t|
-		if Node === t
-		    if t.full_name == my_full_name
-			nil
-		    else
-			yield(t)
-			t
-		    end
-		else
-		    t = t.to_s if Symbol === t
-		    if t == my_full_name #TODO
-			nil
-		    else
-			selection = @rac.resolve t,
-					my_project_subdir
-			if selection.empty?
-			    yield(t)
-			else
-			    selection.each { |st| yield(st) }
-			    selection
-			end
-		    end
-		end
-	    }
-            if @pre.kind_of? Rant::FileList
-                @pre.resolve
-            else
-                @pre.flatten!
-                @pre.compact!
-            end
-	    @pre_resolved = true
-	end
-    end	# class Task
-
-    class UserTask < Task
-
-	def initialize(*args)
-	    super
-	    @block = nil
-	    @needed = nil
-            @target_files = nil
-	    yield self if block_given?
-	end
-
-	def act(&block)
-	    @block = block
-	end
-
-	def needed(&block)
-	    @needed = block
-	end
-
-        def file_target?
-            @target_files and @target_files.include? @name
-        end
-
-        def each_target(&block)
-            goto_task_home
-            @target_files.each(&block) if @target_files
-        end
-        
-        def file_target(*args)
-            args.flatten!
-            args << @name if args.empty?
-            if @target_files
-                @target_files.concat(args)
-            else
-                @target_files = args
-            end
-        end
-	
-	def invoke(opt = INVOKE_OPT)
-	    return circular_dep if @run
-	    @run = true
-	    begin
-		return if done?
-		internal_invoke(opt, ud_init_by_needed)
-	    ensure
-		@run = false
-	    end
-	end
-
-	private
-	def ud_init_by_needed
-	    if @needed
-		goto_task_home
-		@needed.arity == 0 ? @needed.call : @needed[self]
-	    end
-	end
-    end	# class UserTask
-
-    class FileTask < Task
-
-	def initialize(*args)
-	    super
-	    @ts = T0
-	end
-
-        def file_target?
-            true
-        end
-
-	def invoke(opt = INVOKE_OPT)
-	    return circular_dep if @run
-	    @run = true
-	    begin
-		return if done?
-		goto_task_home
-		if File.exist? @name
-		    @ts = File.mtime @name
-		    internal_invoke opt, false
-		else
-		    @ts = T0
-		    internal_invoke opt, true
-		end
-	    ensure
-		@run = false
-	    end
-	end
-
-	def timestamp(opt = INVOKE_OPT)
-	    File.exist?(@name) ? File.mtime(@name) : T0
-	end
-
-        def handle_node(dep, opt)
-            return true if dep.file_target? && dep.invoke(opt)
-	    if File.exist? dep.name
-                File.mtime(dep.name) > @ts
-            elsif !dep.file_target?
-		@rac.err_msg @rac.pos_text(rantfile.path, line_number),
-		    "in prerequisites: no such file: `#{dep.full_name}'"
-		self.fail
-	    end
-        end
-
-	def handle_timestamped(dep, opt)
-	    return true if dep.invoke opt
-	    dep.timestamp(opt) > @ts
-	end
-
-	def handle_non_node(dep, opt)
-            goto_task_home # !!??
-	    unless File.exist? dep
-		@rac.err_msg @rac.pos_text(rantfile.path, line_number),
-		    "in prerequisites: no such file or task: `#{dep}'"
-		self.fail
-	    end
-	    [dep, File.mtime(dep) > @ts]
-	end
-
-	def each_target
-	    goto_task_home
-	    yield name
-	end
-    end	# class FileTask
-
-    module AutoInvokeDirNode
-	private
-	def run
-            goto_task_home
-            return if @rac.running_task(self)
-	    dir = File.dirname(name)
-            @rac.build dir unless dir == "." || dir == "/"
-            return unless @block
-            @block.arity == 0 ? @block.call : @block[self]
-	end
-    end
-
-    class AutoSubFileTask < FileTask
-        include AutoInvokeDirNode
-    end
-
-    class DirTask < Task
-
-	def initialize(*args)
-	    super
-	    @ts = T0
-	    @isdir = nil
-	end
-
-	def invoke(opt = INVOKE_OPT)
-	    return circular_dep if @run
-	    @run = true
-	    begin
-		return if done?
-		goto_task_home
-		@isdir = test(?d, @name)
-		if @isdir
-		    @ts = @block ? test(?M, @name) : Time.now
-		    internal_invoke opt, false
-		else
-		    @ts = T0
-		    internal_invoke opt, true
-		end
-	    ensure
-		@run = false
-	    end
-	end
-
-        def file_target?
-            true
-        end
-
-        def handle_node(dep, opt)
-            return true if dep.file_target? && dep.invoke(opt)
-	    if File.exist? dep.name
-                File.mtime(dep.name) > @ts
-            elsif !dep.file_target?
-		@rac.err_msg @rac.pos_text(rantfile.path, line_number),
-		    "in prerequisites: no such file: `#{dep.full_name}'"
-		self.fail
-	    end
-        end
-
-	def handle_timestamped(dep, opt)
-	    return @block if dep.invoke opt
-	    @block && dep.timestamp(opt) > @ts
-	end
-
-	def handle_non_node(dep, opt)
-            goto_task_home
-	    unless File.exist? dep
-		@rac.err_msg @rac.pos_text(rantfile.path, line_number),
-		    "in prerequisites: no such file or task: `#{dep}'"
-		self.fail
-	    end
-	    [dep, @block && File.mtime(dep) > @ts]
-	end
-
-	def run
-            return if @rac.running_task(self)
-	    @rac.sys.mkdir @name unless @isdir
-	    if @block
-		@block.arity == 0 ? @block.call : @block[self]
-		goto_task_home
-		@rac.sys.touch @name
-	    end
-	end
-
-	def each_target
-	    goto_task_home
-	    yield name
-	end
-    end	# class DirTask
-
-    class SourceNode
-	include Node
-	def initialize(rac, name, prerequisites = [])
-	    super()
-	    @rac = rac
-	    @name = name or raise ArgumentError, "name not given"
-	    @pre = prerequisites
-	    @run = false
-	    @ts = nil
-	end
-	def prerequisites
-	    @pre
-	end
-	def timestamp(opt = INVOKE_OPT)
-	    return @ts if @ts
-	    goto_task_home
-	    if File.exist?(@name)
-		@ts = File.mtime @name
-	    else
-		rac.abort_at(ch, "SourceNode: no such file -- #@name")
-	    end
-	    sd = project_subdir
-	    @pre.each { |f|
-		nodes = rac.resolve f, sd
-		if nodes.empty?
-		    if File.exist? f
-			mtime = File.mtime f
-			@ts = mtime if mtime > @ts
-		    else
-			rac.abort_at(ch, 
-			    "SourceNode: no such file -- #{f}")
-		    end
-		else
-		    nodes.each { |node|
-                        node.invoke(opt)
-			if node.respond_to? :timestamp
-			    node_ts = node.timestamp(opt)
-                            goto_task_home
-			    @ts = node_ts if node_ts > @ts
-			else
-			    rac.abort_at(ch, 
-				"SourceNode can't depend on #{node.name}")
-			end
-		    }
-		end
-	    }
-	    @ts
-	end
-	def invoke(opt = INVOKE_OPT)
-	    false
-	end
-        def related_sources
-            @pre
-        end
-    end # class SourceNode
-
-    module Generators
-        class Task
-	    def self.rant_gen(rac, ch, args, &block)
-		unless args.size == 1
-		    rac.abort("Task takes only one argument " +
-			"which has to be like one given to the " +
-			"`task' function")
-		end
-		rac.prepare_task(args.first, nil, ch) { |name,pre,blk|
-		    rac.node_factory.new_custom(rac, name, pre, block)
-		}
-	    end
-        end
-        class Directory
-	    def self.rant_gen(rac, ch, args, &block)
-		case args.size
-		when 1
-		    name, pre = rac.normalize_task_arg(args.first, ch)
-		    self.task(rac, ch, name, pre, &block)
-		when 2
-		    basedir = args.shift
-		    if basedir.respond_to? :to_str
-			basedir = basedir.to_str
-		    else
-			rac.abort_at(ch,
-			    "Directory: basedir argument has to be a string.")
-		    end
-		    name, pre = rac.normalize_task_arg(args.first, ch)
-		    self.task(rac, ch, name, pre, basedir, &block)
-		else
-		    rac.abort_at(ch, "Directory takes one argument, " +
-			"which should be like one given to the `task' command.")
-		end
-	    end
-
-	    def self.task(rac, ch, name, prerequisites=[], basedir=nil, &block)
-		dirs = ::Rant::Sys.split_all(name)
-		if dirs.empty?
-		    rac.abort_at(ch,
-			"Not a valid directory name: `#{name}'")
-		end
-		path = basedir
-		last_task = nil
-		task_block = nil
-		desc_for_last = rac.pop_desc
-		dirs.each { |dir|
-                    pre = [path]
-                    pre.compact!
-		    if dir.equal?(dirs.last)
-			rac.cx.desc desc_for_last
-
-                        dp = prerequisites.dup
-                        pre.each { |elem| dp << elem }
-                        pre = dp
-
-			task_block = block
-		    end
-		    path = path.nil? ? dir : File.join(path, dir)
-		    last_task = rac.prepare_task({:__caller__ => ch,
-			    path => pre}, task_block) { |name,pre,blk|
-			rac.node_factory.new_dir(rac, name, pre, blk)
-		    }
-		}
-		last_task
-	    end
-        end # class Directory
-        class SourceNode
-            def self.rant_gen(rac, ch, args)
-                unless args.size == 1
-                    rac.abort_at(ch, "SourceNode takes one argument.")
-                end
-                if block_given?
-                    rac.abort_at(ch, "SourceNode doesn't take a block.")
-                end
-                rac.prepare_task(args.first, nil, ch) { |name, pre, blk|
-                    rac.node_factory.new_source(rac, name, pre, blk)
-                }
-            end
-        end
-	class Rule
-	    def self.rant_gen(rac, ch, args, &block)
-		unless args.size == 1
-		    rac.abort_at(ch, "Rule takes only one argument.")
-		end
-                rac.abort_at(ch, "Rule: block required.") unless block
-		arg = args.first
-		target = nil
-		src_arg = nil
-		if Symbol === arg
-		    target = ".#{arg}"
-		elsif arg.respond_to? :to_str
-		    target = arg.to_str
-		elsif Regexp === arg
-		    target = arg
-		elsif Hash === arg && arg.size == 1
-		    arg.each_pair { |target, src_arg| }
-		    src_arg = src_arg.to_str if src_arg.respond_to? :to_str
-		    target = target.to_str if target.respond_to? :to_str
-		    src_arg = ".#{src_arg}" if Symbol === src_arg
-		    target = ".#{target}" if Symbol === target
-		else
-		    rac.abort_at(ch, "Rule argument " +
-			"has to be a hash with one key-value pair.")
-		end
-		esc_target = nil
-		target_rx = case target
-                    when String
-                        esc_target = Regexp.escape(target)
-                        /#{esc_target}$/
-                    when Regexp
-                        target
-                    else
-		    rac.abort_at(ch, "rule target has " +
-			"to be a string or regular expression")
-		end
-		src_proc = case src_arg
-                    when String, Array
-                        unless String === target
-                            rac.abort(ch, "rule target has to be " +
-                                  "a string if source is a string")
-                        end
-                        if src_arg.kind_of? String
-                            lambda { |name|
-                                name.sub(/#{esc_target}$/, src_arg)
-                            }
-                        else
-                            lambda { |name|
-                                src_arg.collect { |s_src|
-                                    s_src = ".#{s_src}" if Symbol === s_src
-                                    name.sub(/#{esc_target}$/, s_src)
-                                }
-                            }
-                        end
-                    when Proc; src_arg
-                    when nil; lambda { |name| [] }
-                    else
-                        rac.abort_at(ch, "rule source has to be a " +
-                            "String, Array or Proc")
-                    end
-                rac.resolve_hooks <<
-                    (block.arity == 2 ? Hook : FileHook).new(
-                           rac, ch, target_rx, src_proc, block)
-		nil
-	    end
-            class Hook
-                attr_accessor :target_rx
-                def initialize(rant, ch, target_rx, src_proc, block)
-                    @rant = rant
-                    @ch = ch
-                    @target_rx = target_rx
-                    @src_proc = src_proc
-                    @block = block
-                end
-                def call(target, rel_project_dir)
-		    if @target_rx =~ target
-                        have_src = true
-                        src = @src_proc[target]
-                        if src.respond_to? :to_ary
-                            have_src = src.to_ary.all? { |s|
-                                have_src?(rel_project_dir, s)
-                            }
-                        else
-                            have_src = have_src?(rel_project_dir, src)
-                        end
-                        if have_src
-                            create_nodes(rel_project_dir, target, src)
-                        end
-                    end
-                end
-                alias [] call
-                private
-                def have_src?(rel_project_dir, name)
-                    return true unless
-                        @rant.rec_save_resolve(name, self, rel_project_dir).empty?
-                    test(?e, @rant.abs_path(rel_project_dir, name))
-                end
-                def create_nodes(rel_project_dir, target, deps)
-                    @rant.goto_project_dir rel_project_dir
-                    case nodes = @block[target, deps]
-                    when Array; nodes
-                    when Node; [nodes]
-                    else
-                        @rant.abort_at(@ch, "Block has to " +
-                            "return Node or array of Nodes.")
-                    end
-                end
-            end
-            class FileHook < Hook
-                private
-                def have_src?(rel_project_dir, name)
-                    test(?e, @rant.abs_path(rel_project_dir, name)) or
-                        @rant.rec_save_resolve(name, self, rel_project_dir
-                            ).any? { |t| t.file_target? }
-                end
-                def create_nodes(rel_project_dir, target, deps)
-                    @rant.goto_project_dir rel_project_dir
-                    t = @rant.file(:__caller__ => @ch,
-                            target => deps, &@block)
-                    [t]
-                end
-            end
-	end # class Rule
-	class Action
-	    def self.rant_gen(rac, ch, args, &block)
-                case args.size
-                when 0
-                    unless (rac[:tasks] || rac[:stop_after_load])
-                        yield
-                    end
-                when 1
-                    rx = args.first
-                    unless rx.kind_of? Regexp
-                        rac.abort_at(ch, "Action: argument has " +
-                            "to be a regular expression.")
-                    end
-                    rac.resolve_hooks << self.new(rac, block, rx)
-                    nil
-                else
-                    rac.abort_at(ch, "Action: too many arguments.")
-                end
-	    end
-            def initialize(rant, block, rx)
-                @rant = rant
-                @subdir = @rant.current_subdir
-                @block = block
-                @rx = rx
-            end
-            def call(target, rel_project_dir)
-                if target =~ @rx
-                    @rant.resolve_hooks.delete(self)
-                    @rant.goto_project_dir @subdir
-                    @block.call
-                    @rant.resolve(target, rel_project_dir)
-                end
-            end
-            alias [] call
-	end
-    end	# module Generators
-end # module Rant
-
-Rant::MAIN_OBJECT = self
-
-class String
-    alias sub_ext _rant_sub_ext
-    def to_rant_target
-        self
-    end
-end
-
-module Rant::Lib
-    def parse_caller_elem(elem)
-        return { :file => "", :ln => 0 } unless elem
-        if elem =~ /^(.+):(\d+)(?::|$)/
-            { :file => $1, :ln => $2.to_i }
-        else
-            $stderr.puts "parse_caller_elem: #{elem.inspect}"
-            { :file => elem, :ln => 0 }
-        end
-        
-    end
-    module_function :parse_caller_elem
-end # module Lib
-
-module Rant::Console
-    RANT_PREFIX		= "rant: "
-    ERROR_PREFIX	= "[ERROR] "
-    WARN_PREFIX		= "[WARNING] "
-    def msg_prefix
-	if defined? @msg_prefix and @msg_prefix
-	    @msg_prefix
-	else
-	    RANT_PREFIX
-	end
-    end
-    def msg(*text)
-        pre = msg_prefix
-        $stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}"
-    end
-    def vmsg(importance, *text)
-        msg(*text) if verbose >= importance
-    end
-    def err_msg(*text)
-        pre = msg_prefix + ERROR_PREFIX
-        $stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}"
-    end
-    def warn_msg(*text)
-        pre = msg_prefix + WARN_PREFIX
-        $stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}"
-    end
-    def ask_yes_no text
-        $stderr.print msg_prefix + text + " [y|n] "
-        case $stdin.readline
-        when /y|yes/i; true
-        when /n|no/i; false
-        else
-            $stderr.puts(' ' * msg_prefix.length +
-                "Please answer with `yes' or `no'")
-            ask_yes_no text
-        end
-    end
-    def prompt text
-        $stderr.print msg_prefix + text
-        input = $stdin.readline
-	input ? input.chomp : input
-    end
-    def option_listing opts
-	rs = ""
-	opts.each { |lopt, *opt_a|
-	    if opt_a.size == 2
-		mode, desc = opt_a
-	    else
-		sopt, mode, desc = opt_a
-	    end
-	    next unless desc	# "private" option
-	    optstr = ""
-	    arg = nil
-	    if mode != GetoptLong::NO_ARGUMENT
-		if desc =~ /(\b[A-Z_]{2,}\b)/
-		    arg = $1
-		end
-	    end
-	    if lopt
-		optstr << lopt
-		if arg
-		    optstr << " " << arg
-		end
-		optstr = optstr.ljust(30)
-	    end
-	    if sopt
-		optstr << "   " unless optstr.empty?
-		optstr << sopt
-		if arg
-		    optstr << " " << arg
-		end
-	    end
-	    rs << "  #{optstr}\n"
-	    rs << "      #{desc.split("\n").join("\n      ")}\n"
-	}
-	rs
-    end
-    extend self
-end # module Rant::Console
-
-module RantContext
-    include Rant::Generators
-
-    Env = Rant::Env
-    FileList = Rant::FileList
-
-    def task(targ, &block)
-	rant.task(targ, &block)
-    end
-
-    def file(targ, &block)
-	rant.file(targ, &block)
-    end
-
-    def enhance(targ, &block)
-	rant.enhance(targ, &block)
-    end
-
-    def desc(*args)
-	rant.desc(*args)
-    end
-
-    def gen(*args, &block)
-	rant.gen(*args, &block)
-    end
-
-    def import(*args, &block)
-	rant.import(*args, &block)
-    end
-
-    def plugin(*args, &block)
-	rant.plugin(*args, &block)
-    end
-
-    def subdirs(*args)
-	rant.subdirs(*args)
-    end
-
-    def source(opt, rantfile = nil)
-	rant.source(opt, rantfile)
-    end
-
-    def sys(*args, &block)
-	rant.sys(*args, &block)
-    end
-
-    def var(*args, &block)
-	rant.var(*args, &block)
-    end
-
-    def make(*args, &block)
-        rant.make(*args, &block)
-    end
-
-end	# module RantContext
-
-class RantAppContext
-    include RantContext
-
-    def initialize(app)
-	@__rant__ = app
-    end
-
-    def rant
-        @__rant__
-    end
-
-    def method_missing(sym, *args)
-	Rant::MAIN_OBJECT.send(sym, *args)
-    rescue NoMethodError
-	raise NameError, "NameError: undefined local " +
-	    "variable or method `#{sym}' for main:Object", caller
-    end
-end
-
-module Rant
-
-    @__rant__ = nil
-    class << self
-
-	def run(first_arg=nil, *other_args)
-	    other_args = other_args.flatten
-	    args = first_arg.nil? ? ARGV.dup : ([first_arg] + other_args)
-	    if rant && !rant.run?
-		rant.run(args.flatten)
-	    else
-                @__rant__ = Rant::RantApp.new
-		rant.run(args)
-	    end
-	end
-
-	def rant
-	    @__rant__
-	end
-    end
-
-end # module Rant
-
-class Rant::RantApp
-    include Rant::Console
-
-    class AutoLoadNodeFactory
-        def initialize(rant)
-            @rant = rant
-        end
-        def method_missing(sym, *args, &block)
-            @rant.import "nodes/default"
-            @rant.node_factory.send(sym, *args, &block)
-        end
-    end
-
-
-
-    OPTIONS	= [
-	[ "--help",	"-h",	GetoptLong::NO_ARGUMENT,
-	    "Print this help and exit."				],
-	[ "--version",	"-V",	GetoptLong::NO_ARGUMENT,
-	    "Print version of Rant and exit."			],
-	[ "--verbose",	"-v",	GetoptLong::NO_ARGUMENT,
-	    "Print more messages to stderr."			],
-	[ "--quiet",	"-q",	GetoptLong::NO_ARGUMENT,
-	    "Don't print commands."			        ],
-	[ "--err-commands",	GetoptLong::NO_ARGUMENT,
-	    "Print failed commands and their exit status."	],
-	[ "--directory","-C",	GetoptLong::REQUIRED_ARGUMENT,
-	    "Run rant in DIRECTORY."				],
-        [ "--cd-parent","-c",   GetoptLong::NO_ARGUMENT,
-            "Run rant in parent directory with Rantfile."       ],
-        [ "--look-up",  "-u",   GetoptLong::NO_ARGUMENT,
-            "Look in parent directories for root Rantfile."     ],
-	[ "--rantfile",	"-f",	GetoptLong::REQUIRED_ARGUMENT,
-	    "Process RANTFILE instead of standard rantfiles.\n" +
-	    "Multiple files may be specified with this option." ],
-	[ "--force-run","-a",	GetoptLong::REQUIRED_ARGUMENT,
-	    "Force rebuild of TARGET and all dependencies."     ],
-        [ "--dry-run",  "-n",   GetoptLong::NO_ARGUMENT,
-            "Print info instead of actually executing actions."  ],
-	[ "--tasks",	"-T",	GetoptLong::NO_ARGUMENT,
-	    "Show a list of all described tasks and exit."	],
-	
-
-        [ "--import",   "-i",   GetoptLong::REQUIRED_ARGUMENT, nil ],
-	[ "--stop-after-load",	GetoptLong::NO_ARGUMENT, nil	],
-	[ "--trace-abort",	GetoptLong::NO_ARGUMENT, nil	],
-    ]
-
-    ROOT_DIR_ID = "@"
-    ESCAPE_ID = "\\"
-
-    attr_reader :args
-    attr_reader :rantfiles
-    attr_reader :force_targets
-    attr_reader :plugins
-    attr_reader :context
-    alias cx context
-    attr_reader :tasks
-    attr_reader :imports
-    attr_reader :current_subdir
-    attr_reader :resolve_hooks
-    attr_reader :rootdir
-
-    attr_accessor :node_factory
-
-    def initialize
-	@args = []
-	@context = RantAppContext.new(self)
-	@sys = ::Rant::SysObject.new(self)
-	@rantfiles = []
-	@tasks = {}
-	@opts = {
-	    :verbose        => 0,
-	    :quiet          => false,
-	}
-        @rootdir = Dir.pwd      # root directory of project
-	@arg_rantfiles = []	# rantfiles given in args
-	@arg_targets = []	# targets given in args
-	@force_targets = []     # targets given with -a option
-	@run = false            # run method was called at least once
-	@done = false           # run method was successful
-	@plugins = []
-	@var = Rant::RantVar::Space.new
-	@var.query :ignore, :AutoList, []
-	@imports = []
-
-	@task_desc = nil
-        @last_build_subdir = ""
-
-	@current_subdir = ""
-	@resolve_hooks = []
-
-        @node_factory = AutoLoadNodeFactory.new(self)
-    end
-
-    def [](opt)
-	@opts[opt]
-    end
-
-    def []=(opt, val)
-        @opts[opt] = val
-    end
-
-    def expand_path(subdir, path)
-	case path
-	when nil;	subdir.dup
-	when "";	subdir.dup
-	when /^@/;	path.sub(/^@/, '')
-	else
-            path = path.sub(/^\\(?=@)/, '')
-	    if subdir.empty?
-		path
-	    else
-		File.join(subdir, path)
-	    end
-	end
-    end
-    def resolve_root_ref(path)
-        return File.join(@rootdir, path[1..-1]) if path =~ /^@/
-        path.sub(/^\\(?=@)/, '')
-    end
-    def project_to_fs_path(path)
-	sub = expand_path(@current_subdir, path)
-	sub.empty? ? @rootdir : File.join(@rootdir, sub)
-    end
-    def abs_path(subdir, fn)
-        return fn if Rant::Sys.absolute_path?(fn)
-        path = File.join(@rootdir, subdir, fn)
-        path.gsub!(%r{/+}, "/")
-        path.sub!(%r{/$}, "") if path.length > 1
-        path
-    end
-    def goto(dir)
-        goto_project_dir(expand_path(@current_subdir, dir))
-    end
-    def goto_project_dir(dir='')
-        @current_subdir = dir
-        abs_path = @current_subdir.empty? ?
-            @rootdir : File.join(@rootdir, @current_subdir)
-	unless Dir.pwd == abs_path
-	    Dir.chdir abs_path
-	    vmsg 1, "in #{abs_path}"
-	end
-    end
-
-    def run?
-	@run
-    end
-
-    def done?
-	@done
-    end
-
-    def run(*args)
-	@run = true
-	@args.concat(args.flatten)
-	orig_pwd = @rootdir = Dir.pwd
-	process_args
-        Dir.chdir(@rootdir) rescue abort $!.message
-	load_rantfiles
-
-	raise Rant::RantDoneException if @opts[:stop_after_load]
-
-	@plugins.each { |plugin| plugin.rant_start }
-	if @opts[:tasks]
-	    show_descriptions
-	    raise Rant::RantDoneException
-	end
-	run_tasks
-	raise Rant::RantDoneException
-    rescue Rant::RantDoneException
-	@done = true
-	@plugins.each { |plugin| plugin.rant_done }
-	return 0
-    rescue Rant::RantAbortException
-	$stderr.puts "rant aborted!"
-	return 1
-    rescue Exception => e
-	ch = get_ch_from_backtrace(e.backtrace)
-	if ch && !@opts[:trace_abort]
-	    err_msg(pos_text(ch[:file], ch[:ln]), e.message)
-	else
-	    err_msg e.message, e.backtrace[0..4]
-	end
-	$stderr.puts "rant aborted!"
-	return 1
-    ensure
-        Dir.chdir @rootdir if test ?d, @rootdir
-        hooks = var._get("__at_return__")
-        hooks.each { |hook| hook.call } if hooks
-	@plugins.each { |plugin| plugin.rant_plugin_stop }
-	@plugins.each { |plugin| plugin.rant_quit }
-        Dir.chdir orig_pwd
-    end
-
-
-    def desc(*args)
-	if args.empty? || (args.size == 1 && args.first.nil?)
-	    @task_desc = nil
-	else
-	    @task_desc = args.join("\n")
-	end
-    end
-
-    def task(targ, &block)
-	prepare_task(targ, block) { |name,pre,blk|
-            @node_factory.new_task(self, name, pre, blk)
-	}
-    end
-
-    def file(targ, &block)
-	prepare_task(targ, block) { |name,pre,blk|
-            @node_factory.new_file(self, name, pre, blk)
-	}
-    end
-
-    def gen(*args, &block)
-	ch = Rant::Lib::parse_caller_elem(caller[1])
-	generator = args.shift
-	unless generator.respond_to? :rant_gen
-	    abort_at(ch,
-		"gen: First argument has to be a task-generator.")
-	end
-	generator.rant_gen(self, ch, args, &block)
-    end
-
-    def import(*args, &block)
-	ch = Rant::Lib::parse_caller_elem(caller[1])
-	if block
-	    warn_msg pos_text(ch[:file], ch[:ln]),
-		"import: ignoring block"
-	end
-	args.flatten.each { |arg|
-	    unless String === arg
-                abort_at(ch, "import: only strings allowed as arguments")
-	    end
-	    unless @imports.include? arg
-		unless Rant::CODE_IMPORTS.include? arg
-		    begin
-			vmsg 2, "import #{arg}"
-			require "rant/import/#{arg}"
-		    rescue LoadError => e
-			abort_at(ch, "No such import - #{arg}")
-		    end
-		    Rant::CODE_IMPORTS << arg.dup
-		end
-                init_msg = "init_import_#{arg.gsub(/[^\w]/, '__')}"
-                Rant.send init_msg, self if Rant.respond_to? init_msg
-		@imports << arg.dup
-	    end
-	}
-    end
-
-    def plugin(*args, &block)
-	clr = caller[1]
-	ch = Rant::Lib::parse_caller_elem(clr)
-	name = nil
-	pre = []
-	ln = ch[:ln] || 0
-	file = ch[:file]
-
-	pl_name = args.shift
-	pl_name = pl_name.to_str if pl_name.respond_to? :to_str
-	pl_name = pl_name.to_s if pl_name.is_a? Symbol
-	unless pl_name.is_a? String
-	    abort(pos_text(file, ln),
-		"Plugin name has to be a string or symbol.")
-	end
-	lc_pl_name = pl_name.downcase
-	import_name = "plugin/#{lc_pl_name}"
-	unless Rant::CODE_IMPORTS.include? import_name
-	    begin
-		require "rant/plugin/#{lc_pl_name}"
-		Rant::CODE_IMPORTS << import_name
-	    rescue LoadError
-		abort(pos_text(file, ln),
-		    "no such plugin library -- #{lc_pl_name}")
-	    end
-	end
-	pl_class = nil
-	begin
-	    pl_class = ::Rant::Plugin.const_get(pl_name)
-	rescue NameError, ArgumentError
-	    abort(pos_text(file, ln),
-		"no such plugin -- #{pl_name}")
-	end
-
-	plugin = pl_class.rant_plugin_new(self, ch, *args, &block)
-	@plugins << plugin
-	vmsg 2, "Plugin `#{plugin.rant_plugin_name}' registered."
-	plugin.rant_plugin_init
-	plugin
-    end
-
-    def enhance(targ, &block)
-	prepare_task(targ, block) { |name,pre,blk|
-	    t = resolve(name).last
-	    if t
-		unless t.respond_to? :enhance
-		    abort("Can't enhance task `#{name}'")
-		end
-		t.enhance(pre, &blk)
-		return t
-	    end
-	    warn_msg "enhance \"#{name}\": no such task",
-		"Generating a new file task with the given name."
-            @node_factory.new_file(self, name, pre, blk)
-	}
-    end
-
-    def source(opt, rantfile = nil)
-	unless rantfile
-	    rantfile = opt
-	    opt = nil
-	end
-	make_rf = opt != :n && opt != :now
-	rf, is_new = rantfile_for_path(rantfile)
-	return false unless is_new
-	make rantfile if make_rf
-	unless File.exist? rf.path
-	    abort("source: No such file -- #{rantfile}")
-	end
-
-	load_file rf
-    end
-
-    def subdirs(*args)
-	args.flatten!
-	ch = Rant::Lib::parse_caller_elem(caller[1])
-	args.each { |arg|
-	    if arg.respond_to? :to_str
-		arg = arg.to_str
-	    else
-		abort_at(ch, "subdirs: arguments must be strings")
-	    end
-	    loaded = false
-	    prev_subdir = @current_subdir
-	    begin
-		goto arg
-                if test(?f, Rant::SUB_RANTFILE)
-                    path = Rant::SUB_RANTFILE
-                else
-                    path = rantfile_in_dir
-                end
-                if path
-                    if defined? @initial_subdir and
-                            @initial_subdir == @current_subdir
-                        rf, is_new = rantfile_for_path(path, false)
-                        @rantfiles.unshift rf if is_new
-                    else
-                        rf, is_new = rantfile_for_path(path)
-                    end
-		    load_file rf if is_new
-                elsif !@opts[:no_warn_subdir]
-                    warn_msg(pos_text(ch[:file], ch[:ln]),
-                        "subdirs: No Rantfile in subdir `#{arg}'.")
-                end
-	    ensure
-		goto_project_dir prev_subdir
-	    end
-	}
-    rescue SystemCallError => e
-	abort_at(ch, "subdirs: " + e.message)
-    end
-
-    def sys(*args, &block)
-	args.empty? ? @sys : @sys.sh(*args, &block)
-    end
-
-    def var(*args, &block)
-	args.empty? ? @var : @var.query(*args, &block)
-    end
-
-    def pop_desc
-	td = @task_desc
-	@task_desc = nil
-	td
-    end
-
-    def abort(*msg)
-	err_msg(msg) unless msg.empty?
-	$stderr.puts caller if @opts[:trace_abort]
-	raise Rant::RantAbortException
-    end
-
-    def abort_at(ch, *msg)
-	err_msg(pos_text(ch[:file], ch[:ln]), msg)
-	$stderr.puts caller if @opts[:trace_abort]
-	raise Rant::RantAbortException
-    end
-
-    def show_help
-	puts "rant [-f Rantfile] [Options] [targets]"
-	puts
-	puts "Options are:"
-	print option_listing(OPTIONS)
-    end
-
-    def show_descriptions
-	tlist = select_tasks { |t| t.description }
-	def_target = target_list.first
-	if tlist.empty?
-	    puts "rant         # => " + list_task_names(
-		resolve(def_target)).join(', ')
-	    msg "No described tasks."
-	    return
-	end
-	prefix = "rant "
-	infix = "  # "
-        name_length = (tlist.map{ |t| t.to_s.length } << 7).max
-	cmd_length = prefix.length + name_length
-	unless tlist.first.to_s == def_target
-	    defaults = list_task_names(
-		resolve(def_target)).join(', ')
-	    puts "#{prefix}#{' ' * name_length}#{infix}=> #{defaults}"
-	end
-	tlist.each { |t|
-	    print(prefix + t.to_s.ljust(name_length) + infix)
-	    dt = t.description.sub(/\s+$/, "")
-	    puts dt.gsub(/\n/, "\n" + ' ' * cmd_length + infix + "  ")
-	}
-	true
-    end
-
-    def list_task_names(*tasks)
-	rsl = []
-	tasks.flatten.each { |t|
-	    if t.respond_to?(:has_actions?) && t.has_actions?
-		rsl << t
-	    elsif t.respond_to? :prerequisites
-		if t.prerequisites.empty?
-		    rsl << t
-		else
-                    t.prerequisites.each { |pre|
-                        rsl.concat(list_task_names(
-                            resolve(pre, t.project_subdir)))
-                    }
-		end
-	    else
-		rsl << t
-	    end
-	}
-	rsl
-    end
-    private :list_task_names
-
-    def verbose
-	@opts[:verbose]
-    end
-
-    def quiet?
-	@opts[:quiet]
-    end
-
-    def pos_text(file, ln)
-	t = "in file `#{file}'"
-        t << ", line #{ln}" if ln && ln > 0
-	t << ": "
-    end
-
-    def cmd_msg(cmd)
-	puts cmd unless quiet?
-    end
-
-    def cmd_print(text)
-        print text unless quiet?
-        $stdout.flush
-    end
-
-    def cmd_targets
-	@force_targets + @arg_targets
-    end
-
-    def running_task(task)
-        if @current_subdir != @last_build_subdir
-            cmd_msg "(in #{@current_subdir.empty? ?
-                @rootdir : @current_subdir})"
-            @last_build_subdir = @current_subdir
-        end
-        if @opts[:dry_run]
-            task.dry_run
-            true
-        end
-    end
-
-    private
-    def have_any_task?
-        !@tasks.empty?
-    end
-
-    def target_list
-	if !have_any_task? && @resolve_hooks.empty?
-	    abort("No tasks defined for this rant application!")
-	end
-
-	target_list = @force_targets + @arg_targets
-	if target_list.empty?
-	    def_tasks = resolve "default"
-	    unless def_tasks.empty?
-		target_list << "default"
-	    else
-		@rantfiles.each { |f|
-                    first = f.tasks.first
-		    if first
-                        target_list << first.reference_name
-			break
-		    end
-		}
-	    end
-	end
-	target_list
-    end
-
-    def run_tasks
-	target_list.each { |target|
-	    if build(target) == 0
-		abort("Don't know how to make `#{target}'.")
-	    end
-        }
-    end
-
-    def make(target, *args, &block)
-        ch = nil
-        if target.respond_to? :to_hash
-            targ = target.to_hash
-            ch = Rant::Lib.parse_caller_elem(caller[1])
-            abort_at(ch, "make: too many arguments") unless args.empty?
-            tn = nil
-            prepare_task(targ, block, ch) { |name,pre,blk|
-                tn = name
-                @node_factory.new_file(self, name, pre, blk)
-            }
-            build(tn)
-        elsif target.respond_to? :to_rant_target
-            rt = target.to_rant_target
-            opt = args.shift
-            unless args.empty?
-                ch ||= Rant::Lib.parse_caller_elem(caller[1])
-                abort_at(ch, "make: too many arguments")
-            end
-            if block
-                ch ||= Rant::Lib.parse_caller_elem(caller[1])
-                prepare_task(rt, block, ch) { |name,pre,blk|
-                    @node_factory.new_file(self, name, pre, blk)
-                }
-                build(rt)
-            else
-                build(rt, opt||{})
-            end
-        elsif target.respond_to? :rant_gen
-            ch = Rant::Lib.parse_caller_elem(caller[1])
-            rv = target.rant_gen(self, ch, args, &block)
-            unless rv.respond_to? :to_rant_target
-                abort_at(ch, "make: invalid generator return value")
-            end
-            build(rv.to_rant_target)
-            rv
-        else
-            ch = Rant::Lib.parse_caller_elem(caller[1])
-            abort_at(ch,
-                "make: generator or target as first argument required.")
-        end
-    end
-    public :make
-
-    def build(target, opt = {})
-	opt[:force] = true if @force_targets.delete(target)
-        opt[:dry_run] = @opts[:dry_run]
-	matching_tasks = 0
-	old_subdir = @current_subdir
-	old_pwd = Dir.pwd
-	resolve(target).each { |t|
-            unless opt[:type] == :file && !t.file_target?
-                matching_tasks += 1
-                begin
-                    t.invoke(opt) 
-                rescue Rant::TaskFail => e
-                    err_task_fail(e)
-                    abort
-                end
-            end
-	}
-	@current_subdir = old_subdir
-	Dir.chdir old_pwd
-	matching_tasks
-    end
-    public :build
-
-    def resolve(task_name, rel_project_dir = @current_subdir)
-	s = @tasks[expand_path(rel_project_dir, task_name)]
-	case s
-	when nil
-	    @resolve_hooks.each { |s|
-		s = s[task_name, rel_project_dir]
-		return s if s
-	    }
-	    []
-	when Rant::Node; [s]
-	else # assuming list of tasks
-	    s
-	end
-    end
-    public :resolve
-
-    def rec_save_resolve(task_name, excl_hook, rel_project_dir = @current_subdir)
-	s = @tasks[expand_path(rel_project_dir, task_name)]
-	case s
-	when nil
-	    @resolve_hooks.each { |s|
-                next if s == excl_hook
-		s = s[task_name, rel_project_dir]
-		return s if s
-	    }
-	    []
-	when Rant::Node; [s]
-	else
-	    s
-	end
-    end
-    public :rec_save_resolve
-
-    def at_resolve(&block)
-	@resolve_hooks << block if block
-    end
-    public :at_resolve
-
-    def at_return(&block)
-        hooks = var._get("__at_return__")
-        if hooks
-            hooks << block
-        else
-            var._set("__at_return__", [block])
-        end
-    end
-    public :at_return
-
-    def select_tasks
-	selection = []
-	@rantfiles.each { |rf|
-	    rf.tasks.each { |t|
-		selection << t if yield t
-	    }
-	}
-	selection
-    end
-    public :select_tasks
-
-    def load_rantfiles
-        unless @arg_rantfiles.empty?
-            @arg_rantfiles.each { |fn|
-                if test(?f, fn)
-                    rf, is_new = rantfile_for_path(fn)
-                    load_file rf if is_new
-                else
-                    abort "No such file -- #{fn}"
-                end
-            }
-            return
-        end
-        return if have_any_task?
-        fn = rantfile_in_dir
-        if @opts[:cd_parent]
-            old_root = @rootdir
-            until fn or @rootdir == "/"
-                @rootdir = File.dirname(@rootdir)
-                fn = rantfile_in_dir(@rootdir)
-            end
-            if @rootdir != old_root and fn
-                Dir.chdir @rootdir
-                cmd_msg "(in #@rootdir)" 
-            end
-        end
-        if fn
-            rf, is_new = rantfile_for_path(fn)
-            load_file rf if is_new
-            return
-        end
-        have_sub_rantfile = test(?f, Rant::SUB_RANTFILE)
-        if have_sub_rantfile || @opts[:look_up]
-            cur_dir = Dir.pwd
-            until cur_dir == "/"
-                cur_dir = File.dirname(cur_dir)
-                Dir.chdir cur_dir
-                fn = rantfile_in_dir
-                if fn
-                    @initial_subdir = @rootdir.sub(
-                        /^#{Regexp.escape cur_dir}\//, '')
-                    @rootdir = cur_dir
-                    cmd_msg "(root is #@rootdir, in #@initial_subdir)"
-                    @last_build_subdir = @initial_subdir
-                    rf, is_new = rantfile_for_path(fn)
-                    load_file rf if is_new
-                    goto_project_dir @initial_subdir
-                    if have_sub_rantfile
-                        rf, is_new = rantfile_for_path(
-                                Rant::SUB_RANTFILE, false)
-                        if is_new
-                            @rantfiles.unshift rf
-                            load_file rf
-                        end
-                    end
-                    break
-                end
-            end
-        end
-        if @rantfiles.empty?
-            abort("No Rantfile found, looking for:",
-                Rant::RANTFILES.join(", "))
-        end
-    end
-
-    def load_file(rantfile)
-	vmsg 1, "source #{rantfile}"
-	@context.instance_eval(File.read(rantfile), rantfile)
-    end
-    private :load_file
-
-    def rantfile_in_dir(dir=nil)
-	::Rant::RANTFILES.each { |rfn|
-	    path = dir ? File.join(dir, rfn) : rfn
-            return path if test ?f, path
-	}
-        nil
-    end
-
-    def process_args
-	old_argv = ARGV.dup
-	ARGV.replace(@args.dup)
-	cmd_opts = GetoptLong.new(*OPTIONS.collect { |lst| lst[0..-2] })
-	cmd_opts.quiet = true
-	cmd_opts.each { |opt, value|
-	    case opt
-	    when "--verbose"; @opts[:verbose] += 1
-	    when "--version"
-		puts "rant #{Rant::VERSION}"
-		raise Rant::RantDoneException
-	    when "--help"
-		show_help
-		raise Rant::RantDoneException
-	    when "--directory"
-                @rootdir = File.expand_path(value)
-	    when "--rantfile"
-		@arg_rantfiles << value
-	    when "--force-run"
-		@force_targets << value
-            when "--import"
-                import value
-	    else
-		@opts[opt.sub(/^--/, '').tr('-', "_").to_sym] = true
-	    end
-	}
-    rescue GetoptLong::Error => e
-	abort(e.message)
-    ensure
-	rem_args = ARGV.dup
-	ARGV.replace(old_argv)
-	rem_args.each { |ra|
-	    if ra =~ /(^[^=]+)=([^=]+)$/
-		vmsg 2, "var: #$1=#$2"
-		@var[$1] = $2
-	    else
-		@arg_targets << ra
-	    end
-	}
-    end
-
-    def prepare_task(targ, block, clr = caller[2])
-
-	if targ.is_a? Hash
-	    targ.reject! { |k, v| clr = v if k == :__caller__ }
-	end
-	ch = Hash === clr ? clr : Rant::Lib::parse_caller_elem(clr)
-
-	name, pre = normalize_task_arg(targ, ch)
-
-	file, is_new = rantfile_for_path(ch[:file])
-	nt = yield(name, pre, block)
-	nt.rantfile = file
-        nt.project_subdir = @current_subdir
-	nt.line_number = ch[:ln]
-	nt.description = @task_desc
-	@task_desc = nil
-	file.tasks << nt
-	hash_task nt
-	nt
-    end
-    public :prepare_task
-
-    def hash_task(task)
-	n = task.full_name
-	et = @tasks[n]
-	case et
-	when nil
-	    @tasks[n] = task
-	when Rant::Node
-	    mt = [et, task]
-	    @tasks[n] = mt
-	else # assuming list of tasks
-	    et << task
-	end
-    end
-
-    def normalize_task_arg(targ, ch)
-	name = nil
-	pre = []
-	
-	if targ.is_a? Hash
-	    if targ.empty?
-		abort_at(ch, "Empty hash as task argument, " +
-		    "task name required.")
-	    end
-	    if targ.size > 1
-		abort_at(ch, "Too many hash elements, " +
-		    "should only be one.")
-	    end
-	    targ.each_pair { |k,v|
-		name = normalize_task_name(k, ch)
-		pre = v
-	    }
-	    unless ::Rant::FileList === pre
-		if pre.respond_to? :to_ary
-		    pre = pre.to_ary.dup
-		    pre.map! { |elem|
-			normalize_task_name(elem, ch)
-		    }
-		else
-		    pre = [normalize_task_name(pre, ch)]
-		end
-	    end
-	else
-	    name = normalize_task_name(targ, ch)
-	end
-
-	[name, pre]
-    end
-    public :normalize_task_arg
-
-    def normalize_task_name(arg, ch)
-	return arg if arg.is_a? String
-	if Symbol === arg
-	    arg.to_s
-	elsif arg.respond_to? :to_str
-	    arg.to_str
-	else
-	    abort_at(ch, "Task name has to be a string or symbol.")
-	end
-    end
-
-    def rantfile_for_path(path, register=true)
-	abs_path = File.expand_path(path)
-        file = @rantfiles.find { |rf| rf.path == abs_path }
-	if file
-	    [file, false]
-	else
-	    file = Rant::Rantfile.new abs_path
-	    file.project_subdir = @current_subdir
-	    @rantfiles << file if register
-	    [file, true]
-	end
-    end
-
-    def get_ch_from_backtrace(backtrace)
-	backtrace.each { |clr|
-	    ch = ::Rant::Lib.parse_caller_elem(clr)
-	    if ::Rant::Env.on_windows?
-		return ch if @rantfiles.any? { |rf|
-		    rf.path.tr("\\", "/").sub(/^\w\:/, '') ==
-			ch[:file].tr("\\", "/").sub(/^\w\:/, '')
-		}
-	    else
-		return ch if @rantfiles.any? { |rf|
-		    rf.path == ch[:file]
-		}
-	    end
-	}
-	nil
-    end
-
-    def err_task_fail(e)
-	msg = []
-	t_msg = ["Task `#{e.tname}' fail."]
-	orig = e
-	loop { orig = orig.orig; break unless Rant::TaskFail === orig }
-	if orig && orig != e && !(Rant::RantAbortException === orig)
-            ch = get_ch_from_backtrace(orig.backtrace)
-            msg << pos_text(ch[:file], ch[:ln]) if ch
-            unless Rant::CommandError === orig && !@opts[:err_commands]
-                msg << orig.message
-                msg << orig.backtrace[0..4] unless ch
-            end
-	end
-        if e.msg && !e.msg.empty?
-            ch = get_ch_from_backtrace(e.backtrace)
-            t_msg.unshift(e.msg)
-            t_msg.unshift(pos_text(ch[:file], ch[:ln])) if ch
-        end
-	err_msg msg unless msg.empty?
-	err_msg t_msg
-    end
-end	# class Rant::RantApp
-
-$".concat(['rant/rantlib.rb', 'rant/init.rb', 'rant/rantvar.rb', 'rant/rantsys.rb', 'rant/import/filelist/core.rb', 'rant/node.rb', 'rant/import/nodes/default.rb', 'rant/coregen.rb'])
-Rant::CODE_IMPORTS.concat %w(nodes/default
-    )
-
-# Catch a `require "rant"', sad...
-alias require_backup_by_rant require
-def require libf
-    if libf == "rant"
-        # TODO: needs rework! look at lib/rant.rb
-	self.class.instance_eval { include Rant }
-    else
-	begin
-	    require_backup_by_rant libf
-	rescue
-	    raise $!, caller
-	end
-    end
-end
-
-exit Rant.run
-- 
cgit v1.2.3