From 0dc342de848a642ecce8db697b8fecd83a63e117 Mon Sep 17 00:00:00 2001 From: yugui Date: Mon, 25 Aug 2008 15:02:05 +0000 Subject: added tag v1_9_0_4 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_4@18845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- trunk/win32/mkexports.rb | 153 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100755 trunk/win32/mkexports.rb (limited to 'trunk/win32/mkexports.rb') diff --git a/trunk/win32/mkexports.rb b/trunk/win32/mkexports.rb new file mode 100755 index 0000000000..2ed251ec1c --- /dev/null +++ b/trunk/win32/mkexports.rb @@ -0,0 +1,153 @@ +#!./miniruby -s + +$name = $library = $description = nil + +module RbConfig + autoload :CONFIG, "rbconfig" +end + +class Exports + @subclass = [] + def self.inherited(klass) + @subclass << [/#{klass.name.sub(/.*::/, '').downcase}/i, klass] + end + + def self.create(*args, &block) + platform = RUBY_PLATFORM + pat, klass = @subclass.find {|p, k| p =~ platform} + unless klass + raise ArgumentError, "unsupported platform: #{platform}" + end + klass.new(*args, &block) + end + + def self.extract(objs, *rest) + create(objs).exports(*rest) + end + + def self.output(output = $output, &block) + if output + open(output, 'wb', &block) + else + yield STDOUT + end + end + + def initialize(objs) + syms = {} + winapis = {} + each_export(objs) do |internal, export| + syms[internal] = export + winapis[$1] = internal if /^_?(rb_w32_\w+)(?:@\d+)?$/ =~ internal + end + win32h = File.join(File.dirname(File.dirname(__FILE__)), "include/ruby/win32.h") + IO.foreach(win32h) do |line| + if /^#define (\w+)\((.*?)\)\s+(?:\(void\))?(rb_w32_\w+)\((.*?)\)\s*$/ =~ line and + $2.delete(" ") == $4.delete(" ") + export, internal = $1, $3 + if syms[internal] or internal = winapis[internal] + syms[forwarding(internal, export)] = internal + end + end + end + syms["NtInitialize"] ||= "ruby_sysinit" if syms["ruby_sysinit"] + @syms = syms + end + + def exports(name = $name, library = $library, description = $description) + exports = [] + if name + exports << "Name " + name + elsif library + exports << "Library " + library + end + exports << "Description " + description.dump if description + exports << "EXPORTS" << symbols() + exports + end + + private + def forwarding(internal, export) + internal.sub(/^[^@]+/, "\\1#{export}") + end + + def each_export(objs) + end + + def objdump(objs, &block) + if objs.empty? + $stdin.each_line(&block) + else + each_line(objs, &block) + end + end + + def symbols() + @syms.sort.collect {|k, v| v ? v == true ? "#{k} DATA" : "#{k}=#{v}" : k} + end +end + +class Exports::Mswin < Exports + def each_line(objs, &block) + IO.popen(%w"dumpbin -symbols -exports" + objs) do |f| + f.each(&block) + end + end + + def each_export(objs) + noprefix = ($arch ||= nil and /^(sh|i\d86)/ !~ $arch) + objs = objs.collect {|s| s.tr('/', '\\')} + filetype = nil + objdump(objs) do |l| + if (filetype = l[/^File Type: (.+)/, 1])..(/^\f/ =~ l) + case filetype + when /OBJECT/, /LIBRARY/ + next if /^[[:xdigit:]]+ 0+ UNDEF / =~ l + next unless /External/ =~ l + next unless l.sub!(/.*?\s(\(\)\s+)?External\s+\|\s+/, '') + is_data = !$1 + if noprefix or /^[@_]/ =~ l + next if /(?!^)@.*@/ =~ l || /@[[:xdigit:]]{16}$/ =~ l + l.sub!(/^[@_]/, '') if /@\d+$/ !~ l + elsif !l.sub!(/^(\S+) \([^@?\`\']*\)$/, '\1') + next + end + when /DLL/ + next unless l.sub!(/^\s*\d+\s+[[:xdigit:]]+\s+[[:xdigit:]]+\s+/, '') + else + next + end + yield l.strip, is_data + end + end + yield "strcasecmp", "msvcrt.stricmp" + yield "strncasecmp", "msvcrt.strnicmp" + end +end + +class Exports::Mingw < Exports + def self.nm + @@nm ||= RbConfig::CONFIG["NM"] + end + + def each_line(objs, &block) + IO.foreach("|#{self.class.nm} --extern --defined #{objs.join(' ')}", &block) + end + + def each_export(objs) + objdump(objs) do |l| + yield $1 if / [[:upper:]] _(.*)$/ =~ l + end + yield "strcasecmp", "_stricmp" + yield "strncasecmp", "_strnicmp" + end + + def symbols() + @syms.select {|k, v| v}.sort.collect {|k, v| "#{k}=#{v}"} + end +end + +END { + exports = Exports.extract(ARGV) + Exports.output {|f| f.puts(*exports)} +} -- cgit v1.2.3