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/