cgialt 0.0.2 → 1.0.0
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/CHANGES.txt +21 -2
- data/README.txt +22 -9
- data/bench.rb +3 -3
- data/lib/cgialt.rb +1 -1
- data/lib/cgialt/cookie.rb +7 -5
- data/lib/cgialt/core.rb +92 -70
- data/lib/cgialt/fcgi.rb +3 -3
- data/lib/cgialt/fcgi/cgi_helper.rb +4 -4
- data/lib/cgialt/fcgi/core.rb +50 -50
- data/lib/cgialt/util.rb +71 -27
- data/setup.rb +861 -607
- data/test/test_cgi_cookie.rb +1 -1
- data/test/test_cgi_core.rb +21 -2
- data/test/test_cgi_header.rb +1 -1
- data/test/test_cgi_modruby.rb +1 -1
- data/test/test_cgi_multipart.rb +29 -4
- data/test/test_cgi_util.rb +240 -0
- metadata +41 -33
    
        data/lib/cgialt/fcgi.rb
    CHANGED
    
    
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ##
         | 
| 2 | 
            -
            ## $Rev | 
| 3 | 
            -
            ## $Release: 0.0 | 
| 4 | 
            -
            ## copyright(c) 2007 kuwata-lab.com all rights reserved.
         | 
| 2 | 
            +
            ## $Rev$
         | 
| 3 | 
            +
            ## $Release: 1.0.0 $
         | 
| 4 | 
            +
            ## copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
         | 
| 5 5 | 
             
            ##
         | 
| 6 6 |  | 
| 7 7 | 
             
            =begin
         | 
| @@ -33,7 +33,7 @@ class FCGI | |
| 33 33 | 
             
                    $stderr = request.err
         | 
| 34 34 | 
             
                    #ENV.clear
         | 
| 35 35 | 
             
                    #ENV.update(request.env)
         | 
| 36 | 
            -
                    $CGI_ENV = request.env
         | 
| 36 | 
            +
                    $CGI_ENV = request.env       # TODO: remove dependency on $CGI_ENV
         | 
| 37 37 | 
             
                    yield CGI.new(arg)
         | 
| 38 38 | 
             
                    request.finish
         | 
| 39 39 | 
             
                  end
         | 
    
        data/lib/cgialt/fcgi/core.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ##
         | 
| 2 | 
            -
            ## $Rev | 
| 3 | 
            -
            ## $Release: 0.0 | 
| 4 | 
            -
            ## copyright(c) 2007 kuwata-lab.com all rights reserved.
         | 
| 2 | 
            +
            ## $Rev$
         | 
| 3 | 
            +
            ## $Release: 1.0.0 $
         | 
| 4 | 
            +
            ## copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
         | 
| 5 5 | 
             
            ##
         | 
| 6 6 |  | 
| 7 7 | 
             
            =begin
         | 
| @@ -109,7 +109,7 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 109 109 | 
             
                      exit 0 if graceful
         | 
| 110 110 | 
             
                    end
         | 
| 111 111 | 
             
                  end
         | 
| 112 | 
            -
             | 
| 112 | 
            +
             | 
| 113 113 | 
             
                  def session
         | 
| 114 114 | 
             
                    sock, addr = *@server.accept
         | 
| 115 115 | 
             
                    return unless sock
         | 
| @@ -126,17 +126,15 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 126 126 | 
             
                  def next_request(sock)
         | 
| 127 127 | 
             
                    while rec = sock.read_record
         | 
| 128 128 | 
             
                      if rec.management_record?
         | 
| 129 | 
            -
                         | 
| 130 | 
            -
                        when FCGI_GET_VALUES
         | 
| 129 | 
            +
                        if rec.type == FCGI_GET_VALUES
         | 
| 131 130 | 
             
                          sock.send_record handle_GET_VALUES(rec)
         | 
| 132 131 | 
             
                        else
         | 
| 133 132 | 
             
                          sock.send_record UnknownTypeRecord.new(rec.request_id, rec.type)
         | 
| 134 133 | 
             
                        end
         | 
| 135 134 | 
             
                      else
         | 
| 136 | 
            -
                         | 
| 137 | 
            -
                        when FCGI_BEGIN_REQUEST
         | 
| 135 | 
            +
                        if (rec_type = rec.type) == FCGI_BEGIN_REQUEST
         | 
| 138 136 | 
             
                          @buffers[rec.request_id] = RecordBuffer.new(rec)
         | 
| 139 | 
            -
                         | 
| 137 | 
            +
                        elsif rec_type == FCGI_ABORT_REQUEST
         | 
| 140 138 | 
             
                          raise "got ABORT_REQUEST"   # FIXME
         | 
| 141 139 | 
             
                        else
         | 
| 142 140 | 
             
                          buf = @buffers[rec.request_id]   or next # inactive request
         | 
| @@ -196,12 +194,13 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 196 194 | 
             
                    Record.class_for(type).parse(reqid, read_record_body(clen, padlen))
         | 
| 197 195 | 
             
                  end
         | 
