xmpp4r 0.3 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +10 -0
- data/README +12 -4
- data/Rakefile +1 -1
- data/data/doc/xmpp4r/examples/advanced/fileserve.rb +2 -0
- data/data/doc/xmpp4r/examples/advanced/recvfile.rb +2 -0
- data/data/doc/xmpp4r/examples/basic/client.rb +2 -2
- data/data/doc/xmpp4r/examples/basic/mass_sender.rb +1 -0
- data/data/doc/xmpp4r/examples/buggy/miniedgarr_cgi.rb +1 -1
- data/lib/xmpp4r/bytestreams.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +10 -4
- data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +5 -1
- data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +5 -1
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +5 -1
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +20 -6
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +4 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +4 -0
- data/lib/xmpp4r/bytestreams/iq/si.rb +4 -0
- data/lib/xmpp4r/component.rb +1 -1
- data/lib/xmpp4r/dataforms.rb +4 -0
- data/lib/xmpp4r/delay.rb +4 -0
- data/lib/xmpp4r/discovery.rb +4 -0
- data/lib/xmpp4r/feature_negotiation.rb +4 -0
- data/lib/xmpp4r/feature_negotiation/iq/feature.rb +4 -0
- data/lib/xmpp4r/iq.rb +1 -1
- data/lib/xmpp4r/message.rb +10 -3
- data/lib/xmpp4r/muc.rb +4 -0
- data/lib/xmpp4r/muc/helper/simplemucclient.rb +4 -0
- data/lib/xmpp4r/presence.rb +9 -5
- data/lib/xmpp4r/rexmladdons.rb +65 -3
- data/lib/xmpp4r/roster.rb +4 -0
- data/lib/xmpp4r/roster/helper/roster.rb +18 -3
- data/lib/xmpp4r/sasl.rb +59 -10
- data/lib/xmpp4r/stream.rb +22 -2
- data/lib/xmpp4r/vcard.rb +4 -0
- data/lib/xmpp4r/vcard/helper/vcard.rb +4 -4
- data/lib/xmpp4r/version.rb +4 -0
- data/lib/xmpp4r/xmpp4r.rb +1 -1
- data/setup.rb +800 -575
- data/test/bytestreams/tc_socks5bytestreams.rb +46 -0
- data/test/tc_iq.rb +1 -1
- data/test/tc_rexml.rb +60 -0
- data/test/ts_xmpp4r.rb +2 -1
- data/test/vcard/tc_helper.rb +49 -0
- metadata +96 -94
- data/test/roster/.tc_helper.rb.swp +0 -0
    
        data/lib/xmpp4r/roster.rb
    CHANGED
    
    | @@ -1,3 +1,7 @@ | |
| 1 | 
            +
            # =XMPP4R - XMPP Library for Ruby
         | 
| 2 | 
            +
            # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
         | 
| 3 | 
            +
            # Website::http://home.gna.org/xmpp4r/
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            require 'xmpp4r/roster/iq/roster.rb'
         | 
| 2 6 | 
             
            require 'xmpp4r/roster/helper/roster.rb'
         | 
| 3 7 | 
             
            require 'xmpp4r/roster/x/roster.rb'
         | 
| @@ -12,6 +12,10 @@ module Jabber | |
| 12 12 | 
             
                # The Roster helper intercepts <tt><iq/></tt> stanzas with Jabber::IqQueryRoster
         | 
| 13 13 | 
             
                # and <tt><presence/></tt> stanzas, but provides cbs which allow the programmer
         | 
| 14 14 | 
             
                # to keep track of updates.
         | 
| 15 | 
            +
                #
         | 
| 16 | 
            +
                # A thread for any received stanza is spawned, so the user can invoke
         | 
| 17 | 
            +
                # accept_subscription et al in the callback blocks, without stopping
         | 
| 18 | 
            +
                # the current (= parser) thread when waiting for a reply.
         | 
| 15 19 | 
             
                class Helper
         | 
| 16 20 | 
             
                  ##
         | 
| 17 21 | 
             
                  # All items in your roster
         | 
| @@ -25,6 +29,10 @@ module Jabber | |
| 25 29 | 
             
                  #
         | 
| 26 30 | 
             
                  # Request a roster
         | 
| 27 31 | 
             
                  # (Remember to send initial presence afterwards!)
         | 
| 32 | 
            +
                  #
         | 
| 33 | 
            +
                  # The initialization will not wait for the roster being received,
         | 
| 34 | 
            +
                  # use add_query_callback to get notifyed when Roster::Helper#items
         | 
| 35 | 
            +
                  # has been filled.
         | 
| 28 36 | 
             
                  def initialize(stream)
         | 
| 29 37 | 
             
                    @stream = stream
         | 
| 30 38 | 
             
                    @items = {}
         | 
| @@ -37,12 +45,16 @@ module Jabber | |
| 37 45 |  | 
| 38 46 | 
             
                    # Register cbs
         | 
| 39 47 | 
             
                    stream.add_iq_callback(120, self) { |iq|
         | 
| 40 | 
            -
                       | 
| 48 | 
            +
                      Thread.new do
         | 
| 49 | 
            +
                        handle_iq(iq)
         | 
| 50 | 
            +
                      end
         | 
| 41 51 | 
             
                    }
         | 
| 42 52 | 
             
                    stream.add_presence_callback(120, self) { |pres|
         | 
| 43 | 
            -
                       | 
| 53 | 
            +
                      Thread.new do
         | 
| 54 | 
            +
                        handle_presence(pres)
         | 
| 55 | 
            +
                      end
         | 
| 44 56 | 
             
                    }
         | 
| 45 | 
            -
             | 
| 57 | 
            +
             | 
| 46 58 | 
             
                    # Request the roster
         | 
| 47 59 | 
             
                    rosterget = Iq.new_rosterget
         | 
| 48 60 | 
             
                    stream.send(rosterget)
         | 
| @@ -171,12 +183,15 @@ module Jabber | |
| 171 183 | 
             
                  # used internally
         | 
| 172 184 | 
             
                  def handle_presence(pres)
         | 
| 173 185 | 
             
                    item = self[pres.from]
         | 
| 186 | 
            +
             | 
| 174 187 | 
             
                    if [:subscribed, :unsubscribe, :unsubscribed].include?(pres.type)
         | 
| 175 188 | 
             
                      @subscription_cbs.process(item, pres)
         | 
| 176 189 | 
             
                      true
         | 
| 190 | 
            +
             | 
| 177 191 | 
             
                    elsif pres.type == :subscribe
         | 
| 178 192 | 
             
                      @subscription_request_cbs.process(item, pres)
         | 
| 179 193 | 
             
                      true
         | 
| 194 | 
            +
             | 
| 180 195 | 
             
                    else
         | 
| 181 196 | 
             
                      unless item.nil?
         | 
| 182 197 | 
             
                        update_presence(item, pres)
         | 
    
        data/lib/xmpp4r/sasl.rb
    CHANGED
    
    | @@ -1,3 +1,7 @@ | |
| 1 | 
            +
            # =XMPP4R - XMPP Library for Ruby
         | 
| 2 | 
            +
            # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
         | 
| 3 | 
            +
            # Website::http://home.gna.org/xmpp4r/
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            require 'base64'
         | 
| 2 6 | 
             
            require 'digest/md5'
         | 
| 3 7 |  | 
| @@ -41,7 +45,7 @@ module Jabber | |
| 41 45 | 
             
                  end
         | 
| 42 46 |  | 
| 43 47 | 
             
                  def generate_nonce
         | 
| 44 | 
            -
                    Digest::MD5. | 
| 48 | 
            +
                    Digest::MD5.hexdigest(Time.new.to_f.to_s)
         | 
| 45 49 | 
             
                  end
         | 
| 46 50 | 
             
                end
         | 
| 47 51 |  | 
| @@ -78,13 +82,7 @@ module Jabber | |
| 78 82 | 
             
                    error = nil
         | 
