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

ruby-changes:63631

From: Sutou <ko1@a...>
Date: Wed, 18 Nov 2020 09:05:38 +0900 (JST)
Subject: [ruby-changes:63631] e2dfc0c26b (master): [ruby/fiddle] Add support for specifying types by name as String or Symbol

https://git.ruby-lang.org/ruby.git/commit/?id=e2dfc0c26b

From e2dfc0c26b1f3d3517002ca2645d1b67847fe518 Mon Sep 17 00:00:00 2001
From: Sutou Kouhei <kou@c...>
Date: Thu, 9 Jul 2020 21:39:51 +0900
Subject: [ruby/fiddle] Add support for specifying types by name as String or
 Symbol

For example, :voidp equals to Fiddle::TYPE_VOID_P.

https://github.com/ruby/fiddle/commit/3b4de54899

diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c
index 19bdd8a..27b703d 100644
--- a/ext/fiddle/conversions.c
+++ b/ext/fiddle/conversions.c
@@ -1,5 +1,113 @@ https://github.com/ruby/ruby/blob/trunk/ext/fiddle/conversions.c#L1
 #include <fiddle.h>
 
+VALUE
+rb_fiddle_type_ensure(VALUE type)
+{
+    VALUE original_type = type;
+
+    if (!RB_SYMBOL_P(type)) {
+        VALUE type_string = rb_check_string_type(type);
+        if (!NIL_P(type_string)) {
+            type = rb_to_symbol(type_string);
+        }
+    }
+
+    if (RB_SYMBOL_P(type)) {
+        ID type_id = rb_sym2id(type);
+        ID void_id;
+        ID voidp_id;
+        ID char_id;
+        ID short_id;
+        ID int_id;
+        ID long_id;
+#ifdef TYPE_LONG_LONG
+        ID long_long_id;
+#endif
+        ID float_id;
+        ID double_id;
+        ID variadic_id;
+        ID const_string_id;
+        ID size_t_id;
+        ID ssize_t_id;
+        ID ptrdiff_t_id;
+        ID intptr_t_id;
+        ID uintptr_t_id;
+        RUBY_CONST_ID(void_id, "void");
+        RUBY_CONST_ID(voidp_id, "voidp");
+        RUBY_CONST_ID(char_id, "char");
+        RUBY_CONST_ID(short_id, "short");
+        RUBY_CONST_ID(int_id, "int");
+        RUBY_CONST_ID(long_id, "long");
+#ifdef TYPE_LONG_LONG
+        RUBY_CONST_ID(long_long_id, "long_long");
+#endif
+        RUBY_CONST_ID(float_id, "float");
+        RUBY_CONST_ID(double_id, "double");
+        RUBY_CONST_ID(variadic_id, "variadic");
+        RUBY_CONST_ID(const_string_id, "const_string");
+        RUBY_CONST_ID(size_t_id, "size_t");
+        RUBY_CONST_ID(ssize_t_id, "ssize_t");
+        RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
+        RUBY_CONST_ID(intptr_t_id, "intptr_t");
+        RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
+        if (type_id == void_id) {
+            return INT2NUM(TYPE_VOID);
+        }
+        else if (type_id == voidp_id) {
+            return INT2NUM(TYPE_VOIDP);
+        }
+        else if (type_id == char_id) {
+            return INT2NUM(TYPE_CHAR);
+        }
+        else if (type_id == short_id) {
+            return INT2NUM(TYPE_SHORT);
+        }
+        else if (type_id == int_id) {
+            return INT2NUM(TYPE_INT);
+        }
+        else if (type_id == long_id) {
+            return INT2NUM(TYPE_LONG);
+        }
+#ifdef TYPE_LONG_LONG
+        else if (type_id == long_long_id) {
+            return INT2NUM(TYPE_LONG_LONG);
+        }
+#endif
+        else if (type_id == float_id) {
+            return INT2NUM(TYPE_FLOAT);
+        }
+        else if (type_id == double_id) {
+            return INT2NUM(TYPE_DOUBLE);
+        }
+        else if (type_id == variadic_id) {
+            return INT2NUM(TYPE_VARIADIC);
+        }
+        else if (type_id == const_string_id) {
+            return INT2NUM(TYPE_CONST_STRING);
+        }
+        else if (type_id == size_t_id) {
+            return INT2NUM(TYPE_SIZE_T);
+        }
+        else if (type_id == ssize_t_id) {
+            return INT2NUM(TYPE_SSIZE_T);
+        }
+        else if (type_id == ptrdiff_t_id) {
+            return INT2NUM(TYPE_PTRDIFF_T);
+        }
+        else if (type_id == intptr_t_id) {
+            return INT2NUM(TYPE_INTPTR_T);
+        }
+        else if (type_id == uintptr_t_id) {
+            return INT2NUM(TYPE_UINTPTR_T);
+        }
+        else {
+            type = original_type;
+        }
+    }
+
+    return rb_to_int(type);
+}
+
 ffi_type *
 rb_fiddle_int_to_ffi_type(int type)
 {
diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h
index f900efa..1de956e 100644
--- a/ext/fiddle/conversions.h
+++ b/ext/fiddle/conversions.h
@@ -25,6 +25,7 @@ typedef union https://github.com/ruby/ruby/blob/trunk/ext/fiddle/conversions.h#L25
 } fiddle_generic;
 
 /* Deprecated. Use rb_fiddle_*() version. */
