[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
This commit is contained in:
parent
ae7b53546c
commit
e2dfc0c26b
Notes:
git
2020-11-18 09:05:47 +09:00
@ -1,5 +1,113 @@
|
|||||||
#include <fiddle.h>
|
#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 *
|
ffi_type *
|
||||||
rb_fiddle_int_to_ffi_type(int type)
|
rb_fiddle_int_to_ffi_type(int type)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,7 @@ typedef union
|
|||||||
} fiddle_generic;
|
} fiddle_generic;
|
||||||
|
|
||||||
/* Deprecated. Use rb_fiddle_*() version. */
|
/* Deprecated. Use rb_fiddle_*() version. */
|
||||||
|
VALUE rb_fiddle_type_ensure(VALUE type);
|
||||||
ffi_type * rb_fiddle_int_to_ffi_type(int type);
|
ffi_type * rb_fiddle_int_to_ffi_type(int type);
|
||||||
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
|
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
|
||||||
VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval);
|
VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval);
|
||||||
|
@ -3,38 +3,6 @@
|
|||||||
VALUE mFiddle;
|
VALUE mFiddle;
|
||||||
VALUE rb_eFiddleError;
|
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);
|
void Init_fiddle_pointer(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -118,6 +118,38 @@
|
|||||||
#define TYPE_VARIADIC 9
|
#define TYPE_VARIADIC 9
|
||||||
#define TYPE_CONST_STRING 10
|
#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_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
|
||||||
|
|
||||||
#define ALIGN_VOIDP ALIGN_OF(void*)
|
#define ALIGN_VOIDP ALIGN_OF(void*)
|
||||||
|
@ -106,7 +106,9 @@ normalize_argument_types(const char *name,
|
|||||||
normalized_arg_types = rb_ary_new_capa(n_arg_types);
|
normalized_arg_types = rb_ary_new_capa(n_arg_types);
|
||||||
for (i = 0; i < n_arg_types; i++) {
|
for (i = 0; i < n_arg_types; i++) {
|
||||||
VALUE arg_type = RARRAY_AREF(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 (c_arg_type == TYPE_VARIADIC) {
|
||||||
if (i != n_arg_types - 1) {
|
if (i != n_arg_types - 1) {
|
||||||
rb_raise(rb_eArgError,
|
rb_raise(rb_eArgError,
|
||||||
@ -146,6 +148,7 @@ initialize(int argc, VALUE argv[], VALUE self)
|
|||||||
PTR2NUM(cfunc);
|
PTR2NUM(cfunc);
|
||||||
c_ffi_abi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
|
c_ffi_abi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
|
||||||
abi = INT2FIX(c_ffi_abi);
|
abi = INT2FIX(c_ffi_abi);
|
||||||
|
ret_type = rb_fiddle_type_ensure(ret_type);
|
||||||
c_ret_type = NUM2INT(ret_type);
|
c_ret_type = NUM2INT(ret_type);
|
||||||
(void)INT2FFI_TYPE(c_ret_type); /* raise */
|
(void)INT2FFI_TYPE(c_ret_type); /* raise */
|
||||||
ret_type = INT2FIX(c_ret_type);
|
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);
|
arg_types = rb_ary_dup(fixed_arg_types);
|
||||||
for (i = n_fixed_args; i < argc; i += 2) {
|
for (i = n_fixed_args; i < argc; i += 2) {
|
||||||
VALUE arg_type = argv[i];
|
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 */
|
(void)INT2FFI_TYPE(c_arg_type); /* raise */
|
||||||
rb_ary_push(arg_types, INT2FIX(c_arg_type));
|
rb_ary_push(arg_types, INT2FIX(c_arg_type));
|
||||||
}
|
}
|
||||||
|
@ -96,22 +96,22 @@ module Fiddle
|
|||||||
end
|
end
|
||||||
snprintf = Function.new(snprintf_pointer,
|
snprintf = Function.new(snprintf_pointer,
|
||||||
[
|
[
|
||||||
TYPE_VOIDP,
|
:voidp,
|
||||||
TYPE_SIZE_T,
|
:size_t,
|
||||||
TYPE_CONST_STRING,
|
:const_string,
|
||||||
TYPE_VARIADIC,
|
:variadic,
|
||||||
],
|
],
|
||||||
TYPE_INT)
|
:int)
|
||||||
output_buffer = " " * 1024
|
output_buffer = " " * 1024
|
||||||
output = Pointer[output_buffer]
|
output = Pointer[output_buffer]
|
||||||
|
|
||||||
written = snprintf.call(output,
|
written = snprintf.call(output,
|
||||||
output.size,
|
output.size,
|
||||||
"int: %d, string: %.*s, const string: %s\n",
|
"int: %d, string: %.*s, const string: %s\n",
|
||||||
TYPE_INT, -29,
|
:int, -29,
|
||||||
TYPE_INT, 4,
|
:int, 4,
|
||||||
TYPE_VOIDP, "Hello",
|
:voidp, "Hello",
|
||||||
TYPE_CONST_STRING, "World")
|
:const_string, "World")
|
||||||
assert_equal("int: -29, string: Hell, const string: World\n",
|
assert_equal("int: -29, string: Hell, const string: World\n",
|
||||||
output_buffer[0, written])
|
output_buffer[0, written])
|
||||||
|
|
||||||
@ -127,10 +127,10 @@ module Fiddle
|
|||||||
written = snprintf.call(output,
|
written = snprintf.call(output,
|
||||||
output.size,
|
output.size,
|
||||||
"string: %.*s, const string: %s, uint: %u\n",
|
"string: %.*s, const string: %s, uint: %u\n",
|
||||||
TYPE_INT, 2,
|
:int, 2,
|
||||||
TYPE_VOIDP, "Hello",
|
:voidp, "Hello",
|
||||||
TYPE_CONST_STRING, string_like_class.new("World"),
|
:const_string, string_like_class.new("World"),
|
||||||
TYPE_INT, 29)
|
:int, 29)
|
||||||
assert_equal("string: He, const string: World, uint: 29\n",
|
assert_equal("string: He, const string: World, uint: 29\n",
|
||||||
output_buffer[0, written])
|
output_buffer[0, written])
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user