| 79 83 | 
             
                    @stream.send(generate_auth('DIGEST-MD5')) { |reply|
         | 
| 80 84 | 
             
                      if reply.name == 'challenge' and reply.namespace == NS_SASL
         | 
| 81 | 
            -
                         | 
| 82 | 
            -
                        challenge_text.split(/,/).each { |s|
         | 
| 83 | 
            -
                          key, value = s.split(/=/, 2)
         | 
| 84 | 
            -
                          value.sub!(/^"/, '')
         | 
| 85 | 
            -
                          value.sub!(/"$/, '')
         | 
| 86 | 
            -
                          challenge[key] = value
         | 
| 87 | 
            -
                        }
         | 
| 85 | 
            +
                        challenge = decode_challenge(reply.text)
         | 
| 88 86 | 
             
                      else
         | 
| 89 87 | 
             
                        error = reply.first_element(nil).name
         | 
| 90 88 | 
             
                      end
         | 
| @@ -96,6 +94,49 @@ module Jabber | |
| 96 94 | 
             
                    @realm = challenge['realm']
         | 
| 97 95 | 
             
                  end
         | 
| 98 96 |  | 
| 97 | 
            +
                  def decode_challenge(challenge)
         | 
| 98 | 
            +
                    text = Base64::decode64(challenge)
         | 
| 99 | 
            +
                    res = {}
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    state = :key
         | 
| 102 | 
            +
                    key = ''
         | 
| 103 | 
            +
                    value = ''
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                    text.scan(/./) do |ch|
         | 
| 106 | 
            +
                      if state == :key
         | 
| 107 | 
            +
                        if ch == '='
         | 
| 108 | 
            +
                          state = :value
         | 
| 109 | 
            +
                        else
         | 
| 110 | 
            +
                          key += ch
         | 
| 111 | 
            +
                        end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                      elsif state == :value
         | 
| 114 | 
            +
                        if ch == ','
         | 
| 115 | 
            +
                          res[key] = value
         | 
| 116 | 
            +
                          key = ''
         | 
| 117 | 
            +
                          value = ''
         | 
| 118 | 
            +
                          state = :key
         | 
| 119 | 
            +
                        elsif ch == '"' and value == ''
         | 
| 120 | 
            +
                          state = :quote
         | 
| 121 | 
            +
                        else
         | 
| 122 | 
            +
                          value += ch
         | 
| 123 | 
            +
                        end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                      elsif state == :quote
         | 
| 126 | 
            +
                        if ch == '"'
         | 
| 127 | 
            +
                          state = :value
         | 
| 128 | 
            +
                        else
         | 
| 129 | 
            +
                          value += ch
         | 
| 130 | 
            +
                        end
         | 
| 131 | 
            +
                      end
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
                    res[key] = value unless key == ''
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                    Jabber::debuglog("SASL DIGEST-MD5 challenge:\n#{text.inspect}\n#{res.inspect}")
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    res
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
             | 
| 99 140 | 
             
                  ##
         | 
| 100 141 | 
             
                  # * Send a response
         | 
| 101 142 | 
             
                  # * Wait for the server's challenge (which aren't checked)
         | 
| @@ -117,17 +158,25 @@ module Jabber | |
| 117 158 | 
             
                      end
         | 
| 118 159 | 
             
                    }
         | 
| 119 160 |  | 
| 161 | 
            +
                    response_text = response.collect { |k,v| "#{k}=#{v}" }.join(',')
         | 
| 162 | 
            +
                    Jabber::debuglog("SASL DIGEST-MD5 response:\n#{response_text}")
         | 
| 163 | 
            +
             | 
| 120 164 | 
             
                    r = REXML::Element.new('response')
         | 
| 121 165 | 
             
                    r.add_namespace NS_SASL
         | 
| 122 | 
            -
                    r.text = Base64::encode64( | 
| 166 | 
            +
                    r.text = Base64::encode64(response_text).gsub(/\s/, '')
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                    success_already = false
         | 
| 123 169 | 
             
                    error = nil
         | 
| 124 170 | 
             
                    @stream.send(r) { |reply|
         | 
| 125 | 
            -
                      if reply.name  | 
| 171 | 
            +
                      if reply.name == 'success'
         | 
| 172 | 
            +
                        success_already = true
         | 
| 173 | 
            +
                      elsif reply.name != 'challenge'
         | 
| 126 174 | 
             
                        error = reply.first_element(nil).name
         | 
| 127 175 | 
             
                      end
         | 
| 128 176 | 
             
                      true
         | 
| 129 177 | 
             
                    }
         | 
| 130 178 |  | 
| 179 | 
            +
                    return if success_already
         | 
| 131 180 | 
             
                    raise error if error
         | 
| 132 181 |  | 
| 133 182 | 
             
                    # TODO: check the challenge from the server
         | 
    
        data/lib/xmpp4r/stream.rb
    CHANGED
    
    | @@ -18,6 +18,14 @@ module Jabber | |
| 18 18 | 
             
              ##
         | 
| 19 19 | 
             
              # The stream class manages a connection stream (a file descriptor using which
         | 
| 20 20 | 
             
              # XML messages are read and sent)
         | 
| 21 | 
            +
              #
         | 
| 22 | 
            +
              # You may register callbacks for the three Jabber stanzas
         | 
| 23 | 
            +
              # (message, presence and iq) and use the send and send_with_id
         | 
| 24 | 
            +
              # methods.
         | 
| 25 | 
            +
              #
         | 
| 26 | 
            +
              # To ensure the order of received stanzas, callback blocks are
         | 
| 27 | 
            +
              # launched in the parser thread. If further blocking operations
         | 
| 28 | 
            +
              # are intended in those callbacks, run your own thread there.
         | 
| 21 29 | 
             
              class Stream
         | 
| 22 30 | 
             
                DISCONNECTED = 1
         | 
| 23 31 | 
             
                CONNECTED = 2
         | 
| @@ -352,6 +360,10 @@ module Jabber | |
| 352 360 | 
             
                # Sends XML data to the socket and (optionally) waits
         | 
| 353 361 | 
             
                # to process received data.
         | 
| 354 362 | 
             
                #
         | 
| 363 | 
            +
                # Do not invoke this in a callback but in a seperate thread
         | 
| 364 | 
            +
                # because we may not suspend the parser-thread (in whose
         | 
| 365 | 
            +
                # context callbacks are executed).
         | 
| 366 | 
            +
                #
         | 
| 355 367 | 
             
                # xml:: [String] The xml data to send
         | 
| 356 368 | 
             
                # &block:: [Block] The optional block
         | 
| 357 369 | 
             
                def send(xml, &block)
         | 
| @@ -384,12 +396,16 @@ module Jabber | |
| 384 396 | 
             
                # generated by Jabber::IdGenerator if not already set.
         | 
| 385 397 | 
             
                #
         | 
| 386 398 | 
             
                # The block will be called once: when receiving a stanza with the
         | 
| 387 | 
            -
                # same Jabber:: | 
| 399 | 
            +
                # same Jabber::XMPPStanza#id. There is no need to return true to
         | 
| 400 | 
            +
                # complete this! Instead the return value of the block will be
         | 
| 401 | 
            +
                # returned.
         | 
| 388 402 | 
             
                #
         | 
| 389 403 | 
             
                # Be aware that if a stanza with <tt>type='error'</tt> is received
         | 
| 390 404 | 
             
                # the function does not yield but raises an ErrorException with
         | 
| 391 405 | 
             
                # the corresponding error element.
         | 
| 392 406 | 
             
                #
         | 
| 407 | 
            +
                # Please see Stream#send for some implementational details.
         | 
| 408 | 
            +
                #
         | 
| 393 409 | 
             
                # Please read the note about nesting at Stream#send
         | 
| 394 410 | 
             
                # xml:: [XMLStanza]
         | 
| 395 411 | 
             
                def send_with_id(xml, &block)
         | 
| @@ -397,6 +413,7 @@ module Jabber | |
| 397 413 | 
             
                    xml.id = Jabber::IdGenerator.instance.generate_id
         | 
| 398 414 | 
             
                  end
         | 
| 399 415 |  | 
| 416 | 
            +
                  res = nil
         | 
| 400 417 | 
             
                  error = nil
         | 
| 401 418 | 
             
                  send(xml) do |received|
         | 
| 402 419 | 
             
                    if received.kind_of? XMLStanza and received.id == xml.id
         | 
| @@ -404,7 +421,8 @@ module Jabber | |
| 404 421 | 
             
                        error = (received.error ? received.error : Error.new)
         | 
| 405 422 | 
             
                        true
         | 
| 406 423 | 
             
                      else
         | 
| 407 | 
            -
                        yield(received)
         | 
| 424 | 
            +
                        res = yield(received)
         | 
| 425 | 
            +
                        true
         | 
| 408 426 | 
             
                      end
         | 
| 409 427 | 
             
                    else
         | 
| 410 428 | 
             
                      false
         | 
| @@ -414,6 +432,8 @@ module Jabber | |
| 414 432 | 
             
                  unless error.nil?
         | 
| 415 433 | 
             
                    raise ErrorException.new(error)
         | 
| 416 434 | 
             
                  end
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                  res
         | 
| 417 437 | 
             
                end
         | 
| 418 438 |  | 
| 419 439 | 
             
                ##
         | 
    
        data/lib/xmpp4r/vcard.rb
    CHANGED
    
    
| @@ -70,15 +70,15 @@ module Jabber | |
| 70 70 | 
             
                  ##
         | 
| 71 71 | 
             
                  # Quickly initialize a Vcard helper and get
         | 
| 72 72 | 
             
                  # a vCard. See Vcard#get
         | 
| 73 | 
            -
                  def  | 
| 74 | 
            -
                     | 
| 73 | 
            +
                  def self.get(stream, jid=nil)
         | 
| 74 | 
            +
                    new(stream).get(jid)
         | 
| 75 75 | 
             
                  end
         | 
| 76 76 |  | 
| 77 77 | 
             
                  ##
         | 
| 78 78 | 
             
                  # Quickly initialize a Vcard helper and set
         | 
| 79 79 | 
             
                  # your vCard. See Vcard#set
         | 
| 80 | 
            -
                  def  | 
| 81 | 
            -
                     | 
| 80 | 
            +
                  def self.set(stream, iqvcard)
         | 
| 81 | 
            +
                    new(stream).set(iqvcard)
         | 
| 82 82 | 
             
                  end
         | 
| 83 83 | 
             
                end
         | 
| 84 84 | 
             
              end
         | 
    
        data/lib/xmpp4r/version.rb
    CHANGED
    
    | @@ -1,3 +1,7 @@ | |
| 1 | 
            +
            # =XMPP4R - XMPP Library for Ruby
         | 
| 2 | 
            +
            # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
         | 
| 3 | 
            +
            # Website::http://home.gna.org/xmpp4r/
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            require 'xmpp4r/version/helper/responder.rb'
         | 
| 2 6 | 
             
            require 'xmpp4r/version/helper/simpleresponder.rb'
         | 
| 3 7 | 
             
            require 'xmpp4r/version/iq/version.rb'
         | 
    
        data/lib/xmpp4r/xmpp4r.rb
    CHANGED
    
    
    
        data/setup.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            #
         | 
| 2 2 | 
             
            # setup.rb
         | 
| 3 3 | 
             
            #
         | 
| 4 | 
            -
            # Copyright (c) 2000- | 
| 4 | 
            +
            # Copyright (c) 2000-2005 Minero Aoki
         | 
| 5 5 | 
             
            #
         | 
| 6 6 | 
             
            # This program is free software.
         | 
| 7 7 | 
             
            # You can distribute/modify this program under the terms of
         | 
| @@ -22,176 +22,68 @@ unless File.respond_to?(:read)   # Ruby 1.6 | |
| 22 22 | 
             
              end
         | 
| 23 23 | 
             
            end
         | 
| 24 24 |  | 
| 25 | 
            +
            unless Errno.const_defined?(:ENOTEMPTY)   # Windows?
         | 
| 26 | 
            +
              module Errno
         | 
| 27 | 
            +
                class ENOTEMPTY
         | 
| 28 | 
            +
                  # We do not raise this exception, implementation is not needed.
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 25 33 | 
             
            def File.binread(fname)
         | 
| 26 34 | 
             
              open(fname, 'rb') {|f|
         | 
| 27 35 | 
             
                return f.read
         | 
| 28 36 | 
             
              }
         | 
| 29 37 | 
             
            end
         | 
| 30 38 |  | 
| 31 | 
            -
            # for corrupted  | 
| 39 | 
            +
            # for corrupted Windows' stat(2)
         | 
| 32 40 | 
             
            def File.dir?(path)
         | 
| 33 41 | 
             
              File.directory?((path[-1,1] == '/') ? path : path + '/')
         | 
| 34 42 | 
             
            end
         | 
| 35 43 |  | 
| 36 44 |  | 
| 37 | 
            -
            class  | 
| 38 | 
            -
             | 
| 39 | 
            -
            def setup_rb_error(msg)
         | 
| 40 | 
            -
              raise SetupError, msg
         | 
| 41 | 
            -
            end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
            #
         | 
| 44 | 
            -
            # Config
         | 
| 45 | 
            -
            #
         | 
| 46 | 
            -
             | 
| 47 | 
            -
            if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
         | 
| 48 | 
            -
              ARGV.delete(arg)
         | 
| 49 | 
            -
              require arg.split(/=/, 2)[1]
         | 
| 50 | 
            -
              $".push 'rbconfig.rb'
         | 
| 51 | 
            -
            else
         | 
| 52 | 
            -
              require 'rbconfig'
         | 
| 53 | 
            -
            end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
            def multipackage_install?
         | 
| 56 | 
            -
              FileTest.directory?(File.dirname($0) + '/packages')
         | 
| 57 | 
            -
            end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
            class ConfigItem
         | 
| 61 | 
            -
              def initialize(name, template, default, desc)
         | 
| 62 | 
            -
                @name = name.freeze
         | 
| 63 | 
            -
                @template = template
         | 
| 64 | 
            -
                @value = default
         | 
| 65 | 
            -
                @default = default.dup.freeze
         | 
| 66 | 
            -
                @description = desc
         | 
| 67 | 
            -
              end
         | 
| 68 | 
            -
             | 
| 69 | 
            -
              attr_reader :name
         | 
| 70 | 
            -
              attr_reader :description
         | 
| 71 | 
            -
             | 
| 72 | 
            -
              attr_accessor :default
         | 
| 73 | 
            -
              alias help_default default
         | 
| 74 | 
            -
             | 
| 75 | 
            -
              def help_opt
         | 
| 76 | 
            -
                "--#{@name}=#{@template}"
         | 
| 77 | 
            -
              end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
              def value
         | 
| 80 | 
            -
                @value
         | 
| 81 | 
            -
              end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
              def eval(table)
         | 
| 84 | 
            -
                @value.gsub(%r<\$([^/]+)>) { table[$1] }
         | 
| 85 | 
            -
              end
         | 
| 86 | 
            -
             | 
| 87 | 
            -
              def set(val)
         | 
| 88 | 
            -
                @value = check(val)
         | 
| 89 | 
            -
              end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
              private
         | 
| 92 | 
            -
             | 
| 93 | 
            -
              def check(val)
         | 
| 94 | 
            -
                setup_rb_error "config: --#{name} requires argument" unless val
         | 
| 95 | 
            -
                val
         | 
| 96 | 
            -
              end
         | 
| 97 | 
            -
            end
         | 
| 98 | 
            -
             | 
| 99 | 
            -
            class BoolItem < ConfigItem
         | 
| 100 | 
            -
              def config_type
         | 
| 101 | 
            -
                'bool'
         | 
| 102 | 
            -
              end
         | 
| 103 | 
            -
             | 
| 104 | 
            -
              def help_opt
         | 
| 105 | 
            -
                "--#{@name}"
         | 
| 106 | 
            -
              end
         | 
| 45 | 
            +
            class ConfigTable
         | 
| 107 46 |  | 
| 108 | 
            -
               | 
| 109 | 
            -
             | 
| 110 | 
            -
              def check(val)
         | 
| 111 | 
            -
                return 'yes' unless val
         | 
| 112 | 
            -
                unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ val
         | 
| 113 | 
            -
                  setup_rb_error "config: --#{@name} accepts only yes/no for argument"
         | 
| 114 | 
            -
                end
         | 
| 115 | 
            -
                (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
         | 
| 116 | 
            -
              end
         | 
| 117 | 
            -
            end
         | 
| 47 | 
            +
              include Enumerable
         | 
| 118 48 |  | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
                 | 
| 49 | 
            +
              def initialize(rbconfig)
         | 
| 50 | 
            +
                @rbconfig = rbconfig
         | 
| 51 | 
            +
                @items = []
         | 
| 52 | 
            +
                @table = {}
         | 
| 53 | 
            +
                # options
         | 
| 54 | 
            +
                @install_prefix = nil
         | 
| 55 | 
            +
                @config_opt = nil
         | 
| 56 | 
            +
                @verbose = true
         | 
| 57 | 
            +
                @no_harm = false
         | 
| 122 58 | 
             
              end
         | 
| 123 59 |  | 
| 124 | 
            -
               | 
| 60 | 
            +
              attr_accessor :install_prefix
         | 
| 61 | 
            +
              attr_accessor :config_opt
         | 
| 125 62 |  | 
| 126 | 
            -
               | 
| 127 | 
            -
                setup_rb_error "config: --#{@name} requires argument"  unless path
         | 
| 128 | 
            -
                path[0,1] == '$' ? path : File.expand_path(path)
         | 
| 129 | 
            -
              end
         | 
| 130 | 
            -
            end
         | 
| 131 | 
            -
             | 
| 132 | 
            -
            class ProgramItem < ConfigItem
         | 
| 133 | 
            -
              def config_type
         | 
| 134 | 
            -
                'program'
         | 
| 135 | 
            -
              end
         | 
| 136 | 
            -
            end
         | 
| 63 | 
            +
              attr_writer :verbose
         | 
| 137 64 |  | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
                super
         | 
| 141 | 
            -
                @ok = template.split('/')
         | 
| 142 | 
            -
              end
         | 
| 143 | 
            -
             | 
| 144 | 
            -
              def config_type
         | 
| 145 | 
            -
                'select'
         | 
| 65 | 
            +
              def verbose?
         | 
| 66 | 
            +
                @verbose
         | 
| 146 67 | 
             
              end
         | 
| 147 68 |  | 
| 148 | 
            -
               | 
| 149 | 
            -
             | 
| 150 | 
            -
              def check(val)
         | 
| 151 | 
            -
                unless @ok.include?(val.strip)
         | 
| 152 | 
            -
                  setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
         | 
| 153 | 
            -
                end
         | 
| 154 | 
            -
                val.strip
         | 
| 155 | 
            -
              end
         | 
| 156 | 
            -
            end
         | 
| 69 | 
            +
              attr_writer :no_harm
         | 
| 157 70 |  | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
                super name, template, default, desc
         | 
| 161 | 
            -
                @help_default = help_default
         | 
| 71 | 
            +
              def no_harm?
         | 
| 72 | 
            +
                @no_harm
         | 
| 162 73 | 
             
              end
         | 
| 163 74 |  | 
| 164 | 
            -
               | 
| 165 | 
            -
             | 
| 166 | 
            -
              def config_type
         | 
| 167 | 
            -
                'package'
         | 
| 75 | 
            +
              def [](key)
         | 
| 76 | 
            +
                lookup(key).resolve(self)
         | 
| 168 77 | 
             
              end
         | 
| 169 78 |  | 
| 170 | 
            -
               | 
| 171 | 
            -
             | 
| 172 | 
            -
              def check(val)
         | 
| 173 | 
            -
                unless File.dir?("packages/#{val}")
         | 
| 174 | 
            -
                  setup_rb_error "config: no such package: #{val}"
         | 
| 175 | 
            -
                end
         | 
| 176 | 
            -
                val
         | 
| 79 | 
            +
              def []=(key, val)
         | 
| 80 | 
            +
                lookup(key).set val
         | 
| 177 81 | 
             
              end
         | 
| 178 | 
            -
            end
         | 
| 179 | 
            -
             | 
| 180 | 
            -
            class ConfigTable_class
         | 
| 181 82 |  | 
| 182 | 
            -
              def  | 
| 183 | 
            -
                @items  | 
| 184 | 
            -
                @table = {}
         | 
| 185 | 
            -
                items.each do |i|
         | 
| 186 | 
            -
                  @table[i.name] = i
         | 
| 187 | 
            -
                end
         | 
| 188 | 
            -
                ALIASES.each do |ali, name|
         | 
| 189 | 
            -
                  @table[ali] = @table[name]
         | 
| 190 | 
            -
                end
         | 
| 83 | 
            +
              def names
         | 
| 84 | 
            +
                @items.map {|i| i.name }
         | 
| 191 85 | 
             
              end
         | 
| 192 86 |  | 
| 193 | 
            -
              include Enumerable
         | 
| 194 | 
            -
             | 
| 195 87 | 
             
              def each(&block)
         | 
| 196 88 | 
             
                @items.each(&block)
         | 
| 197 89 | 
             
              end
         | 
| @@ -201,7 +93,7 @@ class ConfigTable_class | |
| 201 93 | 
             
              end
         | 
| 202 94 |  | 
| 203 95 | 
             
              def lookup(name)
         | 
| 204 | 
            -
                @table[name] or  | 
| 96 | 
            +
                @table[name] or setup_rb_error "no such config item: #{name}"
         | 
| 205 97 | 
             
              end
         | 
| 206 98 |  | 
| 207 99 | 
             
              def add(item)
         | 
| @@ -216,24 +108,24 @@ class ConfigTable_class | |
| 216 108 | 
             
                item
         | 
| 217 109 | 
             
              end
         | 
| 218 110 |  | 
| 219 | 
            -
              def  | 
| 220 | 
            -
                 | 
| 111 | 
            +
              def load_script(path, inst = nil)
         | 
| 112 | 
            +
                if File.file?(path)
         | 
| 113 | 
            +
                  MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
         | 
| 114 | 
            +
                end
         | 
| 221 115 | 
             
              end
         | 
| 222 116 |  | 
| 223 117 | 
             
              def savefile
         | 
| 224 118 | 
             
                '.config'
         | 
| 225 119 | 
             
              end
         | 
| 226 120 |  | 
| 227 | 
            -
              def  | 
| 121 | 
            +
              def load_savefile
         | 
| 228 122 | 
             
                begin
         | 
| 229 | 
            -
                  t = dup()
         | 
| 230 123 | 
             
                  File.foreach(savefile()) do |line|
         | 
| 231 124 | 
             
                    k, v = *line.split(/=/, 2)
         | 
| 232 | 
            -
                     | 
| 125 | 
            +
                    self[k] = v.strip
         | 
| 233 126 | 
             
                  end
         | 
| 234 | 
            -
                  t
         | 
| 235 127 | 
             
                rescue Errno::ENOENT
         | 
| 236 | 
            -
                  setup_rb_error $!.message + "#{File.basename($0)} config first"
         | 
| 128 | 
            +
                  setup_rb_error $!.message + "\n#{File.basename($0)} config first"
         | 
| 237 129 | 
             
                end
         | 
| 238 130 | 
             
              end
         | 
| 239 131 |  | 
| @@ -241,117 +133,151 @@ class ConfigTable_class | |
| 241 133 | 
             
                @items.each {|i| i.value }
         | 
| 242 134 | 
             
                File.open(savefile(), 'w') {|f|
         | 
| 243 135 | 
             
                  @items.each do |i|
         | 
| 244 | 
            -
                    f.printf "%s=%s\n", i.name, i.value if i.value
         | 
| 136 | 
            +
                    f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
         | 
| 245 137 | 
             
                  end
         | 
| 246 138 | 
             
                }
         | 
| 247 139 | 
             
              end
         | 
| 248 140 |  | 
| 249 | 
            -
              def  | 
| 250 | 
            -
                 | 
| 141 | 
            +
              def load_standard_entries
         | 
| 142 | 
            +
                standard_entries(@rbconfig).each do |ent|
         | 
| 143 | 
            +
                  add ent
         | 
| 144 | 
            +
                end
         | 
| 251 145 | 
             
              end
         | 
| 252 146 |  | 
| 253 | 
            -
              def  | 
| 254 | 
            -
                 | 
| 255 | 
            -
             | 
| 147 | 
            +
              def standard_entries(rbconfig)
         | 
| 148 | 
            +
                c = rbconfig
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                major = c['MAJOR'].to_i
         | 
| 153 | 
            +
                minor = c['MINOR'].to_i
         | 
| 154 | 
            +
                teeny = c['TEENY'].to_i
         | 
| 155 | 
            +
                version = "#{major}.#{minor}"
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                # ruby ver. >= 1.4.4?
         | 
| 158 | 
            +
                newpath_p = ((major >= 2) or
         | 
| 159 | 
            +
                             ((major == 1) and
         | 
| 160 | 
            +
                              ((minor >= 5) or
         | 
| 161 | 
            +
                               ((minor == 4) and (teeny >= 4)))))
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                if c['rubylibdir']
         | 
| 164 | 
            +
                  # V > 1.6.3
         | 
| 165 | 
            +
                  libruby         = "#{c['prefix']}/lib/ruby"
         | 
| 166 | 
            +
                  librubyver      = c['rubylibdir']
         | 
| 167 | 
            +
                  librubyverarch  = c['archdir']
         | 
| 168 | 
            +
                  siteruby        = c['sitedir']
         | 
| 169 | 
            +
                  siterubyver     = c['sitelibdir']
         | 
| 170 | 
            +
                  siterubyverarch = c['sitearchdir']
         | 
| 171 | 
            +
                elsif newpath_p
         | 
| 172 | 
            +
                  # 1.4.4 <= V <= 1.6.3
         | 
| 173 | 
            +
                  libruby         = "#{c['prefix']}/lib/ruby"
         | 
| 174 | 
            +
                  librubyver      = "#{c['prefix']}/lib/ruby/#{version}"
         | 
| 175 | 
            +
                  librubyverarch  = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
         | 
| 176 | 
            +
                  siteruby        = c['sitedir']
         | 
| 177 | 
            +
                  siterubyver     = "$siteruby/#{version}"
         | 
| 178 | 
            +
                  siterubyverarch = "$siterubyver/#{c['arch']}"
         | 
| 179 | 
            +
                else
         | 
| 180 | 
            +
                  # V < 1.4.4
         | 
| 181 | 
            +
                  libruby         = "#{c['prefix']}/lib/ruby"
         | 
| 182 | 
            +
                  librubyver      = "#{c['prefix']}/lib/ruby/#{version}"
         | 
| 183 | 
            +
                  librubyverarch  = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
         | 
| 184 | 
            +
                  siteruby        = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
         | 
| 185 | 
            +
                  siterubyver     = siteruby
         | 
| 186 | 
            +
                  siterubyverarch = "$siterubyver/#{c['arch']}"
         | 
| 187 | 
            +
                end
         | 
| 188 | 
            +
                parameterize = lambda {|path|
         | 
| 189 | 
            +
                  path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
         | 
| 190 | 
            +
                }
         | 
| 256 191 |  | 
| 257 | 
            -
             | 
| 192 | 
            +
                if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
         | 
| 193 | 
            +
                  makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
         | 
| 194 | 
            +
                else
         | 
| 195 | 
            +
                  makeprog = 'make'
         | 
| 196 | 
            +
                end
         | 
| 258 197 |  | 
| 259 | 
            -
             | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 262 | 
            -
             | 
| 263 | 
            -
             | 
| 264 | 
            -
             | 
| 265 | 
            -
             | 
| 266 | 
            -
             | 
| 267 | 
            -
             | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
             | 
| 271 | 
            -
                           | 
| 272 | 
            -
             | 
| 273 | 
            -
             | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 276 | 
            -
             | 
| 277 | 
            -
             | 
| 278 | 
            -
             | 
| 279 | 
            -
             | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 289 | 
            -
             | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
             | 
| 299 | 
            -
                  . | 
| 300 | 
            -
             | 
| 301 | 
            -
                  . | 
| 302 | 
            -
             | 
| 303 | 
            -
             | 
| 304 | 
            -
             | 
| 305 | 
            -
             | 
| 306 | 
            -
             | 
| 307 | 
            -
             | 
| 308 | 
            -
             | 
| 309 | 
            -
             | 
| 310 | 
            -
             | 
| 311 | 
            -
             | 
| 312 | 
            -
             | 
| 313 | 
            -
             | 
| 314 | 
            -
             | 
| 198 | 
            +
                [
         | 
| 199 | 
            +
                  ExecItem.new('installdirs', 'std/site/home',
         | 
| 200 | 
            +
                               'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
         | 
| 201 | 
            +
                      {|val, table|
         | 
| 202 | 
            +
                        case val
         | 
| 203 | 
            +
                        when 'std'
         | 
| 204 | 
            +
                          table['rbdir'] = '$librubyver'
         | 
| 205 | 
            +
                          table['sodir'] = '$librubyverarch'
         | 
| 206 | 
            +
                        when 'site'
         | 
| 207 | 
            +
                          table['rbdir'] = '$siterubyver'
         | 
| 208 | 
            +
                          table['sodir'] = '$siterubyverarch'
         | 
| 209 | 
            +
                        when 'home'
         | 
| 210 | 
            +
                          setup_rb_error '$HOME was not set' unless ENV['HOME']
         | 
| 211 | 
            +
                          table['prefix'] = ENV['HOME']
         | 
| 212 | 
            +
                          table['rbdir'] = '$libdir/ruby'
         | 
| 213 | 
            +
                          table['sodir'] = '$libdir/ruby'
         | 
| 214 | 
            +
                        end
         | 
| 215 | 
            +
                      },
         | 
| 216 | 
            +
                  PathItem.new('prefix', 'path', c['prefix'],
         | 
| 217 | 
            +
                               'path prefix of target environment'),
         | 
| 218 | 
            +
                  PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
         | 
| 219 | 
            +
                               'the directory for commands'),
         | 
| 220 | 
            +
                  PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
         | 
| 221 | 
            +
                               'the directory for libraries'),
         | 
| 222 | 
            +
                  PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
         | 
| 223 | 
            +
                               'the directory for shared data'),
         | 
| 224 | 
            +
                  PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
         | 
| 225 | 
            +
                               'the directory for man pages'),
         | 
| 226 | 
            +
                  PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
         | 
| 227 | 
            +
                               'the directory for system configuration files'),
         | 
| 228 | 
            +
                  PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
         | 
| 229 | 
            +
                               'the directory for local state data'),
         | 
