From 49775b88e9cc4381f6e43e4465c7003bdba2b228 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 5 Nov 2005 04:43:46 +0000 Subject: * configure.in, cygwin/GNUmakefile.in (mingw): use def file to alias symbols. [ruby-dev:27532] * bcc32/mkexports.rb, win32/mkexports.rb: make aliases in DLL. * win32/win32.c, win32/win32.h: replace symbols only when RUBY_EXPORT is defined. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9502 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- win32/mkexports.rb | 150 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 127 insertions(+), 23 deletions(-) (limited to 'win32/mkexports.rb') diff --git a/win32/mkexports.rb b/win32/mkexports.rb index 3859381935..3cf8bc329e 100644 --- a/win32/mkexports.rb +++ b/win32/mkexports.rb @@ -1,30 +1,134 @@ #!./miniruby -s -SYM = {} - -objs = ARGV.collect {|s| s.tr('/', '\\')} -IO.foreach("|dumpbin -symbols " + objs.join(' ')) do |l| - next if /^[0-9A-F]+ 0+ UNDEF / =~ l - next unless l.sub!(/.*\sExternal\s+\|\s+/, '') - if l.sub!(/^_/, '') - next if /@.*@/ =~ l || /@[0-9a-f]{16}$/ =~ l - elsif !l.sub!(/^(\S+) \([^@?\`\']*\)$/, '\1') - next - end - SYM[l.strip] = true +module Config + autoload :CONFIG, "rbconfig" end -exports = [] -if $name - exports << "Name " + $name -elsif $library - exports << "Library " + $library +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 {|pat, klass| pat =~ 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, 'w', &block) + else + yield STDOUT + end + end + + def initialize(objs) + syms = {} + winapis = {} + internal = export = nil + 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__), "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 = 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 + k = v = nil + exports << "EXPORTS" << symbols() + exports + end + + private + def forwarding(internal, export) + internal.sub(/^[^@]+/, "\\1#{export}") + end + + def each_export(objs) + end + + def symbols() + @syms.sort.collect {|k, v| v ? "#{k}=#{v}" : k} + end end -exports << "Description " + $description.dump if $description -exports << "EXPORTS" << SYM.keys.sort -if $output - open($output, 'w') {|f| f.puts exports.join("\n")} -else - puts exports.join("\n") +class Exports::Mswin < Exports + def each_export(objs) + noprefix = ($arch and /^sh/ !~ $arch) + objs = objs.collect {|s| s.tr('/', '\\')} + filetype = nil + IO.popen(%w"dumpbin -symbols -exports" + objs) do |f| + f.each do |l| + if (filetype = l[/^File Type: (.+)/, 1])..(/^\f/ =~ l) + case filetype + when /OBJECT/, /LIBRARY/ + next if /^[[:xdigit:]]+ 0+ UNDEF / =~ l + next unless l.sub!(/.*\sExternal\s+\|\s+/, '') + if noprefix or l.sub!(/^_/, '') + 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 + end + end + end + yield "strcasecmp", "msvcrt.stricmp" + yield "strncasecmp", "msvcrt.strnicmp" + end end + +class Exports::Mingw < Exports + def self.nm + @@nm ||= Config::CONFIG["NM"] + end + + def each_export(objs) + IO.popen([self.class.nm, "--extern", "--defined", *objs]) do |f| + f.each {|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