#!/usr/bin/env ruby ### ### inline-require - expand 'require "foo"' into inline code ### ### usage: inline-require [-h] [-I path[,path2,..]] script ### ### copyright(c) 2006-2008 kuwata-lab.com all rights reserved. ### 2.6.2 ### $Rev: 2 $ ### class InlineRequire 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) 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 if line =~ /^\s*require ['"](.*)["']\s*$/ 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 elsif inlined.include?(libpath) sbuf << "#--already included #{line}" else sbuf << "#--begin of #{line}" expand_require(libpath, sbuf, inlined, level+1) sbuf << "#--end of #{line}" 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 rubylib_paths = [] flag_help = false while ARGV[0] && ARGV[0][0] == ?- opt = ARGV.shift case opt when '-h', '--help' flag_help = true when '-I' arg = ARGV.shift raise "-I: library path required." unless arg rubylib_paths.concat(arg.split(/,/)) when '-D' $debug_mode = true else raise "#{opt}: invalid option." end end if flag_help command = File.basename($0) puts "Usage: #{command} [-h] [-I path[,path2,..]] script" puts " -h : help" puts " -I path[,path2,...] : ruby library path" exit(0) end $stderr.puts "*** debug: rubylib_paths=#{rubylib_paths.inspect}" if $debug_mode $LOAD_PATH.concat(rubylib_paths) filenames = ARGV inline_require = InlineRequire.new 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