| 230 | 
            +
                  PathItem.new('libruby', 'path', libruby,
         | 
| 231 | 
            +
                               'the directory for ruby libraries'),
         | 
| 232 | 
            +
                  PathItem.new('librubyver', 'path', librubyver,
         | 
| 233 | 
            +
                               'the directory for standard ruby libraries'),
         | 
| 234 | 
            +
                  PathItem.new('librubyverarch', 'path', librubyverarch,
         | 
| 235 | 
            +
                               'the directory for standard ruby extensions'),
         | 
| 236 | 
            +
                  PathItem.new('siteruby', 'path', siteruby,
         | 
| 237 | 
            +
                      'the directory for version-independent aux ruby libraries'),
         | 
| 238 | 
            +
                  PathItem.new('siterubyver', 'path', siterubyver,
         | 
| 239 | 
            +
                               'the directory for aux ruby libraries'),
         | 
| 240 | 
            +
                  PathItem.new('siterubyverarch', 'path', siterubyverarch,
         | 
| 241 | 
            +
                               'the directory for aux ruby binaries'),
         | 
| 242 | 
            +
                  PathItem.new('rbdir', 'path', '$siterubyver',
         | 
| 243 | 
            +
                               'the directory for ruby scripts'),
         | 
| 244 | 
            +
                  PathItem.new('sodir', 'path', '$siterubyverarch',
         | 
| 245 | 
            +
                               'the directory for ruby extentions'),
         | 
| 246 | 
            +
                  PathItem.new('rubypath', 'path', rubypath,
         | 
| 247 | 
            +
                               'the path to set to #! line'),
         | 
| 248 | 
            +
                  ProgramItem.new('rubyprog', 'name', rubypath,
         | 
| 249 | 
            +
                                  'the ruby program using for installation'),
         | 
| 250 | 
            +
                  ProgramItem.new('makeprog', 'name', makeprog,
         | 
| 251 | 
            +
                                  'the make program to compile ruby extentions'),
         | 
| 252 | 
            +
                  SelectItem.new('shebang', 'all/ruby/never', 'ruby',
         | 
| 253 | 
            +
                                 'shebang line (#!) editing mode'),
         | 
| 254 | 
            +
                  BoolItem.new('without-ext', 'yes/no', 'no',
         | 
| 255 | 
            +
                               'does not compile/install ruby extentions')
         | 
| 256 | 
            +
                ]
         | 
| 257 | 
            +
              end
         | 
| 258 | 
            +
              private :standard_entries
         | 
| 259 | 
            +
             | 
| 260 | 
            +
              def load_multipackage_entries
         | 
| 261 | 
            +
                multipackage_entries().each do |ent|
         | 
| 262 | 
            +
                  add ent
         | 
| 263 | 
            +
                end
         | 
| 264 | 
            +
              end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
              def multipackage_entries
         | 
| 267 | 
            +
                [
         | 
| 268 | 
            +
                  PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
         | 
| 269 | 
            +
                                           'package names that you want to install'),
         | 
| 270 | 
            +
                  PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
         | 
| 271 | 
            +
                                           'package names that you do not want to install')
         | 
| 272 | 
            +
                ]
         | 
| 273 | 
            +
              end
         | 
| 274 | 
            +
              private :multipackage_entries
         | 
| 315 275 |  | 
| 316 | 
            -
            common_conf = [
         | 
| 317 | 
            -
              PathItem.new('prefix', 'path', c['prefix'],
         | 
| 318 | 
            -
                           'path prefix of target environment'),
         | 
| 319 | 
            -
              PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
         | 
| 320 | 
            -
                           'the directory for commands'),
         | 
| 321 | 
            -
              PathItem.new('libdir', 'path', libdir,
         | 
| 322 | 
            -
                           'the directory for libraries'),
         | 
| 323 | 
            -
              PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
         | 
| 324 | 
            -
                           'the directory for shared data'),
         | 
| 325 | 
            -
              PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
         | 
| 326 | 
            -
                           'the directory for man pages'),
         | 
| 327 | 
            -
              PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
         | 
| 328 | 
            -
                           'the directory for man pages'),
         | 
| 329 | 
            -
              PathItem.new('stdruby', 'path', stdruby,
         | 
| 330 | 
            -
                           'the directory for standard ruby libraries'),
         | 
| 331 | 
            -
              PathItem.new('siteruby', 'path', siteruby,
         | 
| 332 | 
            -
                  'the directory for version-independent aux ruby libraries'),
         | 
| 333 | 
            -
              PathItem.new('siterubyver', 'path', siterubyver,
         | 
| 334 | 
            -
                           'the directory for aux ruby libraries'),
         | 
| 335 | 
            -
              PathItem.new('siterubyverarch', 'path', siterubyverarch,
         | 
| 336 | 
            -
                           'the directory for aux ruby binaries'),
         | 
| 337 | 
            -
              PathItem.new('rbdir', 'path', '$siterubyver',
         | 
| 338 | 
            -
                           'the directory for ruby scripts'),
         | 
| 339 | 
            -
              PathItem.new('sodir', 'path', '$siterubyverarch',
         | 
| 340 | 
            -
                           'the directory for ruby extentions'),
         | 
| 341 | 
            -
              PathItem.new('rubypath', 'path', rubypath,
         | 
| 342 | 
            -
                           'the path to set to #! line'),
         | 
| 343 | 
            -
              ProgramItem.new('rubyprog', 'name', rubypath,
         | 
| 344 | 
            -
                              'the ruby program using for installation'),
         | 
| 345 | 
            -
              ProgramItem.new('makeprog', 'name', makeprog,
         | 
| 346 | 
            -
                              'the make program to compile ruby extentions'),
         | 
| 347 | 
            -
              SelectItem.new('shebang', 'all/ruby/never', 'ruby',
         | 
| 348 | 
            -
                             'shebang line (#!) editing mode'),
         | 
| 349 | 
            -
              BoolItem.new('without-ext', 'yes/no', 'no',
         | 
| 350 | 
            -
                           'does not compile/install ruby extentions')
         | 
| 351 | 
            -
            ]
         | 
| 352 | 
            -
            class ConfigTable_class   # open again
         | 
| 353 276 | 
             
              ALIASES = {
         | 
| 354 | 
            -
                'std-ruby'         => ' | 
| 277 | 
            +
                'std-ruby'         => 'librubyver',
         | 
| 278 | 
            +
                'stdruby'          => 'librubyver',
         | 
| 279 | 
            +
                'rubylibdir'       => 'librubyver',
         | 
| 280 | 
            +
                'archdir'          => 'librubyverarch',
         | 
| 355 281 | 
             
                'site-ruby-common' => 'siteruby',     # For backward compatibility
         | 
| 356 282 | 
             
                'site-ruby'        => 'siterubyver',  # For backward compatibility
         | 
| 357 283 | 
             
                'bin-dir'          => 'bindir',
         | 
| @@ -365,78 +291,248 @@ class ConfigTable_class   # open again | |
| 365 291 | 
             
                'make-prog'        => 'makeprog',
         | 
| 366 292 | 
             
                'make'             => 'makeprog'
         | 
| 367 293 | 
             
              }
         | 
| 368 | 
            -
            end
         | 
| 369 | 
            -
            multipackage_conf = [
         | 
| 370 | 
            -
              PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
         | 
| 371 | 
            -
                                       'package names that you want to install'),
         | 
| 372 | 
            -
              PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
         | 
| 373 | 
            -
                                       'package names that you do not want to install')
         | 
| 374 | 
            -
            ]
         | 
| 375 | 
            -
            if multipackage_install?
         | 
| 376 | 
            -
              ConfigTable = ConfigTable_class.new(common_conf + multipackage_conf)
         | 