| 198 196 |  | 
| 199 | 
            -
                  def read_record_body( | 
| 200 | 
            -
                    buf = ''
         | 
| 201 | 
            -
                    while buf.length <  | 
| 202 | 
            -
             | 
| 203 | 
            -
                    end
         | 
| 204 | 
            -
                    @socket.read | 
| 197 | 
            +
                  def read_record_body(content_len, padding_len)
         | 
| 198 | 
            +
                    #*buf = ''
         | 
| 199 | 
            +
                    #*while buf.length < content_len
         | 
| 200 | 
            +
                    #*  buf << @socket.read([1024, content_len - buf.length].min)
         | 
| 201 | 
            +
                    #*end
         | 
| 202 | 
            +
                    buf = @socket.read(content_len)
         | 
| 203 | 
            +
                    @socket.read padding_len if padding_len
         | 
| 205 204 | 
             
                    buf
         | 
| 206 205 | 
             
                  end
         | 
| 207 206 | 
             
                  private :read_record_body
         | 
| @@ -324,8 +323,7 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 324 323 | 
             
                    ::FCGI::ProtocolVersion
         | 
| 325 324 | 
             
                  end
         | 
| 326 325 |  | 
| 327 | 
            -
                  attr_reader :type
         | 
| 328 | 
            -
                  attr_reader :request_id
         | 
| 326 | 
            +
                  attr_reader :type, :request_id
         | 
| 329 327 |  | 
| 330 328 | 
             
                  def management_record?
         | 
| 331 329 | 
             
                    @request_id == FCGI_NULL_REQUEST_ID
         | 
| @@ -333,16 +331,21 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 333 331 |  | 
| 334 332 | 
             
                  def serialize
         | 
| 335 333 | 
             
                    body = make_body()
         | 
| 336 | 
            -
                     | 
| 337 | 
            -
                    header = make_header(body.length,  | 
| 338 | 
            -
                    header | 
| 334 | 
            +
                    padding_length = body.length % 8
         | 
| 335 | 
            +
                    header = make_header(body.length, padding_length)
         | 
| 336 | 
            +
                    "#{header}#{body}#{'\000' * padding_length}"
         | 
| 339 337 | 
             
                  end
         | 
| 340 338 |  | 
| 341 339 | 
             
                  private
         | 
| 342 340 |  | 
| 343 | 
            -
                  def make_header( | 
| 344 | 
            -
                    [ | 
| 341 | 
            +
                  def make_header(content_length, pading_length)
         | 
| 342 | 
            +
                    [::FCGI::ProtocolVersion, @type, @request_id, content_length, padding_length, 0].pack(HEADER_FORMAT)
         | 
| 343 | 
            +
                  end
         | 
| 344 | 
            +
             | 
| 345 | 
            +
                  def make_body
         | 
| 346 | 
            +
                    raise NotImplementedError.new("#{self.class.name}#make_body(): not implemented.")
         | 
| 345 347 | 
             
                  end
         | 
| 348 | 
            +
             | 
| 346 349 | 
             
                end
         | 
| 347 350 |  | 
| 348 351 | 
             
                class BeginRequestRecord < Record
         | 
| @@ -351,7 +354,7 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 351 354 | 
             
                  # uint8_t  reserved[5];
         | 
| 352 355 | 
             
                  BODY_FORMAT = 'nCC5'
         | 
| 353 356 |  | 
| 354 | 
            -
                  def  | 
| 357 | 
            +
                  def self.parse(id, body)
         | 
| 355 358 | 
             
                    role, flags, *reserved = *body.unpack(BODY_FORMAT)
         | 
| 356 359 | 
             
                    new(id, role, flags)
         | 
| 357 360 | 
             
                  end
         | 
| @@ -364,14 +367,14 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 364 367 |  | 
| 365 368 | 
             
                  attr_reader :role
         | 
| 366 369 | 
             
                  attr_reader :flags
         | 
| 367 | 
            -
             | 
| 370 | 
            +
             | 
| 368 371 | 
             
                  def make_body
         | 
| 369 372 | 
             
                    [@role, @flags, 0, 0, 0, 0, 0].pack(BODY_FORMAT)
         | 
| 370 373 | 
             
                  end
         | 
| 371 374 | 
             
                end
         | 
| 372 375 |  | 
| 373 376 | 
             
                class AbortRequestRecord < Record
         | 
| 374 | 
            -
                  def  | 
| 377 | 
            +
                  def self.parse(id, body)
         | 
| 375 378 | 
             
                    new(id)
         | 
| 376 379 | 
             
                  end
         | 
| 377 380 |  | 
| @@ -386,7 +389,7 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 386 389 | 
             
                  # uint8_t  reserved[3];
         | 
| 387 390 | 
             
                  BODY_FORMAT = 'NCC3'
         | 
| 388 391 |  | 
| 389 | 
            -
                  def self | 
| 392 | 
            +
                  def self.parse(id, body)
         | 
| 390 393 | 
             
                    appstatus, protostatus, *reserved = *body.unpack(BODY_FORMAT)
         | 
| 391 394 | 
             
                    new(id, appstatus, protostatus)
         | 
| 392 395 | 
             
                  end
         | 
| @@ -412,14 +415,14 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 412 415 | 
             
                  # uint8_t reserved[7];
         | 
| 413 416 | 
             
                  BODY_FORMAT = 'CC7'
         | 
| 414 417 |  | 
| 415 | 
            -
                  def self | 
| 418 | 
            +
                  def self.parse(id, body)
         | 
| 416 419 | 
             
                    type, *reserved = *body.unpack(BODY_FORMAT)
         | 
| 417 420 | 
             
                    new(id, type)
         | 
| 418 421 | 
             
                  end
         | 
| 419 422 |  | 
| 420 | 
            -
                  def initialize(id,  | 
| 423 | 
            +
                  def initialize(id, type)
         | 
| 421 424 | 
             
                    super FCGI_UNKNOWN_TYPE, id
         | 
| 422 | 
            -
                    @unknown_type =  | 
| 425 | 
            +
                    @unknown_type = type
         | 
| 423 426 | 
             
                  end
         | 
| 424 427 |  | 
| 425 428 | 
             
                  attr_reader :unknown_type
         | 
| @@ -439,28 +442,32 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 439 442 | 
             
                  def self::parse_values(buf)
         | 
| 440 443 | 
             
                    result = {}
         | 
| 441 444 | 
             
                    until buf.empty?
         | 
| 442 | 
            -
                      name, value = *read_pair(buf)
         | 
| 445 | 
            +
                      #*name, value = *read_pair(buf)
         | 
| 446 | 
            +
                      #*result[name] = value
         | 
| 447 | 
            +
                      name_len = read_length(buf)
         | 
| 448 | 
            +
                      value_len = read_length(buf)
         | 
| 449 | 
            +
                      name = buf.slice!(0, name_len)
         | 
| 450 | 
            +
                      value = buf.slice!(0, value_len)
         | 
| 443 451 | 
             
                      result[name] = value
         | 
| 444 452 | 
             
                    end
         | 
| 445 453 | 
             
                    result
         | 
| 446 454 | 
             
                  end
         | 
| 447 | 
            -
             | 
| 455 | 
            +
             | 
| 448 456 | 
             
                  def self::read_pair(buf)
         | 
| 449 | 
            -
                     | 
| 450 | 
            -
                     | 
| 451 | 
            -
                    return buf.slice!(0,  | 
| 457 | 
            +
                    name_len = read_length(buf)
         | 
| 458 | 
            +
                    value_len = read_length(buf)
         | 
| 459 | 
            +
                    return buf.slice!(0, name_len), buf.slice!(0, value_len)
         | 
| 452 460 | 
             
                  end
         | 
| 453 | 
            -
             | 
| 461 | 
            +
             | 
| 462 | 
            +
                  MASK = ((1<<31) - 1)
         | 
| 454 463 | 
             
                  def self::read_length(buf)
         | 
| 455 | 
            -
                     | 
| 456 | 
            -
             | 
| 457 | 
            -
                    else buf.slice!(0,4).unpack('N')[0] & ((1<<31) - 1)
         | 
| 458 | 
            -
                    end
         | 
| 464 | 
            +
                    buf[0] >> 7 == 0 ? buf.slice!(0,1)[0] \
         | 
| 465 | 
            +
                                     : buf.slice!(0,4).unpack('N')[0] & MASK
         | 
| 459 466 | 
             
                  end
         | 
| 460 467 |  | 
| 461 468 | 
             
                  def initialize(type, id, values)
         | 
| 462 469 | 
             
                    super type, id
         | 
| 463 | 
            -
                    @values = values
         | 
| 470 | 
            +
                    @values = values   # Hash
         | 
| 464 471 | 
             
                  end
         | 
| 465 472 |  | 
| 466 473 | 
             
                  attr_reader :values
         | 
| @@ -470,19 +477,13 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 470 477 | 
             
                  def make_body
         | 
| 471 478 | 
             
                    buf = ''
         | 
| 472 479 | 
             
                    @values.each do |name, value|
         | 
| 473 | 
            -
                      buf << serialize_length(name.length)
         | 
| 474 | 
            -
                      buf << serialize_length(value.length)
         | 
| 475 | 
            -
                      buf << name
         | 
| 476 | 
            -
                      buf << value
         | 
| 480 | 
            +
                      buf << "#{serialize_length(name.length)}#{serialize_length(value.length)}#{name}#{value}"
         | 
| 477 481 | 
             
                    end
         | 
| 478 482 | 
             
                    buf
         | 
| 479 483 | 
             
                  end
         | 
| 480 484 |  | 
| 481 485 | 
             
                  def serialize_length(len)
         | 
| 482 | 
            -
                     | 
| 483 | 
            -
                    then len.chr
         | 
| 484 | 
            -
                    else [len | (1<<31)].pack('N')
         | 
| 485 | 
            -
                    end
         | 
| 486 | 
            +
                    len < 128 ? len.chr : [len | (1<<31)].pack('N')
         | 
| 486 487 | 
             
                  end
         | 
| 487 488 | 
             
                end
         | 
| 488 489 |  | 
| @@ -507,7 +508,7 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 507 508 | 
             
                    new(id, body)
         | 
| 508 509 | 
             
                  end
         | 
| 509 510 |  | 
| 510 | 
            -
                  def initialize(type, id, flagment)
         | 
| 511 | 
            +
                  def initialize(type, id, flagment)   # abstract
         | 
| 511 512 | 
             
                    super type, id
         | 
| 512 513 | 
             
                    @flagment = flagment
         | 
| 513 514 | 
             
                  end
         | 
| @@ -558,4 +559,3 @@ fcgi.rb    Copyright (C) 2004 Minero Aoki | |
| 558 559 | 
             
                end
         | 
| 559 560 |  | 
| 560 561 | 
             
              end # FCGI class
         | 
| 561 | 
            -
             | 
    
        data/lib/cgialt/util.rb
    CHANGED
    
    | @@ -1,3 +1,9 @@ | |
| 1 | 
            +
            ##
         | 
| 2 | 
            +
            ## $Rev$
         | 
| 3 | 
            +
            ## $Release: 1.0.0 $
         | 
| 4 | 
            +
            ## copyright(c) 2007-2008 kuwata-lab.com all rights reserved.
         | 
| 5 | 
            +
            ##
         | 
| 6 | 
            +
             | 
| 1 7 | 
             
            ##
         | 
| 2 8 | 
             
            ## Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
         | 
| 3 9 | 
             
            ##
         | 
| @@ -41,39 +47,71 @@ class CGI | |
| 41 47 | 
             
              # Unescape a string that has been HTML-escaped
         | 
| 42 48 | 
             
              #   CGI::unescapeHTML("Usage: foo "bar" <baz>")
         | 
| 43 49 | 
             
              #      # => "Usage: foo \"bar\" <baz>"
         | 
| 44 | 
            -
              def  | 
| 45 | 
            -
                 | 
| 46 | 
            -
             | 
| 47 | 
            -
                   | 
| 48 | 
            -
             | 
| 49 | 
            -
                   | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
                   | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
                     | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
                      end
         | 
| 50 | 
            +
              def self.unescapeHTML(string)
         | 
| 51 | 
            +
                table = UNESCAPE_ENTITIES
         | 
| 52 | 
            +
                if "".respond_to?(:encoding)              # Ruby1.9
         | 
| 53 | 
            +
                  utf8_p = true       # really?
         | 
| 54 | 
            +
                else
         | 
| 55 | 
            +
                  utf8_p = $KCODE[0] == ?u || $KCODE[0] == ?U
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
                return string.gsub(/&#?[a-zA-F0-9]+;/n) do
         | 
| 58 | 
            +
                  match = $&
         | 
| 59 | 
            +
                  key = match[1..-2]
         | 
| 60 | 
            +
                  if (s = table[key])
         | 
| 61 | 
            +
                    s
         | 
| 62 | 
            +
                  elsif key =~ /\A#0*(\d+)\z/n
         | 
| 63 | 
            +
                    if   (v = Integer($1)) < 256 ;  v.chr
         | 
| 64 | 
            +
                    elsif v < 65536 && utf8_p    ;  [v].pack("U")
         | 
| 65 | 
            +
                    else                         ;  match
         | 
| 61 66 | 
             
                    end
         | 
| 62 | 
            -
                   | 
| 63 | 
            -
                    if $1.hex < 256
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                    else
         | 
| 66 | 
            -
                      if $1.hex < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)
         | 
| 67 | 
            -
                        [$1.hex].pack("U")
         | 
| 68 | 
            -
                      else
         | 
| 69 | 
            -
                        "&#x#{$1};"
         | 
| 70 | 
            -
                      end
         | 
| 67 | 
            +
                  elsif key =~ /\A#x([0-9a-f]+)\z/ni
         | 
| 68 | 
            +
                    if   (v = $1.hex) < 256      ;  v.chr
         | 
| 69 | 
            +
                    elsif v < 65536 && utf8_p    ;  [v].pack("U")
         | 
| 70 | 
            +
                    else                         ;  match
         | 
| 71 71 | 
             
                    end
         | 
| 72 72 | 
             
                  else
         | 
| 73 | 
            -
                     | 
| 73 | 
            +
                    match
         | 
| 74 74 | 
             
                  end
         | 
| 75 75 | 
             
                end
         | 
| 76 76 | 
             
              end
         | 
| 77 | 
            +
              UNESCAPE_ENTITIES = {
         | 
| 78 | 
            +
                'amp'=>'&', 'lt'=>'<', 'gt'=>'>', 'quot'=>'"',
         | 
| 79 | 
            +
              }
         | 
| 80 | 
            +
              #*** original
         | 
| 81 | 
            +
              #*def CGI::unescapeHTML(string)
         | 
| 82 | 
            +
              #*  string.gsub(/&(amp|quot|gt|lt|\#[0-9]+|\#x[0-9A-Fa-f]+);/n) do
         | 
| 83 | 
            +
              #*    match = $1.dup
         | 
| 84 | 
            +
              #*    case match
         | 
| 85 | 
            +
              #*    when 'amp'                 then '&'
         | 
| 86 | 
            +
              #*    when 'quot'                then '"'
         | 
| 87 | 
            +
              #*    when 'gt'                  then '>'
         | 
| 88 | 
            +
              #*    when 'lt'                  then '<'
         | 
| 89 | 
            +
              #*    when /\A#0*(\d+)\z/n       then
         | 
| 90 | 
            +
              #*      if Integer($1) < 256
         | 
| 91 | 
            +
              #*        Integer($1).chr
         | 
| 92 | 
            +
              #*      else
         | 
| 93 | 
            +
              #*        if Integer($1) < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)
         | 
| 94 | 
            +
              #*          [Integer($1)].pack("U")
         | 
| 95 | 
            +
              #*        else
         | 
| 96 | 
            +
              #*          "&##{$1};"
         | 
| 97 | 
            +
              #*        end
         | 
| 98 | 
            +
              #*      end
         | 
| 99 | 
            +
              #*    when /\A#x([0-9a-f]+)\z/ni then
         | 
| 100 | 
            +
              #*      if $1.hex < 256
         | 
| 101 | 
            +
              #*        $1.hex.chr
         | 
| 102 | 
            +
              #*      else
         | 
| 103 | 
            +
              #*        if $1.hex < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)
         | 
| 104 | 
            +
              #*          [$1.hex].pack("U")
         | 
| 105 | 
            +
              #*        else
         | 
| 106 | 
            +
              #*          "&#x#{$1};"
         | 
| 107 | 
            +
              #*        end
         | 
| 108 | 
            +
              #*      end
         | 
| 109 | 
            +
              #*    else
         | 
| 110 | 
            +
              #*      "&#{match};"
         | 
| 111 | 
            +
              #*    end
         | 
| 112 | 
            +
              #*  end
         | 
| 113 | 
            +
              #*end
         | 
| 114 | 
            +
              #*** /original
         | 
| 77 115 |  | 
| 78 116 |  | 
| 79 117 | 
             
              # Escape only the tags of certain HTML elements in +string+.
         | 
| @@ -133,6 +171,12 @@ class CGI | |
| 133 171 | 
             
                            t.hour, t.min, t.sec)
         | 
| 134 172 | 
             
              end
         | 
| 135 173 |  | 
| 174 | 
            +
              # Abbreviated day-of-week names specified by RFC 822
         | 
| 175 | 
            +
              RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ]
         | 
| 176 | 
            +
             | 
| 177 | 
            +
              # Abbreviated month names specified by RFC 822
         | 
| 178 | 
            +
              RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]
         | 
| 179 | 
            +
             | 
| 136 180 |  | 
| 137 181 | 
             
              # Prettify (indent) an HTML string.
         | 
| 138 182 | 
             
              #
         | 
    
        data/setup.rb
    CHANGED
    
    | @@ -1,70 +1,20 @@ | |
| 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
         | 
| 8 | 
            -
            # the GNU Lesser General Public License version 2.1.
         | 
| 8 | 
            +
            # the GNU LGPL, Lesser General Public License version 2.1.
         | 
| 9 9 | 
             
            #
         | 
| 10 10 |  | 
| 11 | 
            -
            #
         | 
| 12 | 
            -
            # For backward compatibility
         | 
| 13 | 
            -
            #
         | 
| 14 | 
            -
             | 
| 15 | 
            -
            unless Enumerable.method_defined?(:map)
         | 
| 11 | 
            +
            unless Enumerable.method_defined?(:map)   # Ruby 1.4.6
         | 
| 16 12 | 
             
              module Enumerable
         | 
| 17 13 | 
             
                alias map collect
         | 
| 18 14 | 
             
              end
         | 
| 19 15 | 
             
            end
         | 
| 20 16 |  | 
| 21 | 
            -
            unless  | 
| 22 | 
            -
              module Enumerable
         | 
| 23 | 
            -
                alias detect find
         | 
| 24 | 
            -
              end
         | 
| 25 | 
            -
            end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            unless Enumerable.method_defined?(:select)
         | 
| 28 | 
            -
              module Enumerable
         | 
| 29 | 
            -
                alias select find_all
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
            end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
            unless Enumerable.method_defined?(:reject)
         | 
| 34 | 
            -
              module Enumerable
         | 
| 35 | 
            -
                def reject
         | 
| 36 | 
            -
                  result = []
         | 
| 37 | 
            -
                  each do |i|
         | 
| 38 | 
            -
                    result.push i unless yield(i)
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
                  result
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
              end
         | 
| 43 | 
            -
            end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
            unless Enumerable.method_defined?(:inject)
         | 
| 46 | 
            -
              module Enumerable
         | 
| 47 | 
            -
                def inject(result)
         | 
| 48 | 
            -
                  each do |i|
         | 
| 49 | 
            -
                    result = yield(result, i)
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
                  result
         | 
| 52 | 
            -
                end
         | 
| 53 | 
            -
              end
         | 
| 54 | 
            -
            end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
            unless Enumerable.method_defined?(:any?)
         | 
| 57 | 
            -
              module Enumerable
         | 
| 58 | 
            -
                def any?
         | 
| 59 | 
            -
                  each do |i|
         | 
| 60 | 
            -
                    return true if yield(i)
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
                  false
         | 
| 63 | 
            -
                end
         | 
| 64 | 
            -
              end
         | 
| 65 | 
            -
            end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
            unless File.respond_to?(:read)
         | 
| 17 | 
            +
            unless File.respond_to?(:read)   # Ruby 1.6
         | 
| 68 18 | 
             
              def File.read(fname)
         | 
| 69 19 | 
             
                open(fname) {|f|
         | 
| 70 20 | 
             
                  return f.read
         | 
| @@ -72,9 +22,13 @@ unless File.respond_to?(:read) | |
| 72 22 | 
             
              end
         | 
| 73 23 | 
             
            end
         | 
| 74 24 |  | 
| 75 | 
            -
            #
         | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 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
         | 
| 78 32 |  | 
| 79 33 | 
             
            def File.binread(fname)
         | 
| 80 34 | 
             
              open(fname, 'rb') {|f|
         | 
| @@ -82,311 +36,512 @@ def File.binread(fname) | |
| 82 36 | 
             
              }
         | 
| 83 37 | 
             
            end
         | 
| 84 38 |  | 
| 85 | 
            -
            # for corrupted  | 
| 39 | 
            +
            # for corrupted Windows' stat(2)
         | 
| 86 40 | 
             
            def File.dir?(path)
         | 
| 87 41 | 
             
              File.directory?((path[-1,1] == '/') ? path : path + '/')
         | 
| 88 42 | 
             
            end
         | 
| 89 43 |  | 
| 90 | 
            -
            #
         | 
| 91 | 
            -
            # Config
         | 
| 92 | 
            -
            #
         | 
| 93 | 
            -
             | 
| 94 | 
            -
            if arg = ARGV.detect{|arg| /\A--rbconfig=/ =~ arg }
         | 
| 95 | 
            -
              ARGV.delete(arg)
         | 
| 96 | 
            -
              require arg.split(/=/, 2)[1]
         | 
| 97 | 
            -
              $".push 'rbconfig.rb'
         | 
| 98 | 
            -
            else
         | 
| 99 | 
            -
              require 'rbconfig'
         | 
| 100 | 
            -
            end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
            def multipackage_install?
         | 
| 103 | 
            -
              FileTest.directory?(File.dirname($0) + '/packages')
         | 
| 104 | 
            -
            end
         | 
| 105 | 
            -
             | 
| 106 44 |  | 
| 107 45 | 
             
            class ConfigTable
         | 
| 108 46 |  | 
| 109 | 
            -
               | 
| 47 | 
            +
              include Enumerable
         | 
| 110 48 |  | 
| 111 | 
            -
               | 
| 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
         | 
| 58 | 
            +
              end
         | 
| 112 59 |  | 
| 113 | 
            -
               | 
| 114 | 
            -
               | 
| 115 | 
            -
              teeny = c['TEENY'].to_i
         | 
| 116 | 
            -
              version = "#{major}.#{minor}"
         | 
| 60 | 
            +
              attr_accessor :install_prefix
         | 
| 61 | 
            +
              attr_accessor :config_opt
         | 
| 117 62 |  | 
| 118 | 
            -
               | 
| 119 | 
            -
              newpath_p = ((major >= 2) or
         | 
| 120 | 
            -
                           ((major == 1) and
         | 
| 121 | 
            -
                            ((minor >= 5) or
         | 
| 122 | 
            -
                             ((minor == 4) and (teeny >= 4)))))
         | 
| 123 | 
            -
              
         | 
| 124 | 
            -
              subprefix = lambda {|path|
         | 
| 125 | 
            -
                path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
         | 
| 126 | 
            -
              }
         | 
| 63 | 
            +
              attr_writer :verbose
         | 
| 127 64 |  | 
| 128 | 
            -
               | 
| 129 | 
            -
                 | 
| 130 | 
            -
                stdruby    = subprefix.call(c['rubylibdir'])
         | 
| 131 | 
            -
                siteruby   = subprefix.call(c['sitedir'])
         | 
| 132 | 
            -
                versite    = subprefix.call(c['sitelibdir'])
         | 
| 133 | 
            -
                sodir      = subprefix.call(c['sitearchdir'])
         | 
| 134 | 
            -
              elsif newpath_p
         | 
| 135 | 
            -
                # 1.4.4 <= V <= 1.6.3
         | 
| 136 | 
            -
                stdruby    = "$prefix/lib/ruby/#{version}"
         | 
| 137 | 
            -
                siteruby   = subprefix.call(c['sitedir'])
         | 
| 138 | 
            -
                versite    = siteruby + '/' + version
         | 
| 139 | 
            -
                sodir      = "$site-ruby/#{c['arch']}"
         | 
| 140 | 
            -
              else
         | 
| 141 | 
            -
                # V < 1.4.4
         | 
| 142 | 
            -
                stdruby    = "$prefix/lib/ruby/#{version}"
         | 
| 143 | 
            -
                siteruby   = "$prefix/lib/ruby/#{version}/site_ruby"
         | 
| 144 | 
            -
                versite    = siteruby
         | 
| 145 | 
            -
                sodir      = "$site-ruby/#{c['arch']}"
         | 
| 146 | 
            -
              end
         | 
| 147 | 
            -
             | 
| 148 | 
            -
              if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
         | 
| 149 | 
            -
                makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
         | 
| 150 | 
            -
              else
         | 
| 151 | 
            -
                makeprog = 'make'
         | 
| 152 | 
            -
              end
         | 
| 153 | 
            -
             | 
| 154 | 
            -
              common_descripters = [
         | 
| 155 | 
            -
                [ 'prefix',    [ c['prefix'],
         | 
| 156 | 
            -
                                 'path',
         | 
| 157 | 
            -
                                 'path prefix of target environment' ] ],
         | 
| 158 | 
            -
                [ 'std-ruby',  [ stdruby,
         | 
| 159 | 
            -
                                 'path',
         | 
| 160 | 
            -
                                 'the directory for standard ruby libraries' ] ],
         | 
| 161 | 
            -
                [ 'site-ruby-common', [ siteruby,
         | 
| 162 | 
            -
                                 'path',
         | 
| 163 | 
            -
                                 'the directory for version-independent non-standard ruby libraries' ] ],
         | 
| 164 | 
            -
                [ 'site-ruby', [ versite,
         | 
| 165 | 
            -
                                 'path',
         | 
| 166 | 
            -
                                 'the directory for non-standard ruby libraries' ] ],
         | 
| 167 | 
            -
                [ 'bin-dir',   [ '$prefix/bin',
         | 
| 168 | 
            -
                                 'path',
         | 
| 169 | 
            -
                                 'the directory for commands' ] ],
         | 
| 170 | 
            -
                [ 'rb-dir',    [ '$site-ruby',
         | 
| 171 | 
            -
                                 'path',
         | 
| 172 | 
            -
                                 'the directory for ruby scripts' ] ],
         | 
| 173 | 
            -
                [ 'so-dir',    [ sodir,
         | 
| 174 | 
            -
                                 'path',
         | 
| 175 | 
            -
                                 'the directory for ruby extentions' ] ],
         | 
| 176 | 
            -
                [ 'data-dir',  [ '$prefix/share',
         | 
| 177 | 
            -
                                 'path',
         | 
| 178 | 
            -
                                 'the directory for shared data' ] ],
         | 
| 179 | 
            -
                [ 'ruby-path', [ rubypath,
         | 
| 180 | 
            -
                                 'path',
         | 
| 181 | 
            -
                                 'path to set to #! line' ] ],
         | 
| 182 | 
            -
                [ 'ruby-prog', [ rubypath,
         | 
| 183 | 
            -
                                 'name',
         | 
| 184 | 
            -
                                 'the ruby program using for installation' ] ],
         | 
| 185 | 
            -
                [ 'make-prog', [ makeprog,
         | 
| 186 | 
            -
                                 'name',
         | 
| 187 | 
            -
                                 'the make program to compile ruby extentions' ] ],
         | 
| 188 | 
            -
                [ 'without-ext', [ 'no',
         | 
| 189 | 
            -
                                   'yes/no',
         | 
| 190 | 
            -
                                   'does not compile/install ruby extentions' ] ]
         | 
| 191 | 
            -
              ]
         | 
| 192 | 
            -
              multipackage_descripters = [
         | 
| 193 | 
            -
                [ 'with',      [ '',
         | 
| 194 | 
            -
                                 'name,name...',
         | 
| 195 | 
            -
                                 'package names that you want to install',
         | 
| 196 | 
            -
                                 'ALL' ] ],
         | 
| 197 | 
            -
                [ 'without',   [ '',
         | 
| 198 | 
            -
                                 'name,name...',
         | 
| 199 | 
            -
                                 'package names that you do not want to install',
         | 
| 200 | 
            -
                                 'NONE' ] ]
         | 
| 201 | 
            -
              ]
         | 
| 202 | 
            -
              if multipackage_install?
         | 
| 203 | 
            -
                DESCRIPTER = common_descripters + multipackage_descripters
         | 
| 204 | 
            -
              else
         | 
| 205 | 
            -
                DESCRIPTER = common_descripters
         | 
| 65 | 
            +
              def verbose?
         | 
| 66 | 
            +
                @verbose
         | 
| 206 67 | 
             
              end
         | 
| 207 68 |  | 
| 208 | 
            -
               | 
| 69 | 
            +
              attr_writer :no_harm
         | 
| 209 70 |  | 
| 210 | 
            -
              def  | 
| 211 | 
            -
                 | 
| 71 | 
            +
              def no_harm?
         | 
| 72 | 
            +
                @no_harm
         | 
| 212 73 | 
             
              end
         | 
| 213 74 |  | 
| 214 | 
            -
              def  | 
| 215 | 
            -
                 | 
| 75 | 
            +
              def [](key)
         | 
| 76 | 
            +
                lookup(key).resolve(self)
         | 
| 216 77 | 
             
              end
         | 
| 217 78 |  | 
| 218 | 
            -
              def  | 
| 219 | 
            -
                 | 
| 79 | 
            +
              def []=(key, val)
         | 
| 80 | 
            +
                lookup(key).set val
         | 
| 220 81 | 
             
              end
         | 
| 221 82 |  | 
| 222 | 
            -
              def  | 
| 223 | 
            -
                 | 
| 224 | 
            -
                ent
         | 
| 83 | 
            +
              def names
         | 
| 84 | 
            +
                @items.map {|i| i.name }
         | 
| 225 85 | 
             
              end
         | 
| 226 86 |  | 
| 227 | 
            -
              def  | 
| 228 | 
            -
                 | 
| 87 | 
            +
              def each(&block)
         | 
| 88 | 
            +
                @items.each(&block)
         | 
| 229 89 | 
             
              end
         | 
| 230 90 |  | 
| 231 | 
            -
              def  | 
| 232 | 
            -
                 | 
| 91 | 
            +
              def key?(name)
         | 
| 92 | 
            +
                @table.key?(name)
         | 
| 233 93 | 
             
              end
         | 
| 234 94 |  | 
| 235 | 
            -
              def  | 
| 236 | 
            -
                 | 
| 237 | 
            -
                DESCRIPTER.delete_if {|n, arr| n == name }
         | 
| 95 | 
            +
              def lookup(name)
         | 
| 96 | 
            +
                @table[name] or setup_rb_error "no such config item: #{name}"
         | 
| 238 97 | 
             
              end
         | 
| 239 98 |  | 
| 240 | 
            -
              def  | 
| 241 | 
            -
                 | 
| 99 | 
            +
              def add(item)
         | 
| 100 | 
            +
                @items.push item
         | 
| 101 | 
            +
                @table[item.name] = item
         | 
| 242 102 | 
             
              end
         | 
| 243 103 |  | 
| 244 | 
            -
              def  | 
| 245 | 
            -
                 | 
| 246 | 
            -
                 | 
| 104 | 
            +
              def remove(name)
         | 
| 105 | 
            +
                item = lookup(name)
         | 
| 106 | 
            +
                @items.delete_if {|i| i.name == name }
         | 
| 107 | 
            +
                @table.delete_if {|name, i| i.name == name }
         | 
| 108 | 
            +
                item
         | 
| 247 109 | 
             
              end
         | 
| 248 110 |  | 
| 249 | 
            -
              def  | 
| 250 | 
            -
                 | 
| 251 | 
            -
             | 
| 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
         | 
| 252 115 | 
             
              end
         | 
| 253 116 |  | 
| 254 | 
            -
              def  | 
| 255 | 
            -
                 | 
| 256 | 
            -
                ent[1] == 'path'
         | 
| 117 | 
            +
              def savefile
         | 
| 118 | 
            +
                '.config'
         | 
| 257 119 | 
             
              end
         | 
| 258 120 |  | 
| 259 | 
            -
             | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 121 | 
            +
              def load_savefile
         | 
| 122 | 
            +
                begin
         | 
| 123 | 
            +
                  File.foreach(savefile()) do |line|
         | 
| 124 | 
            +
                    k, v = *line.split(/=/, 2)
         | 
| 125 | 
            +
                    self[k] = v.strip
         | 
| 126 | 
            +
                  end
         | 
| 127 | 
            +
                rescue Errno::ENOENT
         | 
| 128 | 
            +
                  setup_rb_error $!.message + "\n#{File.basename($0)} config first"
         | 
| 129 | 
            +
                end
         | 
| 262 130 | 
             
              end
         | 
| 263 131 |  | 
| 264 | 
            -
              def  | 
| 265 | 
            -
                 | 
| 266 | 
            -
                 | 
| 267 | 
            -
             | 
| 132 | 
            +
              def save
         | 
| 133 | 
            +
                @items.each {|i| i.value }
         | 
| 134 | 
            +
                File.open(savefile(), 'w') {|f|
         | 
| 135 | 
            +
                  @items.each do |i|
         | 
| 136 | 
            +
                    f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
         | 
| 137 | 
            +
                  end
         | 
| 138 | 
            +
                }
         | 
| 268 139 | 
             
              end
         | 
| 269 140 |  | 
| 270 | 
            -
              def  | 
| 271 | 
            -
                 | 
| 272 | 
            -
             | 
| 273 | 
            -
                 | 
| 141 | 
            +
              def load_standard_entries
         | 
| 142 | 
            +
                standard_entries(@rbconfig).each do |ent|
         | 
| 143 | 
            +
                  add ent
         | 
| 144 | 
            +
                end
         | 
| 274 145 | 
             
              end
         | 
| 275 146 |  | 
| 276 | 
            -
              def  | 
| 277 | 
            -
                 | 
| 278 | 
            -
             | 
| 279 | 
            -
             | 
| 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']}"
         | 
| 280 187 | 
             
                end
         | 
| 281 | 
            -
             | 
| 188 | 
            +
                parameterize = lambda {|path|
         | 
| 189 | 
            +
                  path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
         | 
| 190 | 
            +
                }
         | 
| 282 191 |  | 
| 283 | 
            -
             | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 287 | 
            -
                File.foreach(SAVE_FILE) do |line|
         | 
| 288 | 
            -
                  k, v = line.split(/=/, 2)
         | 
| 289 | 
            -
                  @table[k] = v.strip
         | 
| 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'
         | 
| 290 196 | 
             
                end
         | 
| 291 | 
            -
              end
         | 
| 292 197 |  | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
             | 
| 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
         | 
| 299 264 | 
             
              end
         | 
| 300 265 |  | 
| 301 | 
            -
              def  | 
| 302 | 
            -
                 | 
| 303 | 
            -
             | 
| 304 | 
            -
             | 
| 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
         | 
| 275 | 
            +
             | 
| 276 | 
            +
              ALIASES = {
         | 
| 277 | 
            +
                'std-ruby'         => 'librubyver',
         | 
| 278 | 
            +
                'stdruby'          => 'librubyver',
         | 
| 279 | 
            +
                'rubylibdir'       => 'librubyver',
         | 
| 280 | 
            +
                'archdir'          => 'librubyverarch',
         | 
| 281 | 
            +
                'site-ruby-common' => 'siteruby',     # For backward compatibility
         | 
| 282 | 
            +
                'site-ruby'        => 'siterubyver',  # For backward compatibility
         | 
| 283 | 
            +
                'bin-dir'          => 'bindir',
         | 
| 284 | 
            +
                'bin-dir'          => 'bindir',
         | 
| 285 | 
            +
                'rb-dir'           => 'rbdir',
         | 
| 286 | 
            +
                'so-dir'           => 'sodir',
         | 
| 287 | 
            +
                'data-dir'         => 'datadir',
         | 
| 288 | 
            +
                'ruby-path'        => 'rubypath',
         | 
| 289 | 
            +
                'ruby-prog'        => 'rubyprog',
         | 
| 290 | 
            +
                'ruby'             => 'rubyprog',
         | 
| 291 | 
            +
                'make-prog'        => 'makeprog',
         | 
| 292 | 
            +
                'make'             => 'makeprog'
         | 
| 293 | 
            +
              }
         | 
| 294 | 
            +
             | 
| 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/
         | 
| 305 302 | 
             
              end
         | 
| 306 | 
            -
             | 
| 307 | 
            -
              def  | 
| 308 | 
            -
                 | 
| 309 | 
            -
                 | 
| 303 | 
            +
             | 
| 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]
         | 
| 310 307 | 
             
              end
         | 
| 311 308 |  | 
| 312 | 
            -
              def  | 
| 313 | 
            -
                @ | 
| 309 | 
            +
              def dllext
         | 
| 310 | 
            +
                @rbconfig['DLEXT']
         | 
| 314 311 | 
             
              end
         | 
| 315 312 |  | 
| 316 | 
            -
              def  | 
| 317 | 
            -
                 | 
| 313 | 
            +
              def value_config?(name)
         | 
| 314 | 
            +
                lookup(name).value?
         | 
| 318 315 | 
             
              end
         | 
| 319 316 |  | 
| 320 | 
            -
             | 
| 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
         | 
| 321 325 |  | 
| 326 | 
            +
                attr_reader :name
         | 
| 327 | 
            +
                attr_reader :description
         | 
| 322 328 |  | 
| 323 | 
            -
             | 
| 329 | 
            +
                attr_accessor :default
         | 
| 330 | 
            +
                alias help_default default
         | 
| 324 331 |  | 
| 325 | 
            -
             | 
| 326 | 
            -
             | 
| 327 | 
            -
             | 
| 332 | 
            +
                def help_opt
         | 
| 333 | 
            +
                  "--#{@name}=#{@template}"
         | 
| 334 | 
            +
                end
         | 
| 328 335 |  | 
| 329 | 
            -
             | 
| 330 | 
            -
             | 
| 331 | 
            -
             | 
| 336 | 
            +
                def value?
         | 
| 337 | 
            +
                  true
         | 
| 338 | 
            +
                end
         | 
| 332 339 |  | 
| 333 | 
            -
             | 
| 334 | 
            -
             | 
| 335 | 
            -
             | 
| 340 | 
            +
                def value
         | 
| 341 | 
            +
                  @value
         | 
| 342 | 
            +
                end
         | 
| 343 | 
            +
             | 
| 344 | 
            +
                def resolve(table)
         | 
| 345 | 
            +
                  @value.gsub(%r<\$([^/]+)>) { table[$1] }
         | 
| 346 | 
            +
                end
         | 
| 336 347 |  | 
| 337 | 
            -
             | 
| 338 | 
            -
             | 
| 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
         | 
| 357 | 
            +
                end
         | 
| 339 358 | 
             
              end
         | 
| 340 359 |  | 
| 341 | 
            -
               | 
| 342 | 
            -
                 | 
| 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
         | 
| 343 380 | 
             
              end
         | 
| 344 381 |  | 
| 345 | 
            -
               | 
| 346 | 
            -
                 | 
| 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
         | 
| 347 393 | 
             
              end
         | 
| 348 394 |  | 
| 349 | 
            -
               | 
| 350 | 
            -
                 | 
| 395 | 
            +
              class ProgramItem < Item
         | 
| 396 | 
            +
                def config_type
         | 
| 397 | 
            +
                  'program'
         | 
| 398 | 
            +
                end
         | 
| 351 399 | 
             
              end
         | 
| 352 400 |  | 
| 353 | 
            -
               | 
| 354 | 
            -
                 | 
| 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
         | 
| 355 419 | 
             
              end
         | 
| 356 420 |  | 
| 357 | 
            -
               | 
| 358 | 
            -
                 | 
| 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
         | 
| 359 449 | 
             
              end
         | 
| 360 450 |  | 
| 361 | 
            -
               | 
| 362 | 
            -
                 | 
| 363 | 
            -
                   | 
| 364 | 
            -
             | 
| 365 | 
            -
             | 
| 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
         | 
| 456 | 
            +
             | 
| 457 | 
            +
                attr_reader :help_default
         | 
| 458 | 
            +
             | 
| 459 | 
            +
                def config_type
         | 
| 460 | 
            +
                  'package'
         | 
| 461 | 
            +
                end
         | 
| 462 | 
            +
             | 
| 463 | 
            +
                private
         | 
| 464 | 
            +
             | 
| 465 | 
            +
                def check(val)
         | 
| 466 | 
            +
                  unless File.dir?("packages/#{val}")
         | 
| 467 | 
            +
                    setup_rb_error "config: no such package: #{val}"
         | 
| 468 | 
            +
                  end
         | 
| 469 | 
            +
                  val
         | 
| 366 470 | 
             
                end
         | 
| 367 471 | 
             
              end
         | 
| 368 472 |  | 
| 369 | 
            -
               | 
| 370 | 
            -
                 | 
| 371 | 
            -
             | 
| 372 | 
            -
             | 
| 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
         | 
| 373 530 | 
             
              end
         | 
| 374 531 |  | 
| 375 | 
            -
            end
         | 
| 532 | 
            +
            end   # class ConfigTable
         | 
| 376 533 |  | 
| 377 | 
            -
            #
         | 
| 378 | 
            -
            # File Operations
         | 
| 379 | 
            -
            #
         | 
| 380 534 |  | 
| 535 | 
            +
            # This module requires: #verbose?, #no_harm?
         | 
| 381 536 | 
             
            module FileOperations
         | 
| 382 537 |  | 
| 383 538 | 
             
              def mkdir_p(dirname, prefix = nil)
         | 
| 384 | 
            -
                dirname = prefix + dirname if prefix
         | 
| 539 | 
            +
                dirname = prefix + File.expand_path(dirname) if prefix
         | 
| 385 540 | 
             
                $stderr.puts "mkdir -p #{dirname}" if verbose?
         | 
| 386 541 | 
             
                return if no_harm?
         | 
| 387 542 |  | 
| 388 | 
            -
                #  | 
| 389 | 
            -
                dirs = dirname.split(%r<(?=/)>)
         | 
| 543 | 
            +
                # Does not check '/', it's too abnormal.
         | 
| 544 | 
            +
                dirs = File.expand_path(dirname).split(%r<(?=/)>)
         | 
| 390 545 | 
             
                if /\A[a-z]:\z/i =~ dirs[0]
         | 
| 391 546 | 
             
                  disk = dirs.shift
         | 
| 392 547 | 
             
                  dirs[0] = disk + dirs[0]
         | 
| @@ -397,54 +552,78 @@ module FileOperations | |
| 397 552 | 
             
                end
         | 
| 398 553 | 
             
              end
         | 
| 399 554 |  | 
| 400 | 
            -
              def rm_f( | 
| 401 | 
            -
                $stderr.puts "rm -f #{ | 
| 555 | 
            +
              def rm_f(path)
         | 
| 556 | 
            +
                $stderr.puts "rm -f #{path}" if verbose?
         | 
| 402 557 | 
             
                return if no_harm?
         | 
| 403 | 
            -
             | 
| 404 | 
            -
                if File.exist?(fname) or File.symlink?(fname)
         | 
| 405 | 
            -
                  File.chmod 0777, fname
         | 
| 406 | 
            -
                  File.unlink fname
         | 
| 407 | 
            -
                end
         | 
| 558 | 
            +
                force_remove_file path
         | 
| 408 559 | 
             
              end
         | 
| 409 560 |  | 
| 410 | 
            -
              def rm_rf( | 
| 411 | 
            -
                $stderr.puts "rm -rf #{ | 
| 561 | 
            +
              def rm_rf(path)
         | 
| 562 | 
            +
                $stderr.puts "rm -rf #{path}" if verbose?
         | 
| 412 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
         | 
| 413 576 |  | 
| 414 | 
            -
             | 
| 415 | 
            -
                Dir.foreach( | 
| 416 | 
            -
                  next if  | 
| 417 | 
            -
                  next if  | 
| 418 | 
            -
                   | 
| 419 | 
            -
             | 
| 420 | 
            -
             | 
| 421 | 
            -
             | 
| 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
         | 
| 422 586 | 
             
                  else
         | 
| 423 | 
            -
                     | 
| 424 | 
            -
                      rm_f fn
         | 
| 425 | 
            -
                    }
         | 
| 587 | 
            +
                    force_remove_file entpath
         | 
| 426 588 | 
             
                  end
         | 
| 427 589 | 
             
                end
         | 
| 428 | 
            -
                 | 
| 429 | 
            -
             | 
| 590 | 
            +
                begin
         | 
| 591 | 
            +
                  Dir.rmdir path
         | 
| 592 | 
            +
                rescue Errno::ENOTEMPTY
         | 
| 593 | 
            +
                  # directory may not be empty
         | 
| 594 | 
            +
                end
         | 
| 430 595 | 
             
              end
         | 
| 431 596 |  | 
| 432 597 | 
             
              def move_file(src, dest)
         | 
| 433 | 
            -
                 | 
| 598 | 
            +
                force_remove_file dest
         | 
| 434 599 | 
             
                begin
         | 
| 435 600 | 
             
                  File.rename src, dest
         | 
| 436 601 | 
             
                rescue
         | 
| 437 | 
            -
                  File.open(dest, 'wb') {|f| | 
| 602 | 
            +
                  File.open(dest, 'wb') {|f|
         | 
| 603 | 
            +
                    f.write File.binread(src)
         | 
| 604 | 
            +
                  }
         | 
| 438 605 | 
             
                  File.chmod File.stat(src).mode, dest
         | 
| 439 606 | 
             
                  File.unlink src
         | 
| 440 607 | 
             
                end
         | 
| 441 608 | 
             
              end
         | 
| 442 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 | 
            +
             | 
| 443 622 | 
             
              def install(from, dest, mode, prefix = nil)
         | 
| 444 623 | 
             
                $stderr.puts "install #{from} #{dest}" if verbose?
         | 
| 445 624 | 
             
                return if no_harm?
         | 
| 446 625 |  | 
| 447 | 
            -
                realdest = prefix + dest  | 
| 626 | 
            +
                realdest = prefix ? prefix + File.expand_path(dest) : dest
         | 
| 448 627 | 
             
                realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
         | 
| 449 628 | 
             
                str = File.binread(from)
         | 
| 450 629 | 
             
                if diff?(str, realdest)
         | 
| @@ -471,68 +650,42 @@ module FileOperations | |
| 471 650 | 
             
                new_content != File.binread(path)
         | 
| 472 651 | 
             
              end
         | 
| 473 652 |  | 
| 474 | 
            -
              def command( | 
| 475 | 
            -
                $stderr.puts  | 
| 476 | 
            -
                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"
         | 
| 477 657 | 
             
              end
         | 
| 478 658 |  | 
| 479 | 
            -
              def ruby( | 
| 480 | 
            -
                command config(' | 
| 659 | 
            +
              def ruby(*args)
         | 
| 660 | 
            +
                command config('rubyprog'), *args
         | 
| 481 661 | 
             
              end
         | 
| 482 662 |  | 
| 483 | 
            -
              def make(task =  | 
| 484 | 
            -
                command | 
| 663 | 
            +
              def make(task = nil)
         | 
| 664 | 
            +
                command(*[config('makeprog'), task].compact)
         | 
| 485 665 | 
             
              end
         | 
| 486 666 |  | 
| 487 667 | 
             
              def extdir?(dir)
         | 
| 488 | 
            -
                File.exist?(dir  | 
| 668 | 
            +
                File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
         | 
| 489 669 | 
             
              end
         | 
| 490 670 |  | 
| 491 | 
            -
              def  | 
| 492 | 
            -
                Dir.open( | 
| 493 | 
            -
                  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}") }
         | 
| 494 674 | 
             
                }
         | 
| 495 675 | 
             
              end
         | 
| 496 676 |  | 
| 497 | 
            -
               | 
| 498 | 
            -
                CVS SCCS RCS CVS.adm
         | 
| 499 | 
            -
              )
         | 
| 677 | 
            +
              DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
         | 
| 500 678 |  | 
| 501 | 
            -
              def  | 
| 502 | 
            -
                Dir.open( | 
| 503 | 
            -
                  return d.select {| | 
| 679 | 
            +
              def directories_of(dir)
         | 
| 680 | 
            +
                Dir.open(dir) {|d|
         | 
| 681 | 
            +
                  return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
         | 
| 504 682 | 
             
                }
         | 
| 505 683 | 
             
              end
         | 
| 506 684 |  | 
| 507 685 | 
             
            end
         | 
| 508 686 |  | 
| 509 | 
            -
            #
         | 
| 510 | 
            -
            # Main Installer
         | 
| 511 | 
            -
            #
         | 
| 512 | 
            -
             | 
| 513 | 
            -
            class InstallError < StandardError; end
         | 
| 514 | 
            -
             | 
| 515 | 
            -
             | 
| 516 | 
            -
            module HookUtils
         | 
| 517 | 
            -
             | 
| 518 | 
            -
              def run_hook(name)
         | 
| 519 | 
            -
                try_run_hook "#{curr_srcdir()}/#{name}" or
         | 
| 520 | 
            -
                try_run_hook "#{curr_srcdir()}/#{name}.rb"
         | 
| 521 | 
            -
              end
         | 
| 522 | 
            -
             | 
| 523 | 
            -
              def try_run_hook(fname)
         | 
| 524 | 
            -
                return false unless File.file?(fname)
         | 
| 525 | 
            -
                begin
         | 
| 526 | 
            -
                  instance_eval File.read(fname), fname, 1
         | 
| 527 | 
            -
                rescue
         | 
| 528 | 
            -
                  raise InstallError, "hook #{fname} failed:\n" + $!.message
         | 
| 529 | 
            -
                end
         | 
| 530 | 
            -
                true
         | 
| 531 | 
            -
              end
         | 
| 532 | 
            -
             | 
| 533 | 
            -
            end
         | 
| 534 | 
            -
             | 
| 535 687 |  | 
| 688 | 
            +
            # This module requires: #srcdir_root, #objdir_root, #relpath
         | 
| 536 689 | 
             
            module HookScriptAPI
         | 
| 537 690 |  | 
| 538 691 | 
             
              def get_config(key)
         | 
| @@ -541,6 +694,7 @@ module HookScriptAPI | |
| 541 694 |  | 
| 542 695 | 
             
              alias config get_config
         | 
| 543 696 |  | 
| 697 | 
            +
              # obsolete: use metaconfig to change configuration
         | 
| 544 698 | 
             
              def set_config(key, val)
         | 
| 545 699 | 
             
                @config[key] = val
         | 
| 546 700 | 
             
              end
         | 
| @@ -549,10 +703,6 @@ module HookScriptAPI | |
| 549 703 | 
             
              # srcdir/objdir (works only in the package directory)
         | 
| 550 704 | 
             
              #
         | 
| 551 705 |  | 
| 552 | 
            -
              #abstract srcdir_root
         | 
| 553 | 
            -
              #abstract objdir_root
         | 
| 554 | 
            -
              #abstract relpath
         | 
| 555 | 
            -
             | 
| 556 706 | 
             
              def curr_srcdir
         | 
| 557 707 | 
             
                "#{srcdir_root()}/#{relpath()}"
         | 
| 558 708 | 
             
              end
         | 
| @@ -574,7 +724,7 @@ module HookScriptAPI | |
| 574 724 | 
             
              end
         | 
| 575 725 |  | 
| 576 726 | 
             
              def srcfile?(path)
         | 
| 577 | 
            -
                File.file? | 
| 727 | 
            +
                File.file?(srcfile(path))
         | 
| 578 728 | 
             
              end
         | 
| 579 729 |  | 
| 580 730 | 
             
              def srcentries(path = '.')
         | 
| @@ -600,35 +750,53 @@ end | |
| 600 750 |  | 
| 601 751 | 
             
            class ToplevelInstaller
         | 
| 602 752 |  | 
| 603 | 
            -
              Version   = '3. | 
| 604 | 
            -
              Copyright = 'Copyright (c) 2000- | 
| 753 | 
            +
              Version   = '3.4.1'
         | 
| 754 | 
            +
              Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
         | 
| 605 755 |  | 
| 606 756 | 
             
              TASKS = [
         | 
| 757 | 
            +
                [ 'all',      'do config, setup, then install' ],
         | 
| 607 758 | 
             
                [ 'config',   'saves your configurations' ],
         | 
| 608 759 | 
             
                [ 'show',     'shows current configuration' ],
         | 
| 609 760 | 
             
                [ 'setup',    'compiles ruby extentions and others' ],
         | 
| 610 761 | 
             
                [ 'install',  'installs files' ],
         | 
| 762 | 
            +
                [ 'test',     'run all tests in test/' ],
         | 
| 611 763 | 
             
                [ 'clean',    "does `make clean' for each extention" ],
         | 
| 612 764 | 
             
                [ 'distclean',"does `make distclean' for each extention" ]
         | 
| 613 765 | 
             
              ]
         | 
| 614 766 |  | 
| 615 767 | 
             
              def ToplevelInstaller.invoke
         | 
| 616 | 
            -
                 | 
| 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
         | 
| 617 774 | 
             
              end
         | 
| 618 775 |  | 
| 619 | 
            -
               | 
| 620 | 
            -
             | 
| 621 | 
            -
              def ToplevelInstaller.instance
         | 
| 622 | 
            -
                @singleton ||= new(File.dirname($0))
         | 
| 623 | 
            -
                @singleton
         | 
| 776 | 
            +
              def ToplevelInstaller.multipackage?
         | 
| 777 | 
            +
                File.dir?(File.dirname($0) + '/packages')
         | 
| 624 778 | 
             
              end
         | 
| 625 779 |  | 
| 626 | 
            -
               | 
| 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
         | 
| 627 790 |  | 
| 628 | 
            -
              def initialize(ardir_root)
         | 
| 629 | 
            -
                @config = nil
         | 
| 630 | 
            -
                @options = { 'verbose' => true }
         | 
| 791 | 
            +
              def initialize(ardir_root, config)
         | 
| 631 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]
         | 
| 632 800 | 
             
              end
         | 
| 633 801 |  | 
| 634 802 | 
             
              def inspect
         | 
| @@ -637,33 +805,34 @@ class ToplevelInstaller | |
| 637 805 |  | 
| 638 806 | 
             
              def invoke
         | 
| 639 807 | 
             
                run_metaconfigs
         | 
| 640 | 
            -
                task = parsearg_global()
         | 
| 641 | 
            -
                 | 
| 642 | 
            -
             | 
| 643 | 
            -
             | 
| 644 | 
            -
             | 
| 645 | 
            -
             | 
| 646 | 
            -
             | 
| 647 | 
            -
              def run_metaconfigs
         | 
| 648 | 
            -
                eval_file_ifexist "#{@ardir}/metaconfig"
         | 
| 649 | 
            -
              end
         | 
| 650 | 
            -
             | 
| 651 | 
            -
              def load_config(task)
         | 
| 652 | 
            -
                case task
         | 
| 653 | 
            -
                when 'config'
         | 
| 654 | 
            -
                  ConfigTable.new
         | 
| 655 | 
            -
                when 'clean', 'distclean'
         | 
| 656 | 
            -
                  if File.exist?('config.save')
         | 
| 657 | 
            -
                  then ConfigTable.load
         | 
| 658 | 
            -
                  else ConfigTable.new
         | 
| 659 | 
            -
                  end
         | 
| 808 | 
            +
                case task = parsearg_global()
         | 
| 809 | 
            +
                when nil, 'all'
         | 
| 810 | 
            +
                  parsearg_config
         | 
| 811 | 
            +
                  init_installers
         | 
| 812 | 
            +
                  exec_config
         | 
| 813 | 
            +
                  exec_setup
         | 
| 814 | 
            +
                  exec_install
         | 
| 660 815 | 
             
                else
         | 
| 661 | 
            -
                   | 
| 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
         | 
| 824 | 
            +
                  __send__ "parsearg_#{task}"
         | 
| 825 | 
            +
                  init_installers
         | 
| 826 | 
            +
                  __send__ "exec_#{task}"
         | 
| 662 827 | 
             
                end
         | 
| 663 828 | 
             
              end
         | 
| 829 | 
            +
              
         | 
| 830 | 
            +
              def run_metaconfigs
         | 
| 831 | 
            +
                @config.load_script "#{@ardir}/metaconfig"
         | 
| 832 | 
            +
              end
         | 
| 664 833 |  | 
| 665 834 | 
             
              def init_installers
         | 
| 666 | 
            -
                @installer = Installer.new(@config, @ | 
| 835 | 
            +
                @installer = Installer.new(@config, @ardir, File.expand_path('.'))
         | 
| 667 836 | 
             
              end
         | 
| 668 837 |  | 
| 669 838 | 
             
              #
         | 
| @@ -687,96 +856,91 @@ class ToplevelInstaller | |
| 687 856 | 
             
              #
         | 
| 688 857 |  | 
| 689 858 | 
             
              def parsearg_global
         | 
| 690 | 
            -
                valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
         | 
| 691 | 
            -
             | 
| 692 859 | 
             
                while arg = ARGV.shift
         | 
| 693 860 | 
             
                  case arg
         | 
| 694 861 | 
             
                  when /\A\w+\z/
         | 
| 695 | 
            -
                     | 
| 862 | 
            +
                    setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
         | 
| 696 863 | 
             
                    return arg
         | 
| 697 | 
            -
             | 
| 698 864 | 
             
                  when '-q', '--quiet'
         | 
| 699 | 
            -
                    @ | 
| 700 | 
            -
             | 
| 701 | 
            -
             | 
| 702 | 
            -
             | 
| 703 | 
            -
             | 
| 704 | 
            -
                  when '-h', '--help'
         | 
| 865 | 
            +
                    @config.verbose = false
         | 
| 866 | 
            +
                  when '--verbose'
         | 
| 867 | 
            +
                    @config.verbose = true
         | 
| 868 | 
            +
                  when '--help'
         | 
| 705 869 | 
             
                    print_usage $stdout
         | 
| 706 870 | 
             
                    exit 0
         | 
| 707 | 
            -
             | 
| 708 | 
            -
                  when '-v', '--version'
         | 
| 871 | 
            +
                  when '--version'
         | 
| 709 872 | 
             
                    puts "#{File.basename($0)} version #{Version}"
         | 
| 710 873 | 
             
                    exit 0
         | 
| 711 | 
            -
                  
         | 
| 712 874 | 
             
                  when '--copyright'
         | 
| 713 875 | 
             
                    puts Copyright
         | 
| 714 876 | 
             
                    exit 0
         | 
| 715 | 
            -
             | 
| 716 877 | 
             
                  else
         | 
| 717 | 
            -
                     | 
| 878 | 
            +
                    setup_rb_error "unknown global option '#{arg}'"
         | 
| 718 879 | 
             
                  end
         | 
| 719 880 | 
             
                end
         | 
| 881 | 
            +
                nil
         | 
| 882 | 
            +
              end
         | 
| 720 883 |  | 
| 721 | 
            -
             | 
| 722 | 
            -
             | 
| 723 | 
            -
            Typical installation procedure is:
         | 
| 724 | 
            -
                $ ruby #{File.basename($0)} config
         | 
| 725 | 
            -
                $ ruby #{File.basename($0)} setup
         | 
| 726 | 
            -
                # ruby #{File.basename($0)} install  (may require root privilege)
         | 
| 727 | 
            -
            EOS
         | 
| 884 | 
            +
              def valid_task?(t)
         | 
| 885 | 
            +
                valid_task_re() =~ t
         | 
| 728 886 | 
             
              end
         | 
| 729 887 |  | 
| 888 | 
            +
              def valid_task_re
         | 
| 889 | 
            +
                @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
         | 
| 890 | 
            +
              end
         | 
| 730 891 |  | 
| 731 892 | 
             
              def parsearg_no_options
         | 
| 732 | 
            -
                 | 
| 733 | 
            -
             | 
| 893 | 
            +
                unless ARGV.empty?
         | 
| 894 | 
            +
                  task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
         | 
| 895 | 
            +
                  setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
         | 
| 896 | 
            +
                end
         | 
| 734 897 | 
             
              end
         | 
| 735 898 |  | 
| 736 899 | 
             
              alias parsearg_show       parsearg_no_options
         | 
| 737 900 | 
             
              alias parsearg_setup      parsearg_no_options
         | 
| 901 | 
            +
              alias parsearg_test       parsearg_no_options
         | 
| 738 902 | 
             
              alias parsearg_clean      parsearg_no_options
         | 
| 739 903 | 
             
              alias parsearg_distclean  parsearg_no_options
         | 
| 740 904 |  | 
| 741 905 | 
             
              def parsearg_config
         | 
| 742 | 
            -
                 | 
| 743 | 
            -
                 | 
| 744 | 
            -
             | 
| 906 | 
            +
                evalopt = []
         | 
| 907 | 
            +
                set = []
         | 
| 908 | 
            +
                @config.config_opt = []
         | 
| 745 909 | 
             
                while i = ARGV.shift
         | 
| 746 910 | 
             
                  if /\A--?\z/ =~ i
         | 
| 747 | 
            -
                    @ | 
| 911 | 
            +
                    @config.config_opt = ARGV.dup
         | 
| 748 912 | 
             
                    break
         | 
| 749 913 | 
             
                  end
         | 
| 750 | 
            -
                   | 
| 751 | 
            -
                   | 
| 752 | 
            -
             | 
| 753 | 
            -
                    if ConfigTable.bool_config?(name)
         | 
| 754 | 
            -
                      raise InstallError, "config: --#{name} allows only yes/no for argument"\
         | 
| 755 | 
            -
                          unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ value
         | 
| 756 | 
            -
                      value = (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
         | 
| 757 | 
            -
                    end
         | 
| 914 | 
            +
                  name, value = *@config.parse_opt(i)
         | 
| 915 | 
            +
                  if @config.value_config?(name)
         | 
| 916 | 
            +
                    @config[name] = value
         | 
| 758 917 | 
             
                  else
         | 
| 759 | 
            -
                     | 
| 760 | 
            -
                        unless ConfigTable.bool_config?(name)
         | 
| 761 | 
            -
                    value = 'yes'
         | 
| 918 | 
            +
                    evalopt.push [name, value]
         | 
| 762 919 | 
             
                  end
         | 
| 763 | 
            -
                   | 
| 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)
         | 
| 764 928 | 
             
                end
         | 
| 765 929 | 
             
              end
         | 
| 766 930 |  | 
| 767 931 | 
             
              def parsearg_install
         | 
| 768 | 
            -
                @ | 
| 769 | 
            -
                @ | 
| 932 | 
            +
                @config.no_harm = false
         | 
| 933 | 
            +
                @config.install_prefix = ''
         | 
| 770 934 | 
             
                while a = ARGV.shift
         | 
| 771 935 | 
             
                  case a
         | 
| 772 | 
            -
                  when  | 
| 773 | 
            -
                    @ | 
| 774 | 
            -
                  when /\A--prefix | 
| 775 | 
            -
                    path =  | 
| 936 | 
            +
                  when '--no-harm'
         | 
| 937 | 
            +
                    @config.no_harm = true
         | 
| 938 | 
            +
                  when /\A--prefix=/
         | 
| 939 | 
            +
                    path = a.split(/=/, 2)[1]
         | 
| 776 940 | 
             
                    path = File.expand_path(path) unless path[0,1] == '/'
         | 
| 777 | 
            -
                    @ | 
| 941 | 
            +
                    @config.install_prefix = path
         | 
| 778 942 | 
             
                  else
         | 
| 779 | 
            -
                     | 
| 943 | 
            +
                    setup_rb_error "install: unknown option #{a}"
         | 
| 780 944 | 
             
                  end
         | 
| 781 945 | 
             
                end
         | 
| 782 946 | 
             
              end
         | 
| @@ -791,39 +955,31 @@ EOS | |
| 791 955 | 
             
                out.puts "  ruby #{File.basename $0} <global option>"
         | 
| 792 956 | 
             
                out.puts "  ruby #{File.basename $0} [<global options>] <task> [<task options>]"
         | 
| 793 957 |  | 
| 794 | 
            -
                fmt = "  %- | 
| 958 | 
            +
                fmt = "  %-24s %s\n"
         | 
| 795 959 | 
             
                out.puts
         | 
| 796 960 | 
             
                out.puts 'Global options:'
         | 
| 797 961 | 
             
                out.printf fmt, '-q,--quiet',   'suppress message outputs'
         | 
| 798 962 | 
             
                out.printf fmt, '   --verbose', 'output messages verbosely'
         | 
| 799 | 
            -
                out.printf fmt, ' | 
| 800 | 
            -
                out.printf fmt, ' | 
| 963 | 
            +
                out.printf fmt, '   --help',    'print this message'
         | 
| 964 | 
            +
                out.printf fmt, '   --version', 'print version and quit'
         | 
| 801 965 | 
             
                out.printf fmt, '   --copyright',  'print copyright and quit'
         | 
| 802 | 
            -
             | 
| 803 966 | 
             
                out.puts
         | 
| 804 967 | 
             
                out.puts 'Tasks:'
         | 
| 805 968 | 
             
                TASKS.each do |name, desc|
         | 
| 806 | 
            -
                  out.printf  | 
| 969 | 
            +
                  out.printf fmt, name, desc
         | 
| 807 970 | 
             
                end
         | 
| 808 971 |  | 
| 972 | 
            +
                fmt = "  %-24s %s [%s]\n"
         | 
| 809 973 | 
             
                out.puts
         | 
| 810 | 
            -
                out.puts 'Options for  | 
| 811 | 
            -
                 | 
| 812 | 
            -
                  out.printf  | 
| 813 | 
            -
                             '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
         | 
| 814 | 
            -
                             desc,
         | 
| 815 | 
            -
                             default2 || default
         | 
| 974 | 
            +
                out.puts 'Options for CONFIG or ALL:'
         | 
| 975 | 
            +
                @config.each do |item|
         | 
| 976 | 
            +
                  out.printf fmt, item.help_opt, item.description, item.help_default
         | 
| 816 977 | 
             
                end
         | 
| 817 | 
            -
                out.printf " | 
| 818 | 
            -
                    '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
         | 
| 819 | 
            -
             | 
| 978 | 
            +
                out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
         | 
| 820 979 | 
             
                out.puts
         | 
| 821 | 
            -
                out.puts 'Options for  | 
| 822 | 
            -
                out.printf  | 
| 823 | 
            -
             | 
| 824 | 
            -
                out.printf "  %-20s %s [%s]\n",
         | 
| 825 | 
            -
                    '--prefix',  'install path prefix', '$prefix'
         | 
| 826 | 
            -
             | 
| 980 | 
            +
                out.puts 'Options for INSTALL:'
         | 
| 981 | 
            +
                out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
         | 
| 982 | 
            +
                out.printf fmt, '--prefix=path',  'install path prefix', ''
         | 
| 827 983 | 
             
                out.puts
         | 
| 828 984 | 
             
              end
         | 
| 829 985 |  | 
| @@ -844,13 +1000,13 @@ EOS | |
| 844 1000 | 
             
                @installer.exec_install
         | 
| 845 1001 | 
             
              end
         | 
| 846 1002 |  | 
| 1003 | 
            +
              def exec_test
         | 
| 1004 | 
            +
                @installer.exec_test
         | 
| 1005 | 
            +
              end
         | 
| 1006 | 
            +
             | 
| 847 1007 | 
             
              def exec_show
         | 
| 848 | 
            -
                 | 
| 849 | 
            -
                   | 
| 850 | 
            -
                  if not v or v.empty?
         | 
| 851 | 
            -
                    v = '(not specified)'
         | 
| 852 | 
            -
                  end
         | 
| 853 | 
            -
                  printf "%-10s %s\n", k, v
         | 
| 1008 | 
            +
                @config.each do |i|
         | 
| 1009 | 
            +
                  printf "%-20s %s\n", i.name, i.value if i.value?
         | 
| 854 1010 | 
             
                end
         | 
| 855 1011 | 
             
              end
         | 
| 856 1012 |  | 
| @@ -862,36 +1018,45 @@ EOS | |
| 862 1018 | 
             
                @installer.exec_distclean
         | 
| 863 1019 | 
             
              end
         | 
| 864 1020 |  | 
| 865 | 
            -
            end
         | 
| 1021 | 
            +
            end   # class ToplevelInstaller
         | 
| 866 1022 |  | 
| 867 1023 |  | 
| 868 1024 | 
             
            class ToplevelInstallerMulti < ToplevelInstaller
         | 
| 869 1025 |  | 
| 870 | 
            -
              include HookUtils
         | 
| 871 | 
            -
              include HookScriptAPI
         | 
| 872 1026 | 
             
              include FileOperations
         | 
| 873 1027 |  | 
| 874 | 
            -
              def initialize( | 
| 1028 | 
            +
              def initialize(ardir_root, config)
         | 
| 875 1029 | 
             
                super
         | 
| 876 | 
            -
                @packages =  | 
| 1030 | 
            +
                @packages = directories_of("#{@ardir}/packages")
         | 
| 877 1031 | 
             
                raise 'no package exists' if @packages.empty?
         | 
| 1032 | 
            +
                @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
         | 
| 878 1033 | 
             
              end
         | 
| 879 1034 |  | 
| 880 1035 | 
             
              def run_metaconfigs
         | 
| 881 | 
            -
                 | 
| 1036 | 
            +
                @config.load_script "#{@ardir}/metaconfig", self
         | 
| 882 1037 | 
             
                @packages.each do |name|
         | 
| 883 | 
            -
                   | 
| 1038 | 
            +
                  @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
         | 
| 884 1039 | 
             
                end
         | 
| 885 1040 | 
             
              end
         | 
| 886 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 | 
            +
             | 
| 887 1053 | 
             
              def init_installers
         | 
| 888 1054 | 
             
                @installers = {}
         | 
| 889 1055 | 
             
                @packages.each do |pack|
         | 
| 890 | 
            -
                  @installers[pack] = Installer.new(@config, | 
| 1056 | 
            +
                  @installers[pack] = Installer.new(@config,
         | 
| 891 1057 | 
             
                                                   "#{@ardir}/packages/#{pack}",
         | 
| 892 1058 | 
             
                                                   "packages/#{pack}")
         | 
| 893 1059 | 
             
                end
         | 
| 894 | 
            -
             | 
| 895 1060 | 
             
                with    = extract_selection(config('with'))
         | 
| 896 1061 | 
             
                without = extract_selection(config('without'))
         | 
| 897 1062 | 
             
                @selected = @installers.keys.select {|name|
         | 
| @@ -903,8 +1068,7 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 903 1068 | 
             
              def extract_selection(list)
         | 
| 904 1069 | 
             
                a = list.split(/,/)
         | 
| 905 1070 | 
             
                a.each do |name|
         | 
| 906 | 
            -
                   | 
| 907 | 
            -
                          unless @installers.key?(name)
         | 
| 1071 | 
            +
                  setup_rb_error "no such package: #{name}"  unless @installers.key?(name)
         | 
| 908 1072 | 
             
                end
         | 
| 909 1073 | 
             
                a
         | 
| 910 1074 | 
             
              end
         | 
| @@ -916,21 +1080,6 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 916 1080 | 
             
                f.puts
         | 
| 917 1081 | 
             
              end
         | 
| 918 1082 |  | 
| 919 | 
            -
              #
         | 
| 920 | 
            -
              # multi-package metaconfig API
         | 
| 921 | 
            -
              #
         | 
| 922 | 
            -
             | 
| 923 | 
            -
              attr_reader :packages
         | 
| 924 | 
            -
             | 
| 925 | 
            -
              def declare_packages(list)
         | 
| 926 | 
            -
                raise 'package list is empty' if list.empty?
         | 
| 927 | 
            -
                list.each do |name|
         | 
| 928 | 
            -
                  raise "directory packages/#{name} does not exist"\
         | 
| 929 | 
            -
                          unless File.dir?("#{@ardir}/packages/#{name}")
         | 
| 930 | 
            -
                end
         | 
| 931 | 
            -
                @packages = list
         | 
| 932 | 
            -
              end
         | 
| 933 | 
            -
             | 
| 934 1083 | 
             
              #
         | 
| 935 1084 | 
             
              # Task Handlers
         | 
| 936 1085 | 
             
              #
         | 
| @@ -954,15 +1103,21 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 954 1103 | 
             
                run_hook 'post-install'
         | 
| 955 1104 | 
             
              end
         | 
| 956 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 | 
            +
             | 
| 957 1112 | 
             
              def exec_clean
         | 
| 958 | 
            -
                rm_f  | 
| 1113 | 
            +
                rm_f @config.savefile
         | 
| 959 1114 | 
             
                run_hook 'pre-clean'
         | 
| 960 1115 | 
             
                each_selected_installers {|inst| inst.exec_clean }
         | 
| 961 1116 | 
             
                run_hook 'post-clean'
         | 
| 962 1117 | 
             
              end
         | 
| 963 1118 |  | 
| 964 1119 | 
             
              def exec_distclean
         | 
| 965 | 
            -
                rm_f  | 
| 1120 | 
            +
                rm_f @config.savefile
         | 
| 966 1121 | 
             
                run_hook 'pre-distclean'
         | 
| 967 1122 | 
             
                each_selected_installers {|inst| inst.exec_distclean }
         | 
| 968 1123 | 
             
                run_hook 'post-distclean'
         | 
| @@ -975,7 +1130,7 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 975 1130 | 
             
              def each_selected_installers
         | 
| 976 1131 | 
             
                Dir.mkdir 'packages' unless File.dir?('packages')
         | 
| 977 1132 | 
             
                @selected.each do |pack|
         | 
| 978 | 
            -
                  $stderr.puts "Processing the package `#{pack}' ..." if  | 
| 1133 | 
            +
                  $stderr.puts "Processing the package `#{pack}' ..." if verbose?
         | 
| 979 1134 | 
             
                  Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
         | 
| 980 1135 | 
             
                  Dir.chdir "packages/#{pack}"
         | 
| 981 1136 | 
             
                  yield @installers[pack]
         | 
| @@ -983,28 +1138,32 @@ class ToplevelInstallerMulti < ToplevelInstaller | |
| 983 1138 | 
             
                end
         | 
| 984 1139 | 
             
              end
         | 
| 985 1140 |  | 
| 1141 | 
            +
              def run_hook(id)
         | 
| 1142 | 
            +
                @root_installer.run_hook id
         | 
| 1143 | 
            +
              end
         | 
| 1144 | 
            +
             | 
| 1145 | 
            +
              # module FileOperations requires this
         | 
| 986 1146 | 
             
              def verbose?
         | 
| 987 | 
            -
                @ | 
| 1147 | 
            +
                @config.verbose?
         | 
| 988 1148 | 
             
              end
         | 
| 989 1149 |  | 
| 1150 | 
            +
              # module FileOperations requires this
         | 
| 990 1151 | 
             
              def no_harm?
         | 
| 991 | 
            -
                @ | 
| 1152 | 
            +
                @config.no_harm?
         | 
| 992 1153 | 
             
              end
         | 
| 993 1154 |  | 
| 994 | 
            -
            end
         | 
| 1155 | 
            +
            end   # class ToplevelInstallerMulti
         | 
| 995 1156 |  | 
| 996 1157 |  | 
| 997 1158 | 
             
            class Installer
         | 
| 998 1159 |  | 
| 999 | 
            -
              FILETYPES = %w( bin lib ext data )
         | 
| 1160 | 
            +
              FILETYPES = %w( bin lib ext data conf man )
         | 
| 1000 1161 |  | 
| 1001 | 
            -
              include HookScriptAPI
         | 
| 1002 | 
            -
              include HookUtils
         | 
| 1003 1162 | 
             
              include FileOperations
         | 
| 1163 | 
            +
              include HookScriptAPI
         | 
| 1004 1164 |  | 
| 1005 | 
            -
              def initialize(config,  | 
| 1165 | 
            +
              def initialize(config, srcroot, objroot)
         | 
| 1006 1166 | 
             
                @config = config
         | 
| 1007 | 
            -
                @options = opt
         | 
| 1008 1167 | 
             
                @srcdir = File.expand_path(srcroot)
         | 
| 1009 1168 | 
             
                @objdir = File.expand_path(objroot)
         | 
| 1010 1169 | 
             
                @currdir = '.'
         | 
| @@ -1014,8 +1173,11 @@ class Installer | |
| 1014 1173 | 
             
                "#<#{self.class} #{File.basename(@srcdir)}>"
         | 
| 1015 1174 | 
             
              end
         | 
| 1016 1175 |  | 
| 1176 | 
            +
              def noop(rel)
         | 
| 1177 | 
            +
              end
         | 
| 1178 | 
            +
             | 
| 1017 1179 | 
             
              #
         | 
| 1018 | 
            -
              # Hook Script API  | 
| 1180 | 
            +
              # Hook Script API base methods
         | 
| 1019 1181 | 
             
              #
         | 
| 1020 1182 |  | 
| 1021 1183 | 
             
              def srcdir_root
         | 
| @@ -1031,23 +1193,25 @@ class Installer | |
| 1031 1193 | 
             
              end
         | 
| 1032 1194 |  | 
| 1033 1195 | 
             
              #
         | 
| 1034 | 
            -
              #  | 
| 1196 | 
            +
              # Config Access
         | 
| 1035 1197 | 
             
              #
         | 
| 1036 1198 |  | 
| 1037 | 
            -
               | 
| 1038 | 
            -
             | 
| 1199 | 
            +
              # module FileOperations requires this
         | 
| 1200 | 
            +
              def verbose?
         | 
| 1201 | 
            +
                @config.verbose?
         | 
| 1039 1202 | 
             
              end
         | 
| 1040 1203 |  | 
| 1041 | 
            -
               | 
| 1042 | 
            -
             | 
| 1204 | 
            +
              # module FileOperations requires this
         | 
| 1205 | 
            +
              def no_harm?
         | 
| 1206 | 
            +
                @config.no_harm?
         | 
| 1043 1207 | 
             
              end
         | 
| 1044 1208 |  | 
| 1045 1209 | 
             
              def verbose_off
         | 
| 1046 1210 | 
             
                begin
         | 
| 1047 | 
            -
                  save, @ | 
| 1211 | 
            +
                  save, @config.verbose = @config.verbose?, false
         | 
| 1048 1212 | 
             
                  yield
         | 
| 1049 1213 | 
             
                ensure
         | 
| 1050 | 
            -
                  @ | 
| 1214 | 
            +
                  @config.verbose = save
         | 
| 1051 1215 | 
             
                end
         | 
| 1052 1216 | 
             
              end
         | 
| 1053 1217 |  | 
| @@ -1059,22 +1223,19 @@ class Installer | |
| 1059 1223 | 
             
                exec_task_traverse 'config'
         | 
| 1060 1224 | 
             
              end
         | 
| 1061 1225 |  | 
| 1062 | 
            -
               | 
| 1063 | 
            -
               | 
| 1064 | 
            -
             | 
| 1065 | 
            -
              def config_dir_lib(rel)
         | 
| 1066 | 
            -
              end
         | 
| 1226 | 
            +
              alias config_dir_bin noop
         | 
| 1227 | 
            +
              alias config_dir_lib noop
         | 
| 1067 1228 |  | 
| 1068 1229 | 
             
              def config_dir_ext(rel)
         | 
| 1069 1230 | 
             
                extconf if extdir?(curr_srcdir())
         | 
| 1070 1231 | 
             
              end
         | 
| 1071 1232 |  | 
| 1072 | 
            -
               | 
| 1073 | 
            -
             | 
| 1074 | 
            -
             | 
| 1075 | 
            -
              end
         | 
| 1233 | 
            +
              alias config_dir_data noop
         | 
| 1234 | 
            +
              alias config_dir_conf noop
         | 
| 1235 | 
            +
              alias config_dir_man noop
         | 
| 1076 1236 |  | 
| 1077 | 
            -
              def  | 
| 1237 | 
            +
              def extconf
         | 
| 1238 | 
            +
                ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
         | 
| 1078 1239 | 
             
              end
         | 
| 1079 1240 |  | 
| 1080 1241 | 
             
              #
         | 
| @@ -1086,46 +1247,90 @@ class Installer | |
| 1086 1247 | 
             
              end
         | 
| 1087 1248 |  | 
| 1088 1249 | 
             
              def setup_dir_bin(rel)
         | 
| 1089 | 
            -
                 | 
| 1090 | 
            -
                   | 
| 1250 | 
            +
                files_of(curr_srcdir()).each do |fname|
         | 
| 1251 | 
            +
                  update_shebang_line "#{curr_srcdir()}/#{fname}"
         | 
| 1091 1252 | 
             
                end
         | 
| 1092 1253 | 
             
              end
         | 
| 1093 1254 |  | 
| 1094 | 
            -
               | 
| 1095 | 
            -
             | 
| 1096 | 
            -
               | 
| 1097 | 
            -
             | 
| 1098 | 
            -
               | 
| 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
         | 
| 1099 1264 |  | 
| 1100 | 
            -
              def  | 
| 1265 | 
            +
              def update_shebang_line(path)
         | 
| 1101 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
         | 
| 1102 1297 |  | 
| 1298 | 
            +
              def open_atomic_writer(path, &block)
         | 
| 1103 1299 | 
             
                tmpfile = File.basename(path) + '.tmp'
         | 
| 1104 1300 | 
             
                begin
         | 
| 1105 | 
            -
                  File.open( | 
| 1106 | 
            -
             | 
| 1107 | 
            -
                      first = r.gets
         | 
| 1108 | 
            -
                      return unless SHEBANG_RE =~ first
         | 
| 1109 | 
            -
             | 
| 1110 | 
            -
                      $stderr.puts "adjusting shebang: #{File.basename path}" if verbose?
         | 
| 1111 | 
            -
                      w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
         | 
| 1112 | 
            -
                      w.write r.read
         | 
| 1113 | 
            -
                    }
         | 
| 1114 | 
            -
                  }
         | 
| 1115 | 
            -
                  move_file tmpfile, File.basename(path)
         | 
| 1301 | 
            +
                  File.open(tmpfile, 'wb', &block)
         | 
| 1302 | 
            +
                  File.rename tmpfile, File.basename(path)
         | 
| 1116 1303 | 
             
                ensure
         | 
| 1117 1304 | 
             
                  File.unlink tmpfile if File.exist?(tmpfile)
         | 
| 1118 1305 | 
             
                end
         | 
| 1119 1306 | 
             
              end
         | 
| 1120 1307 |  | 
| 1121 | 
            -
               | 
| 1122 | 
            -
             | 
| 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
         | 
| 1123 1317 |  | 
| 1124 | 
            -
             | 
| 1125 | 
            -
             | 
| 1126 | 
            -
             | 
| 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
         | 
| 1327 | 
            +
             | 
| 1328 | 
            +
                attr_reader :cmd
         | 
| 1329 | 
            +
                attr_reader :args
         | 
| 1127 1330 |  | 
| 1128 | 
            -
             | 
| 1331 | 
            +
                def to_s
         | 
| 1332 | 
            +
                  "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
         | 
| 1333 | 
            +
                end
         | 
| 1129 1334 | 
             
              end
         | 
| 1130 1335 |  | 
| 1131 1336 | 
             
              #
         | 
| @@ -1133,67 +1338,82 @@ class Installer | |
| 1133 1338 | 
             
              #
         | 
| 1134 1339 |  | 
| 1135 1340 | 
             
              def exec_install
         | 
| 1341 | 
            +
                rm_f 'InstalledFiles'
         | 
| 1136 1342 | 
             
                exec_task_traverse 'install'
         | 
| 1137 1343 | 
             
              end
         | 
| 1138 1344 |  | 
| 1139 1345 | 
             
              def install_dir_bin(rel)
         | 
| 1140 | 
            -
                install_files  | 
| 1346 | 
            +
                install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
         | 
| 1141 1347 | 
             
              end
         | 
| 1142 1348 |  | 
| 1143 1349 | 
             
              def install_dir_lib(rel)
         | 
| 1144 | 
            -
                install_files  | 
| 1350 | 
            +
                install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
         | 
| 1145 1351 | 
             
              end
         | 
| 1146 1352 |  | 
| 1147 1353 | 
             
              def install_dir_ext(rel)
         | 
| 1148 1354 | 
             
                return unless extdir?(curr_srcdir())
         | 
| 1149 | 
            -
                install_files  | 
| 1150 | 
            -
                              "#{config(' | 
| 1355 | 
            +
                install_files rubyextentions('.'),
         | 
| 1356 | 
            +
                              "#{config('sodir')}/#{File.dirname(rel)}",
         | 
| 1151 1357 | 
             
                              0555
         | 
| 1152 1358 | 
             
              end
         | 
| 1153 1359 |  | 
| 1154 1360 | 
             
              def install_dir_data(rel)
         | 
| 1155 | 
            -
                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
         | 
| 1156 1372 | 
             
              end
         | 
| 1157 1373 |  | 
| 1158 1374 | 
             
              def install_files(list, dest, mode)
         | 
| 1159 | 
            -
                mkdir_p dest, @ | 
| 1375 | 
            +
                mkdir_p dest, @config.install_prefix
         | 
| 1160 1376 | 
             
                list.each do |fname|
         | 
| 1161 | 
            -
                  install fname, dest, mode, @ | 
| 1377 | 
            +
                  install fname, dest, mode, @config.install_prefix
         | 
| 1162 1378 | 
             
                end
         | 
| 1163 1379 | 
             
              end
         | 
| 1164 1380 |  | 
| 1165 | 
            -
              def  | 
| 1166 | 
            -
                 | 
| 1381 | 
            +
              def libfiles
         | 
| 1382 | 
            +
                glob_reject(%w(*.y *.output), targetfiles())
         | 
| 1167 1383 | 
             
              end
         | 
| 1168 | 
            -
             | 
| 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 | 
            +
             | 
| 1169 1406 | 
             
              # picked up many entries from cvs-1.11.1/src/ignore.c
         | 
| 1170 | 
            -
               | 
| 1407 | 
            +
              JUNK_FILES = %w( 
         | 
| 1171 1408 | 
             
                core RCSLOG tags TAGS .make.state
         | 
| 1172 1409 | 
             
                .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
         | 
| 1173 1410 | 
             
                *~ *.old *.bak *.BAK *.orig *.rej _$* *$
         | 
| 1174 1411 |  | 
| 1175 1412 | 
             
                *.org *.in .*
         | 
| 1176 1413 | 
             
              )
         | 
| 1177 | 
            -
              mapping = {
         | 
| 1178 | 
            -
                '.' => '\.',
         | 
| 1179 | 
            -
                '$' => '\$',
         | 
| 1180 | 
            -
                '#' => '\#',
         | 
| 1181 | 
            -
                '*' => '.*'
         | 
| 1182 | 
            -
              }
         | 
| 1183 | 
            -
              REJECT_PATTERNS = Regexp.new('\A(?:' +
         | 
| 1184 | 
            -
                                           reject_patterns.map {|pat|
         | 
| 1185 | 
            -
                                             pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
         | 
| 1186 | 
            -
                                           }.join('|') +
         | 
| 1187 | 
            -
                                           ')\z')
         | 
| 1188 | 
            -
             | 
| 1189 | 
            -
              def collect_filenames_auto
         | 
| 1190 | 
            -
                mapdir((existfiles() - hookfiles()).reject {|fname|
         | 
| 1191 | 
            -
                         REJECT_PATTERNS =~ fname
         | 
| 1192 | 
            -
                       })
         | 
| 1193 | 
            -
              end
         | 
| 1194 1414 |  | 
| 1195 1415 | 
             
              def existfiles
         | 
| 1196 | 
            -
                 | 
| 1416 | 
            +
                glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
         | 
| 1197 1417 | 
             
              end
         | 
| 1198 1418 |  | 
| 1199 1419 | 
             
              def hookfiles
         | 
| @@ -1202,27 +1422,49 @@ class Installer | |
| 1202 1422 | 
             
                }.flatten
         | 
| 1203 1423 | 
             
              end
         | 
| 1204 1424 |  | 
| 1205 | 
            -
              def  | 
| 1206 | 
            -
                 | 
| 1207 | 
            -
             | 
| 1208 | 
            -
                    fname
         | 
| 1209 | 
            -
                  else                    # srcdir
         | 
| 1210 | 
            -
                    File.join(curr_srcdir(), fname)
         | 
| 1211 | 
            -
                  end
         | 
| 1212 | 
            -
                }
         | 
| 1425 | 
            +
              def glob_select(pat, ents)
         | 
| 1426 | 
            +
                re = globs2re([pat])
         | 
| 1427 | 
            +
                ents.select {|ent| re =~ ent }
         | 
| 1213 1428 | 
             
              end
         | 
| 1214 1429 |  | 
| 1215 | 
            -
              def  | 
| 1216 | 
            -
                 | 
| 1217 | 
            -
             | 
| 1430 | 
            +
              def glob_reject(pats, ents)
         | 
| 1431 | 
            +
                re = globs2re(pats)
         | 
| 1432 | 
            +
                ents.reject {|ent| re =~ ent }
         | 
| 1218 1433 | 
             
              end
         | 
| 1219 1434 |  | 
| 1220 | 
            -
               | 
| 1435 | 
            +
              GLOB2REGEX = {
         | 
| 1436 | 
            +
                '.' => '\.',
         | 
| 1437 | 
            +
                '$' => '\$',
         | 
| 1438 | 
            +
                '#' => '\#',
         | 
| 1439 | 
            +
                '*' => '.*'
         | 
| 1440 | 
            +
              }
         | 
| 1221 1441 |  | 
| 1222 | 
            -
              def  | 
| 1223 | 
            -
                 | 
| 1224 | 
            -
                   | 
| 1225 | 
            -
                }
         | 
| 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
         | 
| 1226 1468 | 
             
              end
         | 
| 1227 1469 |  | 
| 1228 1470 | 
             
              #
         | 
| @@ -1231,53 +1473,51 @@ class Installer | |
| 1231 1473 |  | 
| 1232 1474 | 
             
              def exec_clean
         | 
| 1233 1475 | 
             
                exec_task_traverse 'clean'
         | 
| 1234 | 
            -
                rm_f  | 
| 1476 | 
            +
                rm_f @config.savefile
         | 
| 1235 1477 | 
             
                rm_f 'InstalledFiles'
         | 
| 1236 1478 | 
             
              end
         | 
| 1237 1479 |  | 
| 1238 | 
            -
               | 
| 1239 | 
            -
               | 
| 1240 | 
            -
             | 
| 1241 | 
            -
               | 
| 1242 | 
            -
               | 
| 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
         | 
| 1243 1485 |  | 
| 1244 1486 | 
             
              def clean_dir_ext(rel)
         | 
| 1245 1487 | 
             
                return unless extdir?(curr_srcdir())
         | 
| 1246 1488 | 
             
                make 'clean' if File.file?('Makefile')
         | 
| 1247 1489 | 
             
              end
         | 
| 1248 1490 |  | 
| 1249 | 
            -
              def clean_dir_data(rel)
         | 
| 1250 | 
            -
              end
         | 
| 1251 | 
            -
             | 
| 1252 1491 | 
             
              #
         | 
| 1253 1492 | 
             
              # TASK distclean
         | 
| 1254 1493 | 
             
              #
         | 
| 1255 1494 |  | 
| 1256 1495 | 
             
              def exec_distclean
         | 
| 1257 1496 | 
             
                exec_task_traverse 'distclean'
         | 
| 1258 | 
            -
                rm_f  | 
| 1497 | 
            +
                rm_f @config.savefile
         | 
| 1259 1498 | 
             
                rm_f 'InstalledFiles'
         | 
| 1260 1499 | 
             
              end
         | 
| 1261 1500 |  | 
| 1262 | 
            -
               | 
| 1263 | 
            -
               | 
| 1264 | 
            -
             | 
| 1265 | 
            -
              def distclean_dir_lib(rel)
         | 
| 1266 | 
            -
              end
         | 
| 1501 | 
            +
              alias distclean_dir_bin noop
         | 
| 1502 | 
            +
              alias distclean_dir_lib noop
         | 
| 1267 1503 |  | 
| 1268 1504 | 
             
              def distclean_dir_ext(rel)
         | 
| 1269 1505 | 
             
                return unless extdir?(curr_srcdir())
         | 
| 1270 1506 | 
             
                make 'distclean' if File.file?('Makefile')
         | 
| 1271 1507 | 
             
              end
         | 
| 1272 1508 |  | 
| 1509 | 
            +
              alias distclean_dir_data noop
         | 
| 1510 | 
            +
              alias distclean_dir_conf noop
         | 
| 1511 | 
            +
              alias distclean_dir_man noop
         | 
| 1512 | 
            +
             | 
| 1273 1513 | 
             
              #
         | 
| 1274 | 
            -
              #  | 
| 1514 | 
            +
              # Traversing
         | 
| 1275 1515 | 
             
              #
         | 
| 1276 1516 |  | 
| 1277 1517 | 
             
              def exec_task_traverse(task)
         | 
| 1278 1518 | 
             
                run_hook "pre-#{task}"
         | 
| 1279 1519 | 
             
                FILETYPES.each do |type|
         | 
| 1280 | 
            -
                  if config('without-ext') == 'yes' | 
| 1520 | 
            +
                  if type == 'ext' and config('without-ext') == 'yes'
         | 
| 1281 1521 | 
             
                    $stderr.puts 'skipping ext/* by user option' if verbose?
         | 
| 1282 1522 | 
             
                    next
         | 
| 1283 1523 | 
             
                  end
         | 
| @@ -1290,7 +1530,7 @@ class Installer | |
| 1290 1530 | 
             
                dive_into(rel) {
         | 
| 1291 1531 | 
             
                  run_hook "pre-#{task}"
         | 
| 1292 1532 | 
             
                  __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
         | 
| 1293 | 
            -
                   | 
| 1533 | 
            +
                  directories_of(curr_srcdir()).each do |d|
         | 
| 1294 1534 | 
             
                    traverse task, "#{rel}/#{d}", mid
         | 
| 1295 1535 | 
             
                  end
         | 
| 1296 1536 | 
             
                  run_hook "post-#{task}"
         | 
| @@ -1312,17 +1552,31 @@ class Installer | |
| 1312 1552 | 
             
                @currdir = File.dirname(rel)
         | 
| 1313 1553 | 
             
              end
         | 
| 1314 1554 |  | 
| 1315 | 
            -
             | 
| 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
         | 
| 1316 1568 |  | 
| 1317 1569 |  | 
| 1570 | 
            +
            class SetupError < StandardError; end
         | 
| 1571 | 
            +
             | 
| 1572 | 
            +
            def setup_rb_error(msg)
         | 
| 1573 | 
            +
              raise SetupError, msg
         | 
| 1574 | 
            +
            end
         | 
| 1575 | 
            +
             | 
| 1318 1576 | 
             
            if $0 == __FILE__
         | 
| 1319 1577 | 
             
              begin
         | 
| 1320 | 
            -
                 | 
| 1321 | 
            -
             | 
| 1322 | 
            -
                else
         | 
| 1323 | 
            -
                  ToplevelInstaller.invoke
         | 
| 1324 | 
            -
                end
         | 
| 1325 | 
            -
              rescue
         | 
| 1578 | 
            +
                ToplevelInstaller.invoke
         | 
| 1579 | 
            +
              rescue SetupError
         | 
| 1326 1580 | 
             
                raise if $DEBUG
         | 
| 1327 1581 | 
             
                $stderr.puts $!.message
         | 
| 1328 1582 | 
             
                $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
         |