diff options
author | Sutou Kouhei <kou@clear-code.com> | 2020-07-09 21:39:51 +0900 |
---|---|---|
committer | Sutou Kouhei <kou@cozmixng.org> | 2020-11-18 09:05:13 +0900 |
commit | e2dfc0c26b1f3d3517002ca2645d1b67847fe518 (patch) | |
tree | 943da48b87240b9b32c7885d332ef1488f270b6f /ext/fiddle | |
parent | ae7b53546ca18b56c23f612b6935e98268a07602 (diff) | |
download | ruby-e2dfc0c26b1f3d3517002ca2645d1b67847fe518.tar.gz |
[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
Diffstat (limited to 'ext/fiddle')
-rw-r--r-- | ext/fiddle/conversions.c | 108 | ||||
-rw-r--r-- | ext/fiddle/conversions.h | 1 | ||||
-rw-r--r-- | ext/fiddle/fiddle.c | 32 | ||||
-rw-r--r-- | ext/fiddle/fiddle.h | 32 | ||||
-rw-r--r-- | ext/fiddle/function.c | 9 |
5 files changed, 148 insertions, 34 deletions
diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c index 19bdd8a896..27b703df9e 100644 --- a/ext/fiddle/conversions.c +++ b/ext/fiddle/conversions.c @@ -1,5 +1,113 @@ #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 f900efa9ad..1de956e90c 100644 --- a/ext/fiddle/conversions.h +++ b/ext/fiddle/conversions.h @@ -25,6 +25,7 @@ typedef union } 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 be287e6fdb..e6435ba3f3 100644 --- a/ext/fiddle/fiddle.c +++ b/ext/fiddle/fiddle.c @@ -3,38 +3,6 @@ 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 f142229b0c..16f12cab74 100644 --- a/ext/fiddle/fiddle.h +++ b/ext/fiddle/fiddle.h @@ -118,6 +118,38 @@ #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 8771dd3e30..437dbb624a 100644 --- a/ext/fiddle/function.c +++ b/ext/fiddle/function.c @@ -106,7 +106,9 @@ normalize_argument_types(const char *name, 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) 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) 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)); } |