File: rb-link

package info (click to toggle)
wfo 0.1-2
  • links: PTS
  • area: main
  • in suites: lenny, squeeze, wheezy
  • size: 1,508 kB
  • ctags: 485
  • sloc: ruby: 1,996; makefile: 66
file content (121 lines) | stat: -rwxr-xr-x 2,920 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env ruby

require 'rbconfig'
require 'optparse'
require 'pathname'

def expand_require(out, filename, dirs, main, included={})
  open(filename) {|f|
    comment = false
    test = false
    f.each {|line|
      if /^=begin/ =~ line
        comment = true
	out.print line
      elsif /^=end/ =~ line
        comment = false
	out.print line
      elsif comment
	out.print line
      elsif !main && (/^if __FILE__ == \$0/ =~ line || /^if \$0 == __FILE__/ =~ line)
        test = true
	out.print "#", line
      elsif test && /^end/ =~ line
        test = false
	out.print "#", line
      elsif test
	out.print "#", line
      elsif /^require '([^']*)'/ =~ line && %r{^/} !~ (req = $1)
	if included[req]
	  out.print "#", line
	else
	  dir = dirs.find {|d| (d + "#{req}.rb").exist? }
	  if dir
	    out.print "#", line
	    filename = dir + "#{req}.rb"
	    included[req] = filename
            #endmark = 'End_' + [req].pack("m*").delete("\n")
	    #out.print "eval <<'#{endmark}', TOPLEVEL_BINDING, #{"[#{filename}]".dump}, #{out.output_line+1}\n"
	    expand_require(out, filename, dirs, false, included)
	    #out.print "#{endmark}\n"
	  else
	    out.print line
	  end
	end
      elsif /^__END__$/ =~ line
        break
      else
	out.print line
      end
    }
  }
end

module CountOutputLine
  def output_line
    @output_line = 1 unless defined? @output_line
    @output_line
  end

  def write(str)
    @output_line = output_line + str.count("\n")
    super
  end
end

def parse_options
  $output_filename = nil
  $dep_output_filename = nil
  ARGV.options {|q|
    q.banner = 'rb-link [opts] script-file [library-directories...]'
    q.def_option('--help', 'show this message') {puts q; exit(0)}
    q.def_option('--output=filename', '-o', 'specify output file') {|filename| $output_filename = filename}
    q.def_option('--dependency=filename', '-d', 'specify dependency output file') {|filename| $dep_output_filename = filename}
    q.parse!
  }
end

def open_output
  if $output_filename
    File.open($output_filename, 'w') {|f|
      yield f
      f.chmod 0755
    }
  else
    yield STDOUT
  end
end

def main
  parse_options

  script = ARGV.shift
  if ARGV.empty?
    libdirs = [Pathname.new('.')]
  else
    libdirs = ARGV.map {|f| Pathname.new(f) }
  end

  open_output {|out|
    out.extend CountOutputLine
    interpreter_path = File.join(Config::CONFIG["bindir"], Config::CONFIG["ruby_install_name"])
    out.print "#!#{interpreter_path}\n"
    included = {}
    expand_require(out, script, libdirs, true, included)
    if $dep_output_filename
      open($dep_output_filename, 'w') {|f|
        incs = included.values.sort
        if incs.empty?
          f.puts "#{$output_filename} : #{script}"
        else
          f.puts "#{$output_filename} : #{script} #{incs.join(' ')}"
          incs.each {|inc|
            f.puts "#{inc} :"
          }
        end
      }
    end
  }
end

main