+VALUE rb_fiddle_type_ensure(VALUE type);
 ffi_type * rb_fiddle_int_to_ffi_type(int type);
 void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
 VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval);
diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c
index be287e6..e6435ba 100644
--- a/ext/fiddle/fiddle.c
+++ b/ext/fiddle/fiddle.c
@@ -3,38 +3,6 @@ https://github.com/ruby/ruby/blob/trunk/ext/fiddle/fiddle.c#L3
 VALUE mFiddle;
 VALUE rb_eFiddleError;
 
-#ifndef TYPE_SSIZE_T
-# if SIZEOF_SIZE_T == SIZEOF_INT
-#   define TYPE_SSIZE_T TYPE_INT
-# elif SIZEOF_SIZE_T == SIZEOF_LONG
-#   define TYPE_SSIZE_T TYPE_LONG
-# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
-#   define TYPE_SSIZE_T TYPE_LONG_LONG
-# endif
-#endif
-#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
-
-#ifndef TYPE_PTRDIFF_T
-# if SIZEOF_PTRDIFF_T == SIZEOF_INT
-#   define TYPE_PTRDIFF_T TYPE_INT
-# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
-#   define TYPE_PTRDIFF_T TYPE_LONG
-# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
-#   define TYPE_PTRDIFF_T TYPE_LONG_LONG
-# endif
-#endif
-
-#ifndef TYPE_INTPTR_T
-# if SIZEOF_INTPTR_T == SIZEOF_INT
-#   define TYPE_INTPTR_T TYPE_INT
-# elif SIZEOF_INTPTR_T == SIZEOF_LONG
-#   define TYPE_INTPTR_T TYPE_LONG
-# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
-#   define TYPE_INTPTR_T TYPE_LONG_LONG
-# endif
-#endif
-#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
-
 void Init_fiddle_pointer(void);
 
 /*
diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h
index f142229..16f12ca 100644
--- a/ext/fiddle/fiddle.h
+++ b/ext/fiddle/fiddle.h
@@ -118,6 +118,38 @@ https://github.com/ruby/ruby/blob/trunk/ext/fiddle/fiddle.h#L118
 #define TYPE_VARIADIC 9
 #define TYPE_CONST_STRING 10
 
+#ifndef TYPE_SSIZE_T
+# if SIZEOF_SIZE_T == SIZEOF_INT
+#   define TYPE_SSIZE_T TYPE_INT
+# elif SIZEOF_SIZE_T == SIZEOF_LONG
+#   define TYPE_SSIZE_T TYPE_LONG
+# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+#   define TYPE_SSIZE_T TYPE_LONG_LONG
+# endif
+#endif
+#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
+
+#ifndef TYPE_PTRDIFF_T
+# if SIZEOF_PTRDIFF_T == SIZEOF_INT
+#   define TYPE_PTRDIFF_T TYPE_INT
+# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
+#   define TYPE_PTRDIFF_T TYPE_LONG
+# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
+#   define TYPE_PTRDIFF_T TYPE_LONG_LONG
+# endif
+#endif
+
+#ifndef TYPE_INTPTR_T
+# if SIZEOF_INTPTR_T == SIZEOF_INT
+#   define TYPE_INTPTR_T TYPE_INT
+# elif SIZEOF_INTPTR_T == SIZEOF_LONG
+#   define TYPE_INTPTR_T TYPE_LONG
+# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
+#   define TYPE_INTPTR_T TYPE_LONG_LONG
+# endif
+#endif
+#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
+
 #define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
 
 #define ALIGN_VOIDP  ALIGN_OF(void*)
diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c
index 8771dd3..437dbb6 100644
--- a/ext/fiddle/function.c
+++ b/ext/fiddle/function.c
@@ -106,7 +106,9 @@ normalize_argument_types(const char *name, https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L106
     normalized_arg_types = rb_ary_new_capa(n_arg_types);
     for (i = 0; i < n_arg_types; i++) {
         VALUE arg_type = RARRAY_AREF(arg_types, i);
-        int c_arg_type = NUM2INT(arg_type);
+        int c_arg_type;
+        arg_type = rb_fiddle_type_ensure(arg_type);
+        c_arg_type = NUM2INT(arg_type);
         if (c_arg_type == TYPE_VARIADIC) {
             if (i != n_arg_types - 1) {
                 rb_raise(rb_eArgError,
@@ -146,6 +148,7 @@ initialize(int argc, VALUE argv[], VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L148
     PTR2NUM(cfunc);
     c_ffi_abi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
     abi = INT2FIX(c_ffi_abi);
+    ret_type = rb_fiddle_type_ensure(ret_type);
     c_ret_type = NUM2INT(ret_type);
     (void)INT2FFI_TYPE(c_ret_type); /* raise */
     ret_type = INT2FIX(c_ret_type);