| 377 | 
            -
            else
         | 
| 378 | 
            -
              ConfigTable = ConfigTable_class.new(common_conf)
         | 
| 379 | 
            -
            end
         | 
| 380 294 |  | 
| 381 | 
            -
             | 
| 382 | 
            -
             | 
| 383 | 
            -
             | 
| 384 | 
            -
             | 
| 385 | 
            -
                 | 
| 295 | 
            +
              def fixup
         | 
| 296 | 
            +
                ALIASES.each do |ali, name|
         | 
| 297 | 
            +
                  @table[ali] = @table[name]
         | 
| 298 | 
            +
                end
         | 
| 299 | 
            +
                @items.freeze
         | 
| 300 | 
            +
                @table.freeze
         | 
| 301 | 
            +
                @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
         | 
| 386 302 | 
             
              end
         | 
| 387 303 |  | 
| 388 | 
            -
              def  | 
| 389 | 
            -
                 | 
| 304 | 
            +
              def parse_opt(opt)
         | 
| 305 | 
            +
                m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
         | 
| 306 | 
            +
                m.to_a[1,2]
         | 
| 390 307 | 
             
              end
         | 
| 391 308 |  | 
| 392 | 
            -
              def  | 
| 393 | 
            -
                 | 
| 309 | 
            +
              def dllext
         | 
| 310 | 
            +
                @rbconfig['DLEXT']
         | 
| 394 311 | 
             
              end
         | 
| 395 312 |  | 
| 396 | 
            -
              def  | 
| 397 | 
            -
                 | 
| 313 | 
            +
              def value_config?(name)
         | 
| 314 | 
            +
                lookup(name).value?
         | 
| 398 315 | 
             
              end
         | 
| 399 316 |  | 
| 400 | 
            -
               | 
| 401 | 
            -
                 | 
| 402 | 
            -
             | 
| 317 | 
            +
              class Item
         | 
| 318 | 
            +
                def initialize(name, template, default, desc)
         | 
| 319 | 
            +
                  @name = name.freeze
         | 
| 320 | 
            +
                  @template = template
         | 
| 321 | 
            +
                  @value = default
         | 
| 322 | 
            +
                  @default = default
         | 
| 323 | 
            +
                  @description = desc
         | 
| 324 | 
            +
                end
         | 
| 403 325 |  | 
| 404 | 
            -
             | 
| 405 | 
            -
                 | 
| 406 | 
            -
             | 
| 326 | 
            +
                attr_reader :name
         | 
| 327 | 
            +
                attr_reader :description
         | 
| 328 | 
            +
             | 
| 329 | 
            +
                attr_accessor :default
         | 
| 330 | 
            +
                alias help_default default
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                def help_opt
         | 
| 333 | 
            +
                  "--#{@name}=#{@template}"
         | 
| 334 | 
            +
                end
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                def value?
         | 
| 407 337 | 
             
                  true
         | 
| 408 | 
            -
                 | 
| 409 | 
            -
             | 
| 338 | 
            +
                end
         | 
| 339 | 
            +
             | 
| 340 | 
            +
                def value
         | 
| 341 | 
            +
                  @value
         | 
| 342 | 
            +
                end
         | 
| 343 | 
            +
             | 
| 344 | 
            +
                def resolve(table)
         | 
| 345 | 
            +
                  @value.gsub(%r<\$([^/]+)>) { table[$1] }
         | 
| 346 | 
            +
                end
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                def set(val)
         | 
| 349 | 
            +
                  @value = check(val)
         | 
| 350 | 
            +
                end
         | 
| 351 | 
            +
             | 
| 352 | 
            +
                private
         | 
| 353 | 
            +
             | 
| 354 | 
            +
                def check(val)
         | 
| 355 | 
            +
                  setup_rb_error "config: --#{name} requires argument" unless val
         | 
| 356 | 
            +
                  val
         | 
| 410 357 | 
             
                end
         | 
| 411 358 | 
             
              end
         | 
| 412 359 |  | 
| 413 | 
            -
               | 
| 414 | 
            -
                 | 
| 360 | 
            +
              class BoolItem < Item
         | 
| 361 | 
            +
                def config_type
         | 
| 362 | 
            +
                  'bool'
         | 
| 363 | 
            +
                end
         | 
| 364 | 
            +
             | 
| 365 | 
            +
                def help_opt
         | 
| 366 | 
            +
                  "--#{@name}"
         | 
| 367 | 
            +
                end
         | 
| 368 | 
            +
             | 
| 369 | 
            +
                private
         | 
| 370 | 
            +
             | 
| 371 | 
            +
                def check(val)
         | 
| 372 | 
            +
                  return 'yes' unless val
         | 
| 373 | 
            +
                  case val
         | 
| 374 | 
            +
                  when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
         | 
| 375 | 
            +
                  when /\An(o)?\z/i, /\Af(alse)\z/i  then 'no'
         | 
| 376 | 
            +
                  else
         | 
| 377 | 
            +
                    setup_rb_error "config: --#{@name} accepts only yes/no for argument"
         | 
| 378 | 
            +
                  end
         | 
| 379 | 
            +
                end
         | 
| 415 380 | 
             
              end
         | 
| 416 381 |  | 
| 417 | 
            -
               | 
| 418 | 
            -
                 | 
| 382 | 
            +
              class PathItem < Item
         | 
| 383 | 
            +
                def config_type
         | 
| 384 | 
            +
                  'path'
         | 
| 385 | 
            +
                end
         | 
| 386 | 
            +
             | 
| 387 | 
            +
                private
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                def check(path)
         | 
| 390 | 
            +
                  setup_rb_error "config: --#{@name} requires argument"  unless path
         | 
| 391 | 
            +
                  path[0,1] == '$' ? path : File.expand_path(path)
         | 
| 392 | 
            +
                end
         | 
| 419 393 | 
             
              end
         | 
| 420 394 |  | 
| 421 | 
            -
               | 
| 422 | 
            -
                 | 
| 395 | 
            +
              class ProgramItem < Item
         | 
| 396 | 
            +
                def config_type
         | 
| 397 | 
            +
                  'program'
         | 
| 398 | 
            +
                end
         | 
| 423 399 | 
             
              end
         | 
| 424 400 |  | 
| 425 | 
            -
               | 
| 426 | 
            -
                 | 
| 401 | 
            +
              class SelectItem < Item
         | 
| 402 | 
            +
                def initialize(name, selection, default, desc)
         | 
| 403 | 
            +
                  super
         | 
| 404 | 
            +
                  @ok = selection.split('/')
         | 
| 405 | 
            +
                end
         | 
| 406 | 
            +
             | 
| 407 | 
            +
                def config_type
         | 
| 408 | 
            +
                  'select'
         | 
| 409 | 
            +
                end
         | 
| 410 | 
            +
             | 
| 411 | 
            +
                private
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                def check(val)
         | 
| 414 | 
            +
                  unless @ok.include?(val.strip)
         | 
| 415 | 
            +
                    setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
         | 
| 416 | 
            +
                  end
         | 
| 417 | 
            +
                  val.strip
         | 
| 418 | 
            +
                end
         | 
| 427 419 | 
             
              end
         | 
| 428 420 |  | 
| 429 | 
            -
               | 
| 430 | 
            -
                 | 
| 421 | 
            +
              class ExecItem < Item
         | 
| 422 | 
            +
                def initialize(name, selection, desc, &block)
         | 
| 423 | 
            +
                  super name, selection, nil, desc
         | 
| 424 | 
            +
                  @ok = selection.split('/')
         | 
| 425 | 
            +
                  @action = block
         | 
| 426 | 
            +
                end
         | 
| 427 | 
            +
             | 
| 428 | 
            +
                def config_type
         | 
| 429 | 
            +
                  'exec'
         | 
| 430 | 
            +
                end
         | 
| 431 | 
            +
             | 
| 432 | 
            +
                def value?
         | 
| 433 | 
            +
                  false
         | 
| 434 | 
            +
                end
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                def resolve(table)
         | 
| 437 | 
            +
                  setup_rb_error "$#{name()} wrongly used as option value"
         | 
| 438 | 
            +
                end
         | 
| 439 | 
            +
             | 
| 440 | 
            +
                undef set
         | 
| 441 | 
            +
             | 
| 442 | 
            +
                def evaluate(val, table)
         | 
| 443 | 
            +
                  v = val.strip.downcase
         | 
| 444 | 
            +
                  unless @ok.include?(v)
         | 
| 445 | 
            +
                    setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
         | 
| 446 | 
            +
                  end
         | 
| 447 | 
            +
                  @action.call v, table
         | 
| 448 | 
            +
                end
         | 
| 431 449 | 
             
              end
         | 
| 432 450 |  | 
| 433 | 
            -
             | 
| 451 | 
            +
              class PackageSelectionItem < Item
         | 
| 452 | 
            +
                def initialize(name, template, default, help_default, desc)
         | 
| 453 | 
            +
                  super name, template, default, desc
         | 
| 454 | 
            +
                  @help_default = help_default
         | 
| 455 | 
            +
                end
         | 
| 434 456 |  | 
| 457 | 
            +
                attr_reader :help_default
         | 
| 435 458 |  | 
| 436 | 
            -
             | 
| 437 | 
            -
             | 
| 438 | 
            -
             | 
| 459 | 
            +
                def config_type
         | 
| 460 | 
            +
                  'package'
         | 
| 461 | 
            +
                end
         | 
| 462 | 
            +
             | 
| 463 | 
            +
                private
         | 
| 439 464 |  | 
| 465 | 
            +
                def check(val)
         | 
| 466 | 
            +
                  unless File.dir?("packages/#{val}")
         | 
| 467 | 
            +
                    setup_rb_error "config: no such package: #{val}"
         | 
| 468 | 
            +
                  end
         | 
| 469 | 
            +
                  val
         | 
| 470 | 
            +
                end
         | 
| 471 | 
            +
              end
         | 
| 472 | 
            +
             | 
| 473 | 
            +
              class MetaConfigEnvironment
         | 
| 474 | 
            +
                def initialize(config, installer)
         | 
| 475 | 
            +
                  @config = config
         | 
| 476 | 
            +
                  @installer = installer
         | 
| 477 | 
            +
                end
         | 
| 478 | 
            +
             | 
| 479 | 
            +
                def config_names
         | 
| 480 | 
            +
                  @config.names
         | 
| 481 | 
            +
                end
         | 
| 482 | 
            +
             | 
| 483 | 
            +
                def config?(name)
         | 
| 484 | 
            +
                  @config.key?(name)
         | 
| 485 | 
            +
                end
         | 
| 486 | 
            +
             | 
| 487 | 
            +
                def bool_config?(name)
         | 
| 488 | 
            +
                  @config.lookup(name).config_type == 'bool'
         | 
| 489 | 
            +
                end
         | 
| 490 | 
            +
             | 
| 491 | 
            +
                def path_config?(name)
         | 
| 492 | 
            +
                  @config.lookup(name).config_type == 'path'
         | 
| 493 | 
            +
                end
         | 
| 494 | 
            +
             | 
| 495 | 
            +
                def value_config?(name)
         | 
| 496 | 
            +
                  @config.lookup(name).config_type != 'exec'
         | 
| 497 | 
            +
                end
         | 
| 498 | 
            +
             | 
| 499 | 
            +
                def add_config(item)
         | 
| 500 | 
            +
                  @config.add item
         | 
| 501 | 
            +
                end
         | 
| 502 | 
            +
             | 
| 503 | 
            +
                def add_bool_config(name, default, desc)
         | 
| 504 | 
            +
                  @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
         | 
| 505 | 
            +
                end
         | 
| 506 | 
            +
             | 
| 507 | 
            +
                def add_path_config(name, default, desc)
         | 
| 508 | 
            +
                  @config.add PathItem.new(name, 'path', default, desc)
         | 
| 509 | 
            +
                end
         | 
| 510 | 
            +
             | 
| 511 | 
            +
                def set_config_default(name, default)
         | 
| 512 | 
            +
                  @config.lookup(name).default = default
         | 
| 513 | 
            +
                end
         | 
| 514 | 
            +
             | 
| 515 | 
            +
                def remove_config(name)
         | 
| 516 | 
            +
                  @config.remove(name)
         | 
| 517 | 
            +
                end
         | 
| 518 | 
            +
             | 
| 519 | 
            +
                # For only multipackage
         | 
| 520 | 
            +
                def packages
         | 
| 521 | 
            +
                  raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
         | 
| 522 | 
            +
                  @installer.packages
         | 
| 523 | 
            +
                end
         | 
| 524 | 
            +
             | 
| 525 | 
            +
                # For only multipackage
         | 
| 526 | 
            +
                def declare_packages(list)
         | 
| 527 | 
            +
                  raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
         | 
| 528 | 
            +
                  @installer.packages = list
         | 
| 529 | 
            +
                end
         | 
| 530 | 
            +
              end
         | 
| 531 | 
            +
             | 
| 532 | 
            +
            end   # class ConfigTable
         | 
| 533 | 
            +
             | 
| 534 | 
            +
             | 
| 535 | 
            +
            # This module requires: #verbose?, #no_harm?
         | 
| 440 536 | 
             
            module FileOperations
         | 
| 441 537 |  | 
| 442 538 | 
             
              def mkdir_p(dirname, prefix = nil)
         | 
| @@ -444,7 +540,7 @@ module FileOperations | |
| 444 540 | 
             
                $stderr.puts "mkdir -p #{dirname}" if verbose?
         | 
| 445 541 | 
             
                return if no_harm?
         | 
| 446 542 |  | 
| 447 | 
            -
                #  | 
| 543 | 
            +
                # Does not check '/', it's too abnormal.
         | 
| 448 544 | 
             
                dirs = File.expand_path(dirname).split(%r<(?=/)>)
         | 
| 449 545 | 
             
                if /\A[a-z]:\z/i =~ dirs[0]
         | 
| 450 546 | 
             
                  disk = dirs.shift
         | 
| @@ -456,49 +552,73 @@ module FileOperations | |
| 456 552 | 
             
                end
         | 
| 457 553 | 
             
              end
         | 
