instiki/vendor/plugins/erubis/contrib/inline-require
2010-07-04 08:51:53 -05:00

179 lines
5.5 KiB
Ruby
Executable file

#!/usr/bin/env ruby
###
### inline-require - expand 'require "foo"' into inline code
###
### usage: inline-require [-h] [-I path[,path2,..]] script
###
### copyright(c) 2006-2010 kuwata-lab.com all rights reserved.
### 2.6.6
### $Rev: 10 $
###
class InlineRequire
def initialize(opts={})
@opts = opts.dup
end
attr_accessor :opts
def expand(filename)
sbuf = ''
inlined = []
level = 0
expand_require(filename, sbuf, inlined, level)
return sbuf
end
private
def expand_require(filename, sbuf, inlined, level)
raise "*** assertion error" if inlined.include?(filename)
remove_comment = @opts[:remove_comment]
expand_indented = @opts[:expand_indented]
keep_filename = @opts[:keep_filename]
loaded_features = @opts[:loaded_features]
inlined << filename
prog = File.read(filename)
n = 0
flag_if_file = false
prog.each_line do |line|
n += 1
## comment out from 'if __FILE__ == $0' to 'end'
if level > 0
if flag_if_file
sbuf << "#" << line
flag_if_file = false if line =~ /^end$/
next
end
if line =~ /^if\s+__FILE__\s*==\s*\$0(\s+then)?$/ || line =~ /^if\s+\$0\s*==\s*__FILE__(\s+then)?$/
flag_if_file = true
sbuf << "#" << line
next
end
end
## find 'require "foo"' and expand it to inline code
flag_inline = false
pattern = expand_indented ? /^[ \t]*require ['"](.*)["']\s*$/ \
: /^require ['"](.*)["']\s*$/
if line =~ pattern
libname = $1
libpath = find_library(libname)
$stderr.puts "*** debug: libpath=#{libpath.inspect}" if $debug_mode
unless libpath
#raise "file '#{filename}'(line #{n}): library '#{libname}' not found."
warn "file '#{filename}'(line #{n}): library '#{libname}' not found."
else
flag_inline = true if libpath =~ /\.rb$/ && local_library?(libpath)
end
end
if !flag_inline
sbuf << line unless remove_comment && line =~ /^[ \t]*\#/
elsif inlined.include?(libpath)
sbuf << "#--already included #{line}" unless remove_comment
else
if keep_filename
@n ||= 0; @n += 1; n = @n
end
sbuf << "#--begin of #{line}" unless remove_comment
sbuf << "$LOADED_FEATURES << '#{libname}.rb'\n" if loaded_features
sbuf << "eval <<'END_OF_SCRIPT__#{n}', TOPLEVEL_BINDING, '#{libpath}', 1\n" if keep_filename
expand_require(libpath, sbuf, inlined, level+1)
sbuf << "END_OF_SCRIPT__#{n}\n" if keep_filename
sbuf << "#--end of #{line}" unless remove_comment
end
end
#sbuf << "\n" if sbuf[-1] != ?\n
end
def local_library?(libpath)
return libpath !~ /^\//
end
def find_library(libname)
if libname =~ /^\.rb$/
libname_rb = libname
libname_so = nil
elsif libname =~ /^\.so$/
libname_rb = nil
libname_so = libname
else
libname_rb = libname + ".rb"
libname_so = libname + ".so"
end
$LOAD_PATH.each do |path|
if libname_rb
libpath = path + "/" + libname_rb
return libpath if test(?f, libpath)
end
if libname_so
libpath = path + "/" + libname_so
return libpath if test(?f, libpath)
end
end
return nil
end
end
if __FILE__ == $0
begin
require "optparse"
op = OptionParser.new
options = {}
op.on("-h", "--help") {|v| options[:help] = v }
op.on("-I libpath") {|v| options[:libpath] = v }
op.on("-i") {|v| options[:expand_indented] = v }
op.on("-c") {|v| options[:remove_comment] = v }
op.on("-k") {|v| options[:keep_filename] = v }
op.on("-l") {|v| options[:loaded_features] = v }
op.on("-D") {|v| options[:debug] = v }
op.parse!()
$debug_mode = options[:debug]
if options[:help]
command = File.basename($0)
puts "Usage: #{command} [-h] [-I path[,path2,..]] script"
puts " -h : help"
puts " -i : expand indented require(), too"
puts " -c : remove comment lines start with '#'"
puts " -k : keep filename (for debugging)"
puts " -l : append libs to $LOADED_FEATURES"
puts " -I path[,path2,...] : ruby library path"
exit(0)
end
if options[:libpath]
rubylib_paths = options[:libpath].split(/,/)
else
rubylib_paths = []
end
$stderr.puts "*** debug: rubylib_paths=#{rubylib_paths.inspect}" if $debug_mode
$LOAD_PATH.concat(rubylib_paths)
filenames = ARGV
opts = { :expand_indented => options[:expand_indented],
:remove_comment => options[:remove_comment],
:keep_filename => options[:keep_filename],
:loaded_features => options[:loaded_features] }
inline_require = InlineRequire.new(opts)
filenames.each do |filename|
print inline_require.expand(filename)
end
rescue => ex
if $debug_mode
raise ex
else
$stderr.puts ex.message
end
end
end