@@ -256,7 +259,9 @@ function_call(int argc, VALUE argv[], VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L259
         arg_types = rb_ary_dup(fixed_arg_types);
         for (i = n_fixed_args; i < argc; i += 2) {
           VALUE arg_type = argv[i];
-          int c_arg_type = NUM2INT(arg_type);
+          int c_arg_type;
+          arg_type = rb_fiddle_type_ensure(arg_type);
+          c_arg_type = NUM2INT(arg_type);
           (void)INT2FFI_TYPE(c_arg_type); /* raise */
           rb_ary_push(arg_types, INT2FIX(c_arg_type));
         }
diff --git a/test/fiddle/test_func.rb b/test/fiddle/test_func.rb
index ca9d4cc..d3604c7 100644
--- a/test/fiddle/test_func.rb
+++ b/test/fiddle/test_func.rb
@@ -96,22 +96,22 @@ module Fiddle https://github.com/ruby/ruby/blob/trunk/test/fiddle/test_func.rb#L96
       end
       snprintf = Function.new(snprintf_pointer,
                               [
-                                TYPE_VOIDP,
-                                TYPE_SIZE_T,
-                                TYPE_CONST_STRING,
-                                TYPE_VARIADIC,
+                                :voidp,
+                                :size_t,
+                                :const_string,
+                                :variadic,
                               ],
-                              TYPE_INT)
+                              :int)
       output_buffer = " " * 1024
       output = Pointer[output_buffer]
 
       written = snprintf.call(output,
                               output.size,
                               "int: %d, string: %.*s, const string: %s\n",
-                              TYPE_INT, -29,
-                              TYPE_INT, 4,
-                              TYPE_VOIDP, "Hello" (... truncated)

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

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