| 458 554 |  | 
| 459 | 
            -
              def rm_f( | 
| 460 | 
            -
                $stderr.puts "rm -f #{ | 
| 555 | 
            +
              def rm_f(path)
         | 
| 556 | 
            +
                $stderr.puts "rm -f #{path}" if verbose?
         | 
| 461 557 | 
             
                return if no_harm?
         | 
| 462 | 
            -
             | 
| 463 | 
            -
                if File.exist?(fname) or File.symlink?(fname)
         | 
| 464 | 
            -
                  File.chmod 0777, fname
         | 
| 465 | 
            -
                  File.unlink fname
         | 
| 466 | 
            -
                end
         | 
| 558 | 
            +
                force_remove_file path
         | 
| 467 559 | 
             
              end
         | 
| 468 560 |  | 
| 469 | 
            -
              def rm_rf( | 
| 470 | 
            -
                $stderr.puts "rm -rf #{ | 
| 561 | 
            +
              def rm_rf(path)
         | 
| 562 | 
            +
                $stderr.puts "rm -rf #{path}" if verbose?
         | 
| 471 563 | 
             
                return if no_harm?
         | 
| 564 | 
            +
                remove_tree path
         | 
| 565 | 
            +
              end
         | 
| 566 | 
            +
             | 
| 567 | 
            +
              def remove_tree(path)
         | 
| 568 | 
            +
                if File.symlink?(path)
         | 
| 569 | 
            +
                  remove_file path
         | 
| 570 | 
            +
                elsif File.dir?(path)
         | 
| 571 | 
            +
                  remove_tree0 path
         | 
| 572 | 
            +
                else
         | 
| 573 | 
            +
                  force_remove_file path
         | 
| 574 | 
            +
                end
         | 
| 575 | 
            +
              end
         | 
| 472 576 |  | 
| 473 | 
            -
             | 
| 474 | 
            -
                Dir.foreach( | 
| 475 | 
            -
                  next if  | 
| 476 | 
            -
                  next if  | 
| 477 | 
            -
                   | 
| 478 | 
            -
             | 
| 479 | 
            -
             | 
| 480 | 
            -
             | 
| 577 | 
            +
              def remove_tree0(path)
         | 
| 578 | 
            +
                Dir.foreach(path) do |ent|
         | 
| 579 | 
            +
                  next if ent == '.'
         | 
| 580 | 
            +
                  next if ent == '..'
         | 
| 581 | 
            +
                  entpath = "#{path}/#{ent}"
         | 
| 582 | 
            +
                  if File.symlink?(entpath)
         | 
| 583 | 
            +
                    remove_file entpath
         | 
| 584 | 
            +
                  elsif File.dir?(entpath)
         | 
| 585 | 
            +
                    remove_tree0 entpath
         | 
| 481 586 | 
             
                  else
         | 
| 482 | 
            -
                     | 
| 483 | 
            -
                      rm_f fn
         | 
| 484 | 
            -
                    }
         | 
| 587 | 
            +
                    force_remove_file entpath
         | 
| 485 588 | 
             
                  end
         | 
| 486 589 | 
             
                end
         | 
| 487 | 
            -
                 | 
| 488 | 
            -
             | 
| 590 | 
            +
                begin
         | 
| 591 | 
            +
                  Dir.rmdir path
         | 
| 592 | 
            +
                rescue Errno::ENOTEMPTY
         | 
| 593 | 
            +
                  # directory may not be empty
         | 
| 594 | 
            +
                end
         | 
| 489 595 | 
             
              end
         | 
| 490 596 |  | 
| 491 597 | 
             
              def move_file(src, dest)
         | 
| 492 | 
            -
                 | 
| 598 | 
            +
                force_remove_file dest
         | 
| 493 599 | 
             
                begin
         | 
| 494 600 | 
             
                  File.rename src, dest
         | 
| 495 601 | 
             
                rescue
         | 
| 496 | 
            -
                  File.open(dest, 'wb') {|f| | 
| 602 | 
            +
                  File.open(dest, 'wb') {|f|
         | 
| 603 | 
            +
                    f.write File.binread(src)
         | 
| 604 | 
            +
                  }
         | 
| 497 605 | 
             
                  File.chmod File.stat(src).mode, dest
         | 
| 498 606 | 
             
                  File.unlink src
         | 
| 499 607 | 
             
                end
         | 
| 500 608 | 
             
              end
         | 
| 501 609 |  | 
| 610 | 
            +
              def force_remove_file(path)
         | 
| 611 | 
            +
                begin
         | 
| 612 | 
            +
                  remove_file path
         | 
| 613 | 
            +
                rescue
         | 
| 614 | 
            +
                end
         | 
| 615 | 
            +
              end
         | 
| 616 | 
            +
             | 
| 617 | 
            +
              def remove_file(path)
         | 
| 618 | 
            +
                File.chmod 0777, path
         | 
| 619 | 
            +
                File.unlink path
         | 
| 620 | 
            +
              end
         | 
| 621 | 
            +
             | 
| 502 622 | 
             
              def install(from, dest, mode, prefix = nil)
         | 
| 503 623 | 
             
                $stderr.puts "install #{from} #{dest}" if verbose?
         | 
| 504 624 | 
             
                return if no_harm?
         | 
| @@ -530,66 +650,42 @@ module FileOperations | |
| 530 650 | 
             
                new_content != File.binread(path)
         | 
| 531 651 | 
             
              end
         | 
| 532 652 |  | 
| 533 | 
            -
              def command( | 
| 534 | 
            -
                $stderr.puts  | 
| 535 | 
            -
                system  | 
| 653 | 
            +
              def command(*args)
         | 
| 654 | 
            +
                $stderr.puts args.join(' ') if verbose?
         | 
| 655 | 
            +
                system(*args) or raise RuntimeError,
         | 
| 656 | 
            +
                    "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
         | 
| 536 657 | 
             
              end
         | 
| 537 658 |  | 
| 538 | 
            -
              def ruby( | 
| 539 | 
            -
                command config('rubyprog')  | 
| 659 | 
            +
              def ruby(*args)
         | 
| 660 | 
            +
                command config('rubyprog'), *args
         | 
| 540 661 | 
             
              end
         | 
| 541 662 |  | 
| 542 | 
            -
              def make(task =  | 
| 543 | 
            -
                command | 
| 663 | 
            +
              def make(task = nil)
         | 
| 664 | 
            +
                command(*[config('makeprog'), task].compact)
         | 
| 544 665 | 
             
              end
         | 
| 545 666 |  | 
| 546 667 | 
             
              def extdir?(dir)
         | 
| 547 | 
            -
                File.exist?(dir  | 
| 668 | 
            +
                File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
         | 
| 548 669 | 
             
              end
         | 
| 549 670 |  | 
| 550 | 
            -
              def  | 
| 551 | 
            -
                Dir.open( | 
| 552 | 
            -
                  return d.select {|ent| File.file?("#{ | 
| 671 | 
            +
              def files_of(dir)
         | 
| 672 | 
            +
                Dir.open(dir) {|d|
         | 
| 673 | 
            +
                  return d.select {|ent| File.file?("#{dir}/#{ent}") }
         | 
| 553 674 | 
             
                }
         | 
| 554 675 | 
             
              end
         | 
| 555 676 |  | 
| 556 | 
            -
               | 
| 557 | 
            -
                CVS SCCS RCS CVS.adm .svn
         | 
| 558 | 
            -
              )
         | 
| 677 | 
            +
              DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
         | 
| 559 678 |  | 
| 560 | 
            -
              def  | 
| 561 | 
            -
                Dir.open( | 
| 562 | 
            -
                  return d.select {| | 
| 679 | 
            +
              def directories_of(dir)
         | 
| 680 | 
            +
                Dir.open(dir) {|d|
         | 
| 681 | 
            +
                  return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
         | 
| 563 682 | 
             
                }
         | 
| 564 683 | 
             
              end
         | 
| 565 684 |  | 
| 566 685 | 
             
            end
         | 
| 567 686 |  | 
| 568 687 |  | 
| 569 | 
            -
            #
         | 
| 570 | 
            -
            # Main Installer
         | 
| 571 | 
            -
            #
         | 
| 572 | 
            -
             | 
| 573 | 
            -
            module HookUtils
         | 
| 574 | 
            -
             | 
| 575 | 
            -
              def run_hook(name)
         | 
| 576 | 
            -
                try_run_hook "#{curr_srcdir()}/#{name}" or
         | 
| 577 | 
            -
                try_run_hook "#{curr_srcdir()}/#{name}.rb"
         | 
| 578 | 
            -
              end
         | 
| 579 | 
            -
             | 
| 580 | 
            -
              def try_run_hook(fname)
         | 
| 581 | 
            -
                return false unless File.file?(fname)
         | 
| 582 | 
            -
                begin
         | 
| 583 | 
            -
                  instance_eval File.read(fname), fname, 1
         | 
| 584 | 
            -
                rescue
         | 
| 585 | 
            -
                  setup_rb_error "hook #{fname} failed:\n" + $!.message
         | 
| 586 | 
            -
                end
         | 
| 587 | 
            -
                true
         | 
| 588 | 
            -
              end
         | 
| 589 | 
            -
             | 
| 590 | 
            -
            end
         | 
| 591 | 
            -
             | 
| 592 | 
            -
             | 
| 688 | 
            +
            # This module requires: #srcdir_root, #objdir_root, #relpath
         | 
| 593 689 | 
             
            module HookScriptAPI
         | 
| 594 690 |  | 
| 595 691 | 
             
              def get_config(key)
         | 
| @@ -598,6 +694,7 @@ module HookScriptAPI | |
| 598 694 |  | 
| 599 695 | 
             
              alias config get_config
         | 
| 600 696 |  | 
| 697 | 
            +
              # obsolete: use metaconfig to change configuration
         | 
| 601 698 | 
             
              def set_config(key, val)
         | 
| 602 699 | 
             
                @config[key] = val
         | 
| 603 700 | 
             
              end
         | 
| @@ -606,10 +703,6 @@ module HookScriptAPI | |
| 606 703 | 
             
              # srcdir/objdir (works only in the package directory)
         | 
| 607 704 | 
             
              #
         | 
| 608 705 |  | 
| 609 | 
            -
              #abstract srcdir_root
         | 
| 610 | 
            -
              #abstract objdir_root
         | 
| 611 | 
            -
              #abstract relpath
         | 
| 612 | 
            -
             | 
| 613 706 | 
             
              def curr_srcdir
         | 
| 614 707 | 
             
                "#{srcdir_root()}/#{relpath()}"
         | 
| 615 708 | 
             
              end
         | 
| @@ -631,7 +724,7 @@ module HookScriptAPI | |
| 631 724 | 
             
              end
         | 
| 632 725 |  | 
| 633 726 | 
             
              def srcfile?(path)
         | 
| 634 | 
            -
                File.file? | 
| 727 | 
            +
                File.file?(srcfile(path))
         | 
| 635 728 | 
             
              end
         | 
| 636 729 |  | 
| 637 730 | 
             
              def srcentries(path = '.')
         | 
| @@ -657,8 +750,8 @@ end | |
| 657 750 |  | 
| 658 751 | 
             
            class ToplevelInstaller
         | 
| 659 752 |  | 
| 660 | 
            -
              Version   = '3. | 
| 661 | 
            -
              Copyright = 'Copyright (c) 2000- | 
| 753 | 
            +
              Version   = '3.4.1'
         | 
| 754 | 
            +
              Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
         | 
| 662 755 |  | 
| 663 756 | 
             
              TASKS = [
         | 
| 664 757 | 
             
                [ 'all',      'do config, setup, then install' ],
         | 
| @@ -666,27 +759,44 @@ class ToplevelInstaller | |
| 666 759 | 
             
                [ 'show',     'shows current configuration' ],
         | 
| 667 760 | 
             
                [ 'setup',    'compiles ruby extentions and others' ],
         | 
| 668 761 | 
             
                [ 'install',  'installs files' ],
         | 
| 762 | 
            +
                [ 'test',     'run all tests in test/' ],
         | 
| 669 763 | 
             
                [ 'clean',    "does `make clean' for each extention" ],
         | 
| 670 764 | 
             
                [ 'distclean',"does `make distclean' for each extention" ]
         | 
| 671 765 | 
             
              ]
         | 
| 672 766 |  | 
| 673 767 | 
             
              def ToplevelInstaller.invoke
         | 
| 674 | 
            -
                 | 
| 768 | 
            +
                config = ConfigTable.new(load_rbconfig())
         | 
| 769 | 
            +
                config.load_standard_entries
         | 
| 770 | 
            +
                config.load_multipackage_entries if multipackage?
         | 
| 771 | 
            +
                config.fixup
         | 
| 772 | 
            +
                klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
         | 
| 773 | 
            +
                klass.new(File.dirname($0), config).invoke
         | 
| 675 774 | 
             
              end
         | 
| 676 775 |  | 
| 677 | 
            -
               | 
| 678 | 
            -
             | 
| 679 | 
            -
              def ToplevelInstaller.instance
         | 
| 680 | 
            -
                @singleton ||= new(File.dirname($0))
         | 
| 681 | 
            -
                @singleton
         | 
| 776 | 
            +
              def ToplevelInstaller.multipackage?
         | 
| 777 | 
            +
                File.dir?(File.dirname($0) + '/packages')
         | 
| 682 778 | 
             
              end
         | 
| 683 779 |  | 
| 684 | 
            -
               | 
| 780 | 
            +
              def ToplevelInstaller.load_rbconfig
         | 
| 781 | 
            +
                if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
         | 
| 782 | 
            +
                  ARGV.delete(arg)
         | 
| 783 | 
            +
                  load File.expand_path(arg.split(/=/, 2)[1])
         | 
| 784 | 
            +
                  $".push 'rbconfig.rb'
         | 
| 785 | 
            +
                else
         | 
| 786 | 
            +
                  require 'rbconfig'
         | 
| 787 | 
            +
                end
         | 
| 788 | 
            +
                ::Config::CONFIG
         | 
| 789 | 
            +
              end
         | 
| 685 790 |  | 
| 686 | 
            -
              def initialize(ardir_root)
         | 
| 687 | 
            -
                @config = nil
         | 
| 688 | 
            -
                @options = { 'verbose' => true }
         | 
| 791 | 
            +
              def initialize(ardir_root, config)
         | 
| 689 792 | 
             
                @ardir = File.expand_path(ardir_root)
         | 
| 793 | 
            +
                @config = config
         | 
| 794 | 
            +
                # cache
         | 
| 795 | 
            +
                @valid_task_re = nil
         | 
| 796 | 
            +
              end
         | 
| 797 | 
            +
             | 
| 798 | 
            +
              def config(key)
         | 
| 799 | 
            +
                @config[key]
         | 
| 690 800 | 
             
              end
         | 
| 691 801 |  | 
| 692 802 | 
             
              def inspect
         | 
| @@ -697,14 +807,20 @@ class ToplevelInstaller | |
| 697 807 | 
             
                run_metaconfigs
         | 
| 698 808 | 
             
                case task = parsearg_global()
         | 
| 699 809 | 
             
                when nil, 'all'
         | 
| 700 | 
            -
                  @config = load_config('config')
         | 
| 701 810 | 
             
                  parsearg_config
         | 
| 702 811 | 
             
                  init_installers
         | 
| 703 812 | 
             
                  exec_config
         | 
| 704 813 | 
             
                  exec_setup
         | 
| 705 814 | 
             
                  exec_install
         | 
| 706 815 | 
             
                else
         | 
| 707 | 
            -
                   | 
| 816 | 
            +
                  case task
         | 
| 817 | 
            +
                  when 'config', 'test'
         | 
| 818 | 
            +
                    ;
         | 
| 819 | 
            +
                  when 'clean', 'distclean'
         | 
| 820 | 
            +
                    @config.load_savefile if File.exist?(@config.savefile)
         | 
| 821 | 
            +
                  else
         | 
| 822 | 
            +
                    @config.load_savefile
         | 
| 823 | 
            +
                  end
         | 
| 708 824 | 
             
                  __send__ "parsearg_#{task}"
         | 
| 709 825 | 
             
                  init_installers
         | 
| 710 826 | 
             
                  __send__ "exec_#{task}"
         | 
| @@ -712,25 +828,11 @@ class ToplevelInstaller | |
| 712 828 | 
             
              end
         | 
| 713 829 |  | 
| 714 830 | 
             
              def run_metaconfigs
         | 
| 715 | 
            -
                 | 
| 716 | 
            -
              end
         | 
| 717 | 
            -
             | 
| 718 | 
            -
              def load_config(task)
         | 
| 719 | 
            -
                case task
         | 
| 720 | 
            -
                when 'config'
         | 
| 721 | 
            -
                  ConfigTable.new
         | 
| 722 | 
            -
                when 'clean', 'distclean'
         | 
| 723 | 
            -
                  if File.exist?(ConfigTable.savefile)
         | 
| 724 | 
            -
                  then ConfigTable.load
         | 
| 725 | 
            -
                  else ConfigTable.new
         | 
| 726 | 
            -
                  end
         | 
| 727 | 
            -
                else
         | 
| 728 | 
            -
                  ConfigTable.load
         | 
| 729 | 
            -
                end
         | 
| 831 | 
            +
                @config.load_script "#{@ardir}/metaconfig"
         | 
| 730 832 | 
             
              end
         | 
| 731 833 |  | 
| 732 834 | 
             
              def init_installers
         | 
| 733 | 
            -
                @installer = Installer.new(@config, @ | 
| 835 | 
            +
                @installer = Installer.new(@config, @ardir, File.expand_path('.'))
         | 
| 734 836 | 
             
              end
         | 
| 735 837 |  | 
| 736 838 | 
             
              #
         | 
| @@ -754,78 +856,89 @@ class ToplevelInstaller | |
| 754 856 | 
             
              #
         | 
| 755 857 |  | 
| 756 858 | 
             
              def parsearg_global
         | 
| 757 | 
            -
                valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
         | 
| 758 | 
            -
             | 
| 759 859 | 
             
                while arg = ARGV.shift
         | 
| 760 860 | 
             
                  case arg
         | 
| 761 861 | 
             
                  when /\A\w+\z/
         | 
| 762 | 
            -
                    setup_rb_error "invalid task: #{arg}" unless valid_task | 
| 862 | 
            +
                    setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
         | 
| 763 863 | 
             
                    return arg
         | 
| 764 | 
            -
             | 
| 765 864 | 
             
                  when '-q', '--quiet'
         | 
| 766 | 
            -
                    @ | 
| 767 | 
            -
             | 
| 768 | 
            -
             | 
| 769 | 
            -
             | 
| 770 | 
            -
             | 
| 771 | 
            -
                  when '-h', '--help'
         | 
| 865 | 
            +
                    @config.verbose = false
         | 
| 866 | 
            +
                  when '--verbose'
         | 
| 867 | 
            +
                    @config.verbose = true
         | 
| 868 | 
            +
                  when '--help'
         | 
| 772 869 | 
             
                    print_usage $stdout
         | 
| 773 870 | 
             
                    exit 0
         | 
| 774 | 
            -
             | 
| 775 | 
            -
                  when '-v', '--version'
         | 
| 871 | 
            +
                  when '--version'
         | 
| 776 872 | 
             
                    puts "#{File.basename($0)} version #{Version}"
         | 
| 777 873 | 
             
                    exit 0
         | 
| 778 | 
            -
                  
         | 
| 779 874 | 
             
                  when '--copyright'
         | 
| 780 875 | 
             
                    puts Copyright
         | 
| 781 876 | 
             
                    exit 0
         | 
| 782 | 
            -
             | 
| 783 877 | 
             
                  else
         | 
| 784 878 | 
             
                    setup_rb_error "unknown global option '#{arg}'"
         | 
| 785 879 | 
             
                  end
         | 
| 786 880 | 
             
                end
         | 
| 787 | 
            -
             | 
| 788 881 | 
             
                nil
         | 
| 789 882 | 
             
              end
         | 
| 790 883 |  | 
| 884 | 
            +
              def valid_task?(t)
         | 
| 885 | 
            +
                valid_task_re() =~ t
         | 
| 886 | 
            +
              end
         | 
| 887 | 
            +
             | 
| 888 | 
            +
              def valid_task_re
         | 
| 889 | 
            +
                @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
         | 
| 890 | 
            +
              end
         | 
| 791 891 |  | 
| 792 892 | 
             
              def parsearg_no_options
         | 
| 793 893 | 
             
                unless ARGV.empty?
         | 
| 794 | 
            -
                   | 
| 894 | 
            +
                  task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
         | 
| 895 | 
            +
                  setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
         | 
| 795 896 | 
             
                end
         | 
| 796 897 | 
             
              end
         | 
| 797 898 |  | 
| 798 899 | 
             
              alias parsearg_show       parsearg_no_options
         | 
| 799 900 | 
             
              alias parsearg_setup      parsearg_no_options
         | 
| 901 | 
            +
              alias parsearg_test       parsearg_no_options
         | 
| 800 902 | 
             
              alias parsearg_clean      parsearg_no_options
         | 
| 801 903 | 
             
              alias parsearg_distclean  parsearg_no_options
         | 
| 802 904 |  | 
| 803 905 | 
             
              def parsearg_config
         | 
| 804 | 
            -
                 | 
| 805 | 
            -
                 | 
| 806 | 
            -
             | 
| 906 | 
            +
                evalopt = []
         | 
| 907 | 
            +
                set = []
         | 
| 908 | 
            +
                @config.config_opt = []
         | 
| 807 909 | 
             
                while i = ARGV.shift
         | 
| 808 910 | 
             
                  if /\A--?\z/ =~ i
         | 
| 809 | 
            -
                    @ | 
| 911 | 
            +
                    @config.config_opt = ARGV.dup
         | 
| 810 912 | 
             
                    break
         | 
| 811 913 | 
             
                  end
         | 
| 812 | 
            -
                   | 
| 813 | 
            -
                   | 
| 814 | 
            -
             | 
| 914 | 
            +
                  name, value = *@config.parse_opt(i)
         | 
| 915 | 
            +
                  if @config.value_config?(name)
         | 
| 916 | 
            +
                    @config[name] = value
         | 
| 917 | 
            +
                  else
         | 
| 918 | 
            +
                    evalopt.push [name, value]
         | 
| 919 | 
            +
                  end
         | 
| 920 | 
            +
                  set.push name
         | 
| 921 | 
            +
                end
         | 
| 922 | 
            +
                evalopt.each do |name, value|
         | 
| 923 | 
            +
                  @config.lookup(name).evaluate value, @config
         | 
| 924 | 
            +
                end
         | 
| 925 | 
            +
                # Check if configuration is valid
         | 
| 926 | 
            +
                set.each do |n|
         | 
| 927 | 
            +
                  @config[n] if @config.value_config?(n)
         | 
| 815 928 | 
             
                end
         | 
| 816 929 | 
             
              end
         | 
| 817 930 |  | 
| 818 931 | 
             
              def parsearg_install
         | 
| 819 | 
            -
                @ | 
| 820 | 
            -
                @ | 
| 932 | 
            +
                @config.no_harm = false
         | 
| 933 | 
            +
                @config.install_prefix = ''
         | 
| 821 934 | 
             
                while a = ARGV.shift
         | 
| 822 935 | 
             
                  case a
         | 
| 823 | 
            -
                  when  | 
| 824 | 
            -
                    @ | 
| 825 | 
            -
                  when /\A--prefix | 
| 826 | 
            -
                    path =  | 
| 936 | 
            +
                  when '--no-harm'
         | 
| 937 | 
            +
                    @config.no_harm = true
         | 
| 938 | 
            +
                  when /\A--prefix=/
         | 
| 939 | 
            +
                    path = a.split(/=/, 2)[1]
         | 
| 827 940 | 
             
                    path = File.expand_path(path) unless path[0,1] == '/'
         | 
| 828 | 
            -
                    @ | 
| 941 | 
            +
                    @config.install_prefix = path
         | 
| 829 942 | 
             
                  else
         | 
| 830 943 | 
             
                    setup_rb_error "install: unknown option #{a}"
         | 
| 831 944 | 
             
                  end
         | 
| @@ -847,8 +960,8 @@ class ToplevelInstaller | |
| 847 960 | 
             
                out.puts 'Global options:'
         | 
| 848 961 | 
             
                out.printf fmt, '-q,--quiet',   'suppress message outputs'
         | 
| 849 962 | 
             
                out.printf fmt, '   --verbose', 'output messages verbosely'
         | 
| 850 | 
            -
                out.printf fmt, ' | 
| 851 | 
            -
                out.printf fmt, ' | 
| 963 | 
            +
                out.printf fmt, '   --help',    'print this message'
         | 
| 964 | 
            +
                out.printf fmt, '   --version', 'print version and quit'
         | 
| 852 965 | 
             
                out.printf fmt, '   --copyright',  'print copyright and quit'
         | 
| 853 966 | 
             
                out.puts
         | 
| 854 967 | 
             
                out.puts 'Tasks:'
         | 
| @@ -859,14 +972,14 @@ class ToplevelInstaller | |
| 859 972 | 
             
                fmt = "  %-24s %s [%s]\n"
         | 
| 860 973 | 
             
                out.puts
         | 
| 861 974 | 
             
                out.puts 'Options for CONFIG or ALL:'
         | 
| 862 | 
            -
                 | 
| 975 | 
            +
                @config.each do |item|
         | 
| 863 976 | 
             
                  out.printf fmt, item.help_opt, item.description, item.help_default
         | 
| 864 977 | 
             
                end
         | 
| 865 978 | 
             
                out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
         | 
| 866 979 | 
             
                out.puts
         | 
| 867 980 | 
             
                out.puts 'Options for INSTALL:'
         | 
| 868 981 | 
             
                out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
         | 
| 869 | 
            -
                out.printf fmt, '--prefix=path',  'install path prefix', ' | 
| 982 | 
            +
                out.printf fmt, '--prefix=path',  'install path prefix', ''
         | 
| 870 983 | 
             
                out.puts
         | 
| 871 984 | 
             
              end
         | 
| 872 985 |  | 
| @@ -887,9 +1000,13 @@ class ToplevelInstaller | |
| 887 1000 | 
             
                @installer.exec_install
         | 
| 888 1001 | 
             
              end
         | 
| 889 1002 |  | 
| 1003 | 
            +
              def exec_test
         | 
| 1004 | 
            +
                @installer.exec_test
         | 
| 1005 | 
            +
              end
         | 
| 1006 | 
            +
             | 
| 890 1007 | 
             
              def exec_show
         | 
| 891 | 
            -
                 | 
| 892 | 
            -
                  printf "%-20s %s\n", i.name, i.value
         | 
| 1008 | 
            +
                @config.each do |i|
         | 
| 1009 | 
            +
                  printf "%-20s %s\n", i.name, i.value if i.value?
         | 
| 893 1010 | 
             
                end
         | 
| 894 1011 | 
             
              end
         | 
| 895 1012 |  | 
| @@ -901,36 +1018,45 @@ class ToplevelInstaller | |
| 901 1018 | 
             
                @installer.exec_distclean
         | 
| 902 1019 | 
             
              end
         | 
| 903 1020 |  | 
| 904 | 
            -
            end
         | 
| 1021 | 
            +
            end   # class ToplevelInstaller
         | 
| 905 1022 |  | 
| 906 1023 |  | 
| 907 1024 | 
             
            class ToplevelInstallerMulti < ToplevelInstaller
         | 
| 908 1025 |  | 
| 909 | 
            -
              include HookUtils
         | 
| 910 | 
            -
              include HookScriptAPI
         | 
| 911 1026 | 
             
              include FileOperations
         | 
| 912 1027 |  | 
| 913 | 
            -
              def initialize( | 
| 1028 | 
            +
              def initialize(ardir_root, config)
         | 
| 914 1029 | 
             
                super
         | 
| 915 | 
            -
                @packages =  | 
| 1030 | 
            +
                @packages = directories_of("#{@ardir}/packages")
         | 
| 916 1031 | 
             
                raise 'no package exists' if @packages.empty?
         | 
| 1032 | 
            +
                @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
         | 
| 917 1033 | 
             
              end
         | 
| 918 1034 |  | 
| 919 1035 | 
             
              def run_metaconfigs
         | 
| 920 | 
            -
                 | 
| 1036 | 
            +
                @config.load_script "#{@ardir}/metaconfig", self
         | 
| 921 1037 | 
             
                @packages.each do |name|
         | 
| 922 | 
            -
                   | 
| 1038 | 
            +
                  @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
         | 
| 923 1039 | 
             
                end
         | 
| 924 1040 | 
             
              end
         | 
| 925 1041 |  | 
| 1042 | 
            +
              attr_reader :packages
         | 
| 1043 | 
            +
             | 
| 1044 | 
            +
              def packages=(list)
         | 
| 1045 | 
            +
                raise 'package list is empty' if list.empty?
         | 
| 1046 | 
            +
                list.each do |name|
         | 
| 1047 | 
            +
                  raise "directory packages/#{name} does not exist"\
         | 
| 1048 | 
            +
                          unless File.dir?("#{@ardir}/packages/#{name}")
         | 
| 1049 | 
            +
                end
         | 
| 1050 | 
            +
                @packages = list
         | 
| 1051 | 
            +
              end
         | 
| 1052 | 
            +
             | 
| 926 1053 | 
             
              def init_installers
         | 
| 927 1054 | 
             
                @installers = {}
         | 
| 928 1055 | 
             
                @packages.each do |pack|
         | 
| 929 | 
            -
                  @installers[pack] = Installer.new(@config, | 
| 1056 | 
            +
                  @installers[pack] = Installer.new(@config,
         | 
| 930 1057 | 
             
                                                   "#{@ardir}/packages/#{pack}",
         | 
| 931 1058 | 
             
                                                   "packages/#{pack}")
         | 
| 932 1059 | 
             
                end
         | 
| 933 | 
            -
             | 
| 934 1060 | 
             
                with    = extract_selection(config('with'))
         | 
| 935 1061 | 
             
                without = extract_selection(config('without'))
         | 
| 936 1062 | 
             
                @selected = @installers.keys.select {|name|
         | 
| @@ -954,21 +1080,6 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 954 1080 | 
             
                f.puts
         | 
| 955 1081 | 
             
              end
         | 
| 956 1082 |  | 
| 957 | 
            -
              #
         | 
| 958 | 
            -
              # multi-package metaconfig API
         | 
| 959 | 
            -
              #
         | 
| 960 | 
            -
             | 
| 961 | 
            -
              attr_reader :packages
         | 
| 962 | 
            -
             | 
| 963 | 
            -
              def declare_packages(list)
         | 
| 964 | 
            -
                raise 'package list is empty' if list.empty?
         | 
| 965 | 
            -
                list.each do |name|
         | 
| 966 | 
            -
                  raise "directory packages/#{name} does not exist"\
         | 
| 967 | 
            -
                          unless File.dir?("#{@ardir}/packages/#{name}")
         | 
| 968 | 
            -
                end
         | 
| 969 | 
            -
                @packages = list
         | 
| 970 | 
            -
              end
         | 
| 971 | 
            -
             | 
| 972 1083 | 
             
              #
         | 
| 973 1084 | 
             
              # Task Handlers
         | 
| 974 1085 | 
             
              #
         | 
| @@ -992,15 +1103,21 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 992 1103 | 
             
                run_hook 'post-install'
         | 
| 993 1104 | 
             
              end
         | 
| 994 1105 |  | 
| 1106 | 
            +
              def exec_test
         | 
| 1107 | 
            +
                run_hook 'pre-test'
         | 
| 1108 | 
            +
                each_selected_installers {|inst| inst.exec_test }
         | 
| 1109 | 
            +
                run_hook 'post-test'
         | 
| 1110 | 
            +
              end
         | 
| 1111 | 
            +
             | 
| 995 1112 | 
             
              def exec_clean
         | 
| 996 | 
            -
                rm_f  | 
| 1113 | 
            +
                rm_f @config.savefile
         | 
| 997 1114 | 
             
                run_hook 'pre-clean'
         | 
| 998 1115 | 
             
                each_selected_installers {|inst| inst.exec_clean }
         | 
| 999 1116 | 
             
                run_hook 'post-clean'
         | 
| 1000 1117 | 
             
              end
         | 
| 1001 1118 |  | 
| 1002 1119 | 
             
              def exec_distclean
         | 
| 1003 | 
            -
                rm_f  | 
| 1120 | 
            +
                rm_f @config.savefile
         | 
| 1004 1121 | 
             
                run_hook 'pre-distclean'
         | 
| 1005 1122 | 
             
                each_selected_installers {|inst| inst.exec_distclean }
         | 
| 1006 1123 | 
             
                run_hook 'post-distclean'
         | 
| @@ -1013,7 +1130,7 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 1013 1130 | 
             
              def each_selected_installers
         | 
| 1014 1131 | 
             
                Dir.mkdir 'packages' unless File.dir?('packages')
         | 
| 1015 1132 | 
             
                @selected.each do |pack|
         | 
| 1016 | 
            -
                  $stderr.puts "Processing the package `#{pack}' ..." if  | 
| 1133 | 
            +
                  $stderr.puts "Processing the package `#{pack}' ..." if verbose?
         | 
| 1017 1134 | 
             
                  Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
         | 
| 1018 1135 | 
             
                  Dir.chdir "packages/#{pack}"
         | 
| 1019 1136 | 
             
                  yield @installers[pack]
         | 
| @@ -1021,28 +1138,32 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 1021 1138 | 
             
                end
         | 
| 1022 1139 | 
             
              end
         | 
| 1023 1140 |  | 
| 1141 | 
            +
              def run_hook(id)
         | 
| 1142 | 
            +
                @root_installer.run_hook id
         | 
| 1143 | 
            +
              end
         | 
| 1144 | 
            +
             | 
| 1145 | 
            +
              # module FileOperations requires this
         | 
| 1024 1146 | 
             
              def verbose?
         | 
| 1025 | 
            -
                @ | 
| 1147 | 
            +
                @config.verbose?
         | 
| 1026 1148 | 
             
              end
         | 
| 1027 1149 |  | 
| 1150 | 
            +
              # module FileOperations requires this
         | 
| 1028 1151 | 
             
              def no_harm?
         | 
| 1029 | 
            -
                @ | 
| 1152 | 
            +
                @config.no_harm?
         | 
| 1030 1153 | 
             
              end
         | 
| 1031 1154 |  | 
| 1032 | 
            -
            end
         | 
| 1155 | 
            +
            end   # class ToplevelInstallerMulti
         | 
| 1033 1156 |  | 
| 1034 1157 |  | 
| 1035 1158 | 
             
            class Installer
         | 
| 1036 1159 |  | 
| 1037 | 
            -
              FILETYPES = %w( bin lib ext data )
         | 
| 1160 | 
            +
              FILETYPES = %w( bin lib ext data conf man )
         | 
| 1038 1161 |  | 
| 1039 | 
            -
              include HookScriptAPI
         | 
| 1040 | 
            -
              include HookUtils
         | 
| 1041 1162 | 
             
              include FileOperations
         | 
| 1163 | 
            +
              include HookScriptAPI
         | 
| 1042 1164 |  | 
| 1043 | 
            -
              def initialize(config,  | 
| 1165 | 
            +
              def initialize(config, srcroot, objroot)
         | 
| 1044 1166 | 
             
                @config = config
         | 
| 1045 | 
            -
                @options = opt
         | 
| 1046 1167 | 
             
                @srcdir = File.expand_path(srcroot)
         | 
| 1047 1168 | 
             
                @objdir = File.expand_path(objroot)
         | 
| 1048 1169 | 
             
                @currdir = '.'
         | 
| @@ -1052,6 +1173,9 @@ class Installer | |
| 1052 1173 | 
             
                "#<#{self.class} #{File.basename(@srcdir)}>"
         | 
| 1053 1174 | 
             
              end
         | 
| 1054 1175 |  | 
| 1176 | 
            +
              def noop(rel)
         | 
| 1177 | 
            +
              end
         | 
| 1178 | 
            +
             | 
| 1055 1179 | 
             
              #
         | 
| 1056 1180 | 
             
              # Hook Script API base methods
         | 
| 1057 1181 | 
             
              #
         | 
| @@ -1069,23 +1193,25 @@ class Installer | |
| 1069 1193 | 
             
              end
         | 
| 1070 1194 |  | 
| 1071 1195 | 
             
              #
         | 
| 1072 | 
            -
              #  | 
| 1196 | 
            +
              # Config Access
         | 
| 1073 1197 | 
             
              #
         | 
| 1074 1198 |  | 
| 1075 | 
            -
               | 
| 1076 | 
            -
             | 
| 1199 | 
            +
              # module FileOperations requires this
         | 
| 1200 | 
            +
              def verbose?
         | 
| 1201 | 
            +
                @config.verbose?
         | 
| 1077 1202 | 
             
              end
         | 
| 1078 1203 |  | 
| 1079 | 
            -
               | 
| 1080 | 
            -
             | 
| 1204 | 
            +
              # module FileOperations requires this
         | 
| 1205 | 
            +
              def no_harm?
         | 
| 1206 | 
            +
                @config.no_harm?
         | 
| 1081 1207 | 
             
              end
         | 
| 1082 1208 |  | 
| 1083 1209 | 
             
              def verbose_off
         | 
| 1084 1210 | 
             
                begin
         | 
| 1085 | 
            -
                  save, @ | 
| 1211 | 
            +
                  save, @config.verbose = @config.verbose?, false
         | 
| 1086 1212 | 
             
                  yield
         | 
| 1087 1213 | 
             
                ensure
         | 
| 1088 | 
            -
                  @ | 
| 1214 | 
            +
                  @config.verbose = save
         | 
| 1089 1215 | 
             
                end
         | 
| 1090 1216 | 
             
              end
         | 
| 1091 1217 |  | 
| @@ -1097,22 +1223,19 @@ class Installer | |
| 1097 1223 | 
             
                exec_task_traverse 'config'
         | 
| 1098 1224 | 
             
              end
         | 
| 1099 1225 |  | 
| 1100 | 
            -
               | 
| 1101 | 
            -
               | 
| 1102 | 
            -
             | 
| 1103 | 
            -
              def config_dir_lib(rel)
         | 
| 1104 | 
            -
              end
         | 
| 1226 | 
            +
              alias config_dir_bin noop
         | 
| 1227 | 
            +
              alias config_dir_lib noop
         | 
| 1105 1228 |  | 
| 1106 1229 | 
             
              def config_dir_ext(rel)
         | 
| 1107 1230 | 
             
                extconf if extdir?(curr_srcdir())
         | 
| 1108 1231 | 
             
              end
         | 
| 1109 1232 |  | 
| 1110 | 
            -
               | 
| 1111 | 
            -
             | 
| 1112 | 
            -
             | 
| 1113 | 
            -
              end
         | 
| 1233 | 
            +
              alias config_dir_data noop
         | 
| 1234 | 
            +
              alias config_dir_conf noop
         | 
| 1235 | 
            +
              alias config_dir_man noop
         | 
| 1114 1236 |  | 
| 1115 | 
            -
              def  | 
| 1237 | 
            +
              def extconf
         | 
| 1238 | 
            +
                ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
         | 
| 1116 1239 | 
             
              end
         | 
| 1117 1240 |  | 
| 1118 1241 | 
             
              #
         | 
| @@ -1124,39 +1247,90 @@ class Installer | |
| 1124 1247 | 
             
              end
         | 
| 1125 1248 |  | 
| 1126 1249 | 
             
              def setup_dir_bin(rel)
         | 
| 1127 | 
            -
                 | 
| 1128 | 
            -
                   | 
| 1250 | 
            +
                files_of(curr_srcdir()).each do |fname|
         | 
| 1251 | 
            +
                  update_shebang_line "#{curr_srcdir()}/#{fname}"
         | 
| 1129 1252 | 
             
                end
         | 
| 1130 1253 | 
             
              end
         | 
| 1131 1254 |  | 
| 1132 | 
            -
               | 
| 1255 | 
            +
              alias setup_dir_lib noop
         | 
| 1256 | 
            +
             | 
| 1257 | 
            +
              def setup_dir_ext(rel)
         | 
| 1258 | 
            +
                make if extdir?(curr_srcdir())
         | 
| 1259 | 
            +
              end
         | 
| 1260 | 
            +
             | 
| 1261 | 
            +
              alias setup_dir_data noop
         | 
| 1262 | 
            +
              alias setup_dir_conf noop
         | 
| 1263 | 
            +
              alias setup_dir_man noop
         | 
| 1264 | 
            +
             | 
| 1265 | 
            +
              def update_shebang_line(path)
         | 
| 1133 1266 | 
             
                return if no_harm?
         | 
| 1267 | 
            +
                return if config('shebang') == 'never'
         | 
| 1268 | 
            +
                old = Shebang.load(path)
         | 
| 1269 | 
            +
                if old
         | 
| 1270 | 
            +
                  $stderr.puts "warning: #{path}: Shebang line includes too many args.  It is not portable and your program may not work." if old.args.size > 1
         | 
| 1271 | 
            +
                  new = new_shebang(old)
         | 
| 1272 | 
            +
                  return if new.to_s == old.to_s
         | 
| 1273 | 
            +
                else
         | 
| 1274 | 
            +
                  return unless config('shebang') == 'all'
         | 
| 1275 | 
            +
                  new = Shebang.new(config('rubypath'))
         | 
| 1276 | 
            +
                end
         | 
| 1277 | 
            +
                $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
         | 
| 1278 | 
            +
                open_atomic_writer(path) {|output|
         | 
| 1279 | 
            +
                  File.open(path, 'rb') {|f|
         | 
| 1280 | 
            +
                    f.gets if old   # discard
         | 
| 1281 | 
            +
                    output.puts new.to_s
         | 
| 1282 | 
            +
                    output.print f.read
         | 
| 1283 | 
            +
                  }
         | 
| 1284 | 
            +
                }
         | 
| 1285 | 
            +
              end
         | 
| 1286 | 
            +
             | 
| 1287 | 
            +
              def new_shebang(old)
         | 
| 1288 | 
            +
                if /\Aruby/ =~ File.basename(old.cmd)
         | 
| 1289 | 
            +
                  Shebang.new(config('rubypath'), old.args)
         | 
| 1290 | 
            +
                elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
         | 
| 1291 | 
            +
                  Shebang.new(config('rubypath'), old.args[1..-1])
         | 
| 1292 | 
            +
                else
         | 
| 1293 | 
            +
                  return old unless config('shebang') == 'all'
         | 
| 1294 | 
            +
                  Shebang.new(config('rubypath'))
         | 
| 1295 | 
            +
                end
         | 
| 1296 | 
            +
              end
         | 
| 1297 | 
            +
             | 
| 1298 | 
            +
              def open_atomic_writer(path, &block)
         | 
| 1134 1299 | 
             
                tmpfile = File.basename(path) + '.tmp'
         | 
| 1135 1300 | 
             
                begin
         | 
| 1136 | 
            -
                  File.open( | 
| 1137 | 
            -
             | 
| 1138 | 
            -
                    return unless File.basename(config('rubypath')) == 'ruby'
         | 
| 1139 | 
            -
                    return unless File.basename(first.sub(/\A\#!/, '').split[0]) == 'ruby'
         | 
| 1140 | 
            -
                    $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose?
         | 
| 1141 | 
            -
                    File.open(tmpfile, 'wb') {|w|
         | 
| 1142 | 
            -
                      w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath'))
         | 
| 1143 | 
            -
                      w.write r.read
         | 
| 1144 | 
            -
                    }
         | 
| 1145 | 
            -
                    move_file tmpfile, File.basename(path)
         | 
| 1146 | 
            -
                  }
         | 
| 1301 | 
            +
                  File.open(tmpfile, 'wb', &block)
         | 
| 1302 | 
            +
                  File.rename tmpfile, File.basename(path)
         | 
| 1147 1303 | 
             
                ensure
         | 
| 1148 1304 | 
             
                  File.unlink tmpfile if File.exist?(tmpfile)
         | 
| 1149 1305 | 
             
                end
         | 
| 1150 1306 | 
             
              end
         | 
| 1151 1307 |  | 
| 1152 | 
            -
               | 
| 1153 | 
            -
             | 
| 1308 | 
            +
              class Shebang
         | 
| 1309 | 
            +
                def Shebang.load(path)
         | 
| 1310 | 
            +
                  line = nil
         | 
| 1311 | 
            +
                  File.open(path) {|f|
         | 
| 1312 | 
            +
                    line = f.gets
         | 
| 1313 | 
            +
                  }
         | 
| 1314 | 
            +
                  return nil unless /\A#!/ =~ line
         | 
| 1315 | 
            +
                  parse(line)
         | 
| 1316 | 
            +
                end
         | 
| 1154 1317 |  | 
| 1155 | 
            -
             | 
| 1156 | 
            -
             | 
| 1157 | 
            -
             | 
| 1318 | 
            +
                def Shebang.parse(line)
         | 
| 1319 | 
            +
                  cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
         | 
| 1320 | 
            +
                  new(cmd, args)
         | 
| 1321 | 
            +
                end
         | 
| 1322 | 
            +
             | 
| 1323 | 
            +
                def initialize(cmd, args = [])
         | 
| 1324 | 
            +
                  @cmd = cmd
         | 
| 1325 | 
            +
                  @args = args
         | 
| 1326 | 
            +
                end
         | 
| 1158 1327 |  | 
| 1159 | 
            -
             | 
| 1328 | 
            +
                attr_reader :cmd
         | 
| 1329 | 
            +
                attr_reader :args
         | 
| 1330 | 
            +
             | 
| 1331 | 
            +
                def to_s
         | 
| 1332 | 
            +
                  "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
         | 
| 1333 | 
            +
                end
         | 
| 1160 1334 | 
             
              end
         | 
| 1161 1335 |  | 
| 1162 1336 | 
             
              #
         | 
| @@ -1169,63 +1343,77 @@ class Installer | |
| 1169 1343 | 
             
              end
         | 
| 1170 1344 |  | 
| 1171 1345 | 
             
              def install_dir_bin(rel)
         | 
| 1172 | 
            -
                install_files  | 
| 1346 | 
            +
                install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
         | 
| 1173 1347 | 
             
              end
         | 
| 1174 1348 |  | 
| 1175 1349 | 
             
              def install_dir_lib(rel)
         | 
| 1176 | 
            -
                install_files  | 
| 1350 | 
            +
                install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
         | 
| 1177 1351 | 
             
              end
         | 
| 1178 1352 |  | 
| 1179 1353 | 
             
              def install_dir_ext(rel)
         | 
| 1180 1354 | 
             
                return unless extdir?(curr_srcdir())
         | 
| 1181 | 
            -
                install_files  | 
| 1355 | 
            +
                install_files rubyextentions('.'),
         | 
| 1182 1356 | 
             
                              "#{config('sodir')}/#{File.dirname(rel)}",
         | 
| 1183 1357 | 
             
                              0555
         | 
| 1184 1358 | 
             
              end
         | 
| 1185 1359 |  | 
| 1186 1360 | 
             
              def install_dir_data(rel)
         | 
| 1187 | 
            -
                install_files  | 
| 1361 | 
            +
                install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
         | 
| 1362 | 
            +
              end
         | 
| 1363 | 
            +
             | 
| 1364 | 
            +
              def install_dir_conf(rel)
         | 
| 1365 | 
            +
                # FIXME: should not remove current config files
         | 
| 1366 | 
            +
                # (rename previous file to .old/.org)
         | 
| 1367 | 
            +
                install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
         | 
| 1368 | 
            +
              end
         | 
| 1369 | 
            +
             | 
| 1370 | 
            +
              def install_dir_man(rel)
         | 
| 1371 | 
            +
                install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
         | 
| 1188 1372 | 
             
              end
         | 
| 1189 1373 |  | 
| 1190 1374 | 
             
              def install_files(list, dest, mode)
         | 
| 1191 | 
            -
                mkdir_p dest, @ | 
| 1375 | 
            +
                mkdir_p dest, @config.install_prefix
         | 
| 1192 1376 | 
             
                list.each do |fname|
         | 
| 1193 | 
            -
                  install fname, dest, mode, @ | 
| 1377 | 
            +
                  install fname, dest, mode, @config.install_prefix
         | 
| 1194 1378 | 
             
                end
         | 
| 1195 1379 | 
             
              end
         | 
| 1196 1380 |  | 
| 1197 | 
            -
              def  | 
| 1198 | 
            -
                 | 
| 1381 | 
            +
              def libfiles
         | 
| 1382 | 
            +
                glob_reject(%w(*.y *.output), targetfiles())
         | 
| 1199 1383 | 
             
              end
         | 
| 1200 | 
            -
             | 
| 1384 | 
            +
             | 
| 1385 | 
            +
              def rubyextentions(dir)
         | 
| 1386 | 
            +
                ents = glob_select("*.#{@config.dllext}", targetfiles())
         | 
| 1387 | 
            +
                if ents.empty?
         | 
| 1388 | 
            +
                  setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
         | 
| 1389 | 
            +
                end
         | 
| 1390 | 
            +
                ents
         | 
| 1391 | 
            +
              end
         | 
| 1392 | 
            +
             | 
| 1393 | 
            +
              def targetfiles
         | 
| 1394 | 
            +
                mapdir(existfiles() - hookfiles())
         | 
| 1395 | 
            +
              end
         | 
| 1396 | 
            +
             | 
| 1397 | 
            +
              def mapdir(ents)
         | 
| 1398 | 
            +
                ents.map {|ent|
         | 
| 1399 | 
            +
                  if File.exist?(ent)
         | 
| 1400 | 
            +
                  then ent                         # objdir
         | 
| 1401 | 
            +
                  else "#{curr_srcdir()}/#{ent}"   # srcdir
         | 
| 1402 | 
            +
                  end
         | 
| 1403 | 
            +
                }
         | 
| 1404 | 
            +
              end
         | 
| 1405 | 
            +
             | 
| 1201 1406 | 
             
              # picked up many entries from cvs-1.11.1/src/ignore.c
         | 
| 1202 | 
            -
               | 
| 1407 | 
            +
              JUNK_FILES = %w( 
         | 
| 1203 1408 | 
             
                core RCSLOG tags TAGS .make.state
         | 
| 1204 1409 | 
             
                .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
         | 
| 1205 1410 | 
             
                *~ *.old *.bak *.BAK *.orig *.rej _$* *$
         | 
| 1206 1411 |  | 
| 1207 1412 | 
             
                *.org *.in .*
         | 
| 1208 1413 | 
             
              )
         | 
| 1209 | 
            -
              mapping = {
         | 
| 1210 | 
            -
                '.' => '\.',
         | 
| 1211 | 
            -
                '$' => '\$',
         | 
| 1212 | 
            -
                '#' => '\#',
         | 
| 1213 | 
            -
                '*' => '.*'
         | 
| 1214 | 
            -
              }
         | 
| 1215 | 
            -
              REJECT_PATTERNS = Regexp.new('\A(?:' +
         | 
| 1216 | 
            -
                                           reject_patterns.map {|pat|
         | 
| 1217 | 
            -
                                             pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
         | 
| 1218 | 
            -
                                           }.join('|') +
         | 
| 1219 | 
            -
                                           ')\z')
         | 
| 1220 | 
            -
             | 
| 1221 | 
            -
              def collect_filenames_auto
         | 
| 1222 | 
            -
                mapdir((existfiles() - hookfiles()).reject {|fname|
         | 
| 1223 | 
            -
                         REJECT_PATTERNS =~ fname
         | 
| 1224 | 
            -
                       })
         | 
| 1225 | 
            -
              end
         | 
| 1226 1414 |  | 
| 1227 1415 | 
             
              def existfiles
         | 
| 1228 | 
            -
                 | 
| 1416 | 
            +
                glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
         | 
| 1229 1417 | 
             
              end
         | 
| 1230 1418 |  | 
| 1231 1419 | 
             
              def hookfiles
         | 
| @@ -1234,24 +1422,49 @@ class Installer | |
| 1234 1422 | 
             
                }.flatten
         | 
| 1235 1423 | 
             
              end
         | 
| 1236 1424 |  | 
| 1237 | 
            -
              def  | 
| 1238 | 
            -
                 | 
| 1239 | 
            -
             | 
| 1240 | 
            -
                    fname
         | 
| 1241 | 
            -
                  else                    # srcdir
         | 
| 1242 | 
            -
                    File.join(curr_srcdir(), fname)
         | 
| 1243 | 
            -
                  end
         | 
| 1244 | 
            -
                }
         | 
| 1425 | 
            +
              def glob_select(pat, ents)
         | 
| 1426 | 
            +
                re = globs2re([pat])
         | 
| 1427 | 
            +
                ents.select {|ent| re =~ ent }
         | 
| 1245 1428 | 
             
              end
         | 
| 1246 1429 |  | 
| 1247 | 
            -
              def  | 
| 1248 | 
            -
                 | 
| 1249 | 
            -
             | 
| 1250 | 
            -
             | 
| 1251 | 
            -
             | 
| 1252 | 
            -
             | 
| 1253 | 
            -
             | 
| 1254 | 
            -
                 | 
| 1430 | 
            +
              def glob_reject(pats, ents)
         | 
| 1431 | 
            +
                re = globs2re(pats)
         | 
| 1432 | 
            +
                ents.reject {|ent| re =~ ent }
         | 
| 1433 | 
            +
              end
         | 
| 1434 | 
            +
             | 
| 1435 | 
            +
              GLOB2REGEX = {
         | 
| 1436 | 
            +
                '.' => '\.',
         | 
| 1437 | 
            +
                '$' => '\$',
         | 
| 1438 | 
            +
                '#' => '\#',
         | 
| 1439 | 
            +
                '*' => '.*'
         | 
| 1440 | 
            +
              }
         | 
| 1441 | 
            +
             | 
| 1442 | 
            +
              def globs2re(pats)
         | 
| 1443 | 
            +
                /\A(?:#{
         | 
| 1444 | 
            +
                  pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
         | 
| 1445 | 
            +
                })\z/
         | 
| 1446 | 
            +
              end
         | 
| 1447 | 
            +
             | 
| 1448 | 
            +
              #
         | 
| 1449 | 
            +
              # TASK test
         | 
| 1450 | 
            +
              #
         | 
| 1451 | 
            +
             | 
| 1452 | 
            +
              TESTDIR = 'test'
         | 
| 1453 | 
            +
             | 
| 1454 | 
            +
              def exec_test
         | 
| 1455 | 
            +
                unless File.directory?('test')
         | 
| 1456 | 
            +
                  $stderr.puts 'no test in this package' if verbose?
         | 
| 1457 | 
            +
                  return
         | 
| 1458 | 
            +
                end
         | 
| 1459 | 
            +
                $stderr.puts 'Running tests...' if verbose?
         | 
| 1460 | 
            +
                begin
         | 
| 1461 | 
            +
                  require 'test/unit'
         | 
| 1462 | 
            +
                rescue LoadError
         | 
| 1463 | 
            +
                  setup_rb_error 'test/unit cannot loaded.  You need Ruby 1.8 or later to invoke this task.'
         | 
| 1464 | 
            +
                end
         | 
| 1465 | 
            +
                runner = Test::Unit::AutoRunner.new(true)
         | 
| 1466 | 
            +
                runner.to_run << TESTDIR
         | 
| 1467 | 
            +
                runner.run
         | 
| 1255 1468 | 
             
              end
         | 
| 1256 1469 |  | 
| 1257 1470 | 
             
              #
         | 
| @@ -1260,53 +1473,51 @@ class Installer | |
| 1260 1473 |  | 
| 1261 1474 | 
             
              def exec_clean
         | 
| 1262 1475 | 
             
                exec_task_traverse 'clean'
         | 
| 1263 | 
            -
                rm_f  | 
| 1476 | 
            +
                rm_f @config.savefile
         | 
| 1264 1477 | 
             
                rm_f 'InstalledFiles'
         | 
| 1265 1478 | 
             
              end
         | 
| 1266 1479 |  | 
| 1267 | 
            -
               | 
| 1268 | 
            -
               | 
| 1269 | 
            -
             | 
| 1270 | 
            -
               | 
| 1271 | 
            -
               | 
| 1480 | 
            +
              alias clean_dir_bin noop
         | 
| 1481 | 
            +
              alias clean_dir_lib noop
         | 
| 1482 | 
            +
              alias clean_dir_data noop
         | 
| 1483 | 
            +
              alias clean_dir_conf noop
         | 
| 1484 | 
            +
              alias clean_dir_man noop
         | 
| 1272 1485 |  | 
| 1273 1486 | 
             
              def clean_dir_ext(rel)
         | 
| 1274 1487 | 
             
                return unless extdir?(curr_srcdir())
         | 
| 1275 1488 | 
             
                make 'clean' if File.file?('Makefile')
         | 
| 1276 1489 | 
             
              end
         | 
| 1277 1490 |  | 
| 1278 | 
            -
              def clean_dir_data(rel)
         | 
| 1279 | 
            -
              end
         | 
| 1280 | 
            -
             | 
| 1281 1491 | 
             
              #
         | 
| 1282 1492 | 
             
              # TASK distclean
         | 
| 1283 1493 | 
             
              #
         | 
| 1284 1494 |  | 
| 1285 1495 | 
             
              def exec_distclean
         | 
| 1286 1496 | 
             
                exec_task_traverse 'distclean'
         | 
| 1287 | 
            -
                rm_f  | 
| 1497 | 
            +
                rm_f @config.savefile
         | 
| 1288 1498 | 
             
                rm_f 'InstalledFiles'
         | 
| 1289 1499 | 
             
              end
         | 
| 1290 1500 |  | 
| 1291 | 
            -
               | 
| 1292 | 
            -
               | 
| 1293 | 
            -
             | 
| 1294 | 
            -
              def distclean_dir_lib(rel)
         | 
| 1295 | 
            -
              end
         | 
| 1501 | 
            +
              alias distclean_dir_bin noop
         | 
| 1502 | 
            +
              alias distclean_dir_lib noop
         | 
| 1296 1503 |  | 
| 1297 1504 | 
             
              def distclean_dir_ext(rel)
         | 
| 1298 1505 | 
             
                return unless extdir?(curr_srcdir())
         | 
| 1299 1506 | 
             
                make 'distclean' if File.file?('Makefile')
         | 
| 1300 1507 | 
             
              end
         | 
| 1301 1508 |  | 
| 1509 | 
            +
              alias distclean_dir_data noop
         | 
| 1510 | 
            +
              alias distclean_dir_conf noop
         | 
| 1511 | 
            +
              alias distclean_dir_man noop
         | 
| 1512 | 
            +
             | 
| 1302 1513 | 
             
              #
         | 
| 1303 | 
            -
              #  | 
| 1514 | 
            +
              # Traversing
         | 
| 1304 1515 | 
             
              #
         | 
| 1305 1516 |  | 
| 1306 1517 | 
             
              def exec_task_traverse(task)
         | 
| 1307 1518 | 
             
                run_hook "pre-#{task}"
         | 
| 1308 1519 | 
             
                FILETYPES.each do |type|
         | 
| 1309 | 
            -
                  if config('without-ext') == 'yes' | 
| 1520 | 
            +
                  if type == 'ext' and config('without-ext') == 'yes'
         | 
| 1310 1521 | 
             
                    $stderr.puts 'skipping ext/* by user option' if verbose?
         | 
| 1311 1522 | 
             
                    next
         | 
| 1312 1523 | 
             
                  end
         | 
| @@ -1319,7 +1530,7 @@ class Installer | |
| 1319 1530 | 
             
                dive_into(rel) {
         | 
| 1320 1531 | 
             
                  run_hook "pre-#{task}"
         | 
| 1321 1532 | 
             
                  __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
         | 
| 1322 | 
            -
                   | 
| 1533 | 
            +
                  directories_of(curr_srcdir()).each do |d|
         | 
| 1323 1534 | 
             
                    traverse task, "#{rel}/#{d}", mid
         | 
| 1324 1535 | 
             
                  end
         | 
| 1325 1536 | 
             
                  run_hook "post-#{task}"
         | 
| @@ -1341,16 +1552,30 @@ class Installer | |
| 1341 1552 | 
             
                @currdir = File.dirname(rel)
         | 
| 1342 1553 | 
             
              end
         | 
| 1343 1554 |  | 
| 1344 | 
            -
             | 
| 1555 | 
            +
              def run_hook(id)
         | 
| 1556 | 
            +
                path = [ "#{curr_srcdir()}/#{id}",
         | 
| 1557 | 
            +
                         "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
         | 
| 1558 | 
            +
                return unless path
         | 
| 1559 | 
            +
                begin
         | 
| 1560 | 
            +
                  instance_eval File.read(path), path, 1
         | 
| 1561 | 
            +
                rescue
         | 
| 1562 | 
            +
                  raise if $DEBUG
         | 
| 1563 | 
            +
                  setup_rb_error "hook #{path} failed:\n" + $!.message
         | 
| 1564 | 
            +
                end
         | 
| 1565 | 
            +
              end
         | 
| 1566 | 
            +
             | 
| 1567 | 
            +
            end   # class Installer
         | 
| 1568 | 
            +
             | 
| 1569 | 
            +
             | 
| 1570 | 
            +
            class SetupError < StandardError; end
         | 
| 1345 1571 |  | 
| 1572 | 
            +
            def setup_rb_error(msg)
         | 
| 1573 | 
            +
              raise SetupError, msg
         | 
| 1574 | 
            +
            end
         | 
| 1346 1575 |  | 
| 1347 1576 | 
             
            if $0 == __FILE__
         | 
| 1348 1577 | 
             
              begin
         | 
| 1349 | 
            -
                 | 
| 1350 | 
            -
                  ToplevelInstallerMulti.invoke
         | 
| 1351 | 
            -
                else
         | 
| 1352 | 
            -
                  ToplevelInstaller.invoke
         | 
| 1353 | 
            -
                end
         | 
| 1578 | 
            +
                ToplevelInstaller.invoke
         | 
| 1354 1579 | 
             
              rescue SetupError
         | 
| 1355 1580 | 
             
                raise if $DEBUG
         | 
| 1356 1581 | 
             
                $stderr.puts $!.message
         |