[前][次][番号順一覧][スレッド一覧]

ruby-changes:18048

From: nobu <ko1@a...>
Date: Fri, 3 Dec 2010 19:56:19 +0900 (JST)
Subject: [ruby-changes:18048] Ruby:r30069 (trunk): * lib/mkmf.rb (convertible_int): detect convertible integer type.

nobu	2010-12-03 19:53:53 +0900 (Fri, 03 Dec 2010)

  New Revision: 30069

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30069

  Log:
    * lib/mkmf.rb (convertible_int): detect convertible integer type.
      port RUBY_REPLACE_INT from configure.in.

  Added files:
    trunk/test/mkmf/test_convertible.rb
  Modified files:
    trunk/ChangeLog
    trunk/lib/mkmf.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 30068)
+++ ChangeLog	(revision 30069)
@@ -1,5 +1,8 @@
-Fri Dec  3 19:48:11 2010  Nobuyoshi Nakada  <nobu@r...>
+Fri Dec  3 19:53:50 2010  Nobuyoshi Nakada  <nobu@r...>
 
+	* lib/mkmf.rb (convertible_int): detect convertible integer type.
+	  port RUBY_REPLACE_INT from configure.in.
+
 	* lib/mkmf.rb (check_sizeof): should return integer always.
 
 Fri Dec  3 12:54:48 2010  NAKAMURA Usaku  <usa@r...>
Index: lib/mkmf.rb
===================================================================
--- lib/mkmf.rb	(revision 30068)
+++ lib/mkmf.rb	(revision 30069)
@@ -1084,6 +1084,23 @@
 def STRING_OR_FAILED_FORMAT.%(x)
   x ? super : "failed"
 end
+
+def typedef_expr(type, headers)
+  typename, member = type.split('.', 2)
+  prelude = cpp_include(headers).split(/$/)
+  prelude << "typedef #{typename} rbcv_typedef_;\n"
+  return "rbcv_typedef_", member, prelude
+end
+
+def try_signedness(type, member, headers = nil, opts = nil, &b)
+  raise ArgumentError, "don't know how to tell signedness of members" if member
+  if try_static_assert("(#{type})-1 < 0", headers, opts)
+    return -1
+  elsif try_static_assert("(#{type})-1 > 0", headers, opts)
+    return +1
+  end
+end
+
 # :startdoc:
 
 # Returns the size of the given +type+.  You may optionally specify additional
@@ -1097,10 +1114,8 @@
 # SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
 #
 def check_sizeof(type, headers = nil, opts = "", &b)
-  typename, member = type.split('.', 2)
-  prelude = cpp_include(headers).split(/$/)
-  prelude << "typedef #{typename} rbcv_typedef_;\n"
-  prelude << "static rbcv_typedef_ *rbcv_ptr_;\n"
+  typedef, member, prelude = typedef_expr(type, headers)
+  prelude << "static #{typedef} *rbcv_ptr_;\n"
   prelude = [prelude]
   expr = "sizeof((*rbcv_ptr_)#{"." << member if member})"
   fmt = STRING_OR_FAILED_FORMAT
@@ -1127,22 +1142,63 @@
 # compiler, and SIGNEDNESS_OF_INT=-1 if check_signedness('int') is
 # done.
 #
-def check_signedness(type, headers = nil)
+def check_signedness(type, headers = nil, opts = nil, &b)
+  typedef, member, prelude = typedef_expr(type, headers)
   signed = nil
   checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
-    if try_static_assert("(#{type})-1 < 0")
-      signed = -1
-    elsif try_static_assert("(#{type})-1 > 0")
-      signed = +1
-    else
-      next nil
-    end
+    signed = try_signedness(typedef, member, headers, opts, &b) or next nil
     $defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
     signed < 0 ? "signed" : "unsigned"
   end
   signed
 end
 
+# Returns the convertible integer type of the given +type+.  You may
+# optionally specify additional +headers+ to search in for the +type+.
+# _Convertible_ means actually same type, or typedefed from same type.
+#
+# If the +type+ is a integer type and _convertible_ type is found,
+# following macros are passed as preprocessor constants to the
+# compiler using the +type+ name, in uppercase.
+#
+# * 'TYPEOF_', followed by the +type+ name, followed by '=X' where 'X'
+#   is the found _convertible_ type name.
+# * 'TYP2NUM' and 'NUM2TYP, where 'TYP' is the +type+ name in uppercase sans '_t'
+#   suffix, followed by '=X' where 'X' is the macro name to convert
+#   +type+ to +Integer+ object, and vice versa.
+#
+# For example, if foobar_t is defined as unsigned long, then
+# convertible_int("foobar_t") would return "unsigned long", and define
+# macros:
+#
+#   #define TYPEOF_FOOBAR_T unsigned long
+#   #define FOOBAR2NUM ULONG2NUM
+#   #define NUM2FOOBAR NUM2ULONG
+def convertible_int(type, headers = nil, opts = nil, &b)
+  type, macname = *type
+  checking_for("convertible type of #{type}", STRING_OR_FAILED_FORMAT) do
+    if UNIVERSAL_INTS.include?(type)
+      type
+    else
+      typedef, member, prelude = typedef_expr(type, headers, &b)
+      next unless signed = try_signedness(typedef, member, [prelude])
+      u = "unsigned " if signed > 0
+      prelude << "extern rbcv_typedef_ foo();"
+      compat = UNIVERSAL_INTS.find {|t|
+	try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, &b)
+      }
+      if compat
+	macname ||= type.chomp("_t").tr_cpp
+	conv = (u ? "U" : "") + (compat == "long long" ? "LL" : compat.upcase)
+	compat = "#{u}#{compat}"
+	$defs.push(format("-DTYPEOF_%s=%s", type.tr_cpp, compat.quote))
+	$defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
+	$defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
+	compat
+      end
+    end
+  end
+end
 # :stopdoc:
 
 # Used internally by the what_type? method to determine if +type+ is a scalar
Index: test/mkmf/test_convertible.rb
===================================================================
--- test/mkmf/test_convertible.rb	(revision 0)
+++ test/mkmf/test_convertible.rb	(revision 30069)
@@ -0,0 +1,26 @@
+require_relative 'base'
+
+class TestMkmf
+  class TestConvertible < TestMkmf
+    def test_typeof_builtin
+      ["", ["signed ", ""], "unsigned "].each do |signed, prefix|
+        %w[short int long].each do |type|
+          assert_equal((prefix || signed)+type,
+                       mkmf {convertible_int(signed+type)})
+        end
+      end
+    end
+
+    def test_typeof_typedef
+      ["", ["signed ", ""], "unsigned "].each do |signed, prefix|
+        %w[short int long].each do |type|
+          open("confdefs.h", "w") {|f|
+            f.puts "typedef #{signed}#{type} test1_t;"
+          }
+          assert_equal((prefix || signed)+type,
+                       mkmf {convertible_int("test1_t", "confdefs.h")})
+        end
+      end
+    end
+  end
+end

Property changes on: test/mkmf/test_convertible.rb
___________________________________________________________________
Added: svn:eol-style
   + LF


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]