Skip to content

Commit e2dfc0c

Browse files
committed
[ruby/fiddle] Add support for specifying types by name as String or Symbol
For example, :voidp equals to Fiddle::TYPE_VOID_P. ruby/fiddle@3b4de54899
1 parent ae7b535 commit e2dfc0c

File tree

6 files changed

+161
-47
lines changed

6 files changed

+161
-47
lines changed

ext/fiddle/conversions.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,113 @@
11
#include <fiddle.h>
22

3+
VALUE
4+
rb_fiddle_type_ensure(VALUE type)
5+
{
6+
VALUE original_type = type;
7+
8+
if (!RB_SYMBOL_P(type)) {
9+
VALUE type_string = rb_check_string_type(type);
10+
if (!NIL_P(type_string)) {
11+
type = rb_to_symbol(type_string);
12+
}
13+
}
14+
15+
if (RB_SYMBOL_P(type)) {
16+
ID type_id = rb_sym2id(type);
17+
ID void_id;
18+
ID voidp_id;
19+
ID char_id;
20+
ID short_id;
21+
ID int_id;
22+
ID long_id;
23+
#ifdef TYPE_LONG_LONG
24+
ID long_long_id;
25+
#endif
26+
ID float_id;
27+
ID double_id;
28+
ID variadic_id;
29+
ID const_string_id;
30+
ID size_t_id;
31+
ID ssize_t_id;
32+
ID ptrdiff_t_id;
33+
ID intptr_t_id;
34+
ID uintptr_t_id;
35+
RUBY_CONST_ID(void_id, "void");
36+
RUBY_CONST_ID(voidp_id, "voidp");
37+
RUBY_CONST_ID(char_id, "char");
38+
RUBY_CONST_ID(short_id, "short");
39+
RUBY_CONST_ID(int_id, "int");
40+
RUBY_CONST_ID(long_id, "long");
41+
#ifdef TYPE_LONG_LONG
42+
RUBY_CONST_ID(long_long_id, "long_long");
43+
#endif
44+
RUBY_CONST_ID(float_id, "float");
45+
RUBY_CONST_ID(double_id, "double");
46+
RUBY_CONST_ID(variadic_id, "variadic");
47+
RUBY_CONST_ID(const_string_id, "const_string");
48+
RUBY_CONST_ID(size_t_id, "size_t");
49+
RUBY_CONST_ID(ssize_t_id, "ssize_t");
50+
RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
51+
RUBY_CONST_ID(intptr_t_id, "intptr_t");
52+
RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
53+
if (type_id == void_id) {
54+
return INT2NUM(TYPE_VOID);
55+
}
56+
else if (type_id == voidp_id) {
57+
return INT2NUM(TYPE_VOIDP);
58+
}
59+
else if (type_id == char_id) {
60+
return INT2NUM(TYPE_CHAR);
61+
}
62+
else if (type_id == short_id) {
63+
return INT2NUM(TYPE_SHORT);
64+
}
65+
else if (type_id == int_id) {
66+
return INT2NUM(TYPE_INT);
67+
}
68+
else if (type_id == long_id) {
69+
return INT2NUM(TYPE_LONG);
70+
}
71+
#ifdef TYPE_LONG_LONG
72+
else if (type_id == long_long_id) {
73+
return INT2NUM(TYPE_LONG_LONG);
74+
}
75+
#endif
76+
else if (type_id == float_id) {
77+
return INT2NUM(TYPE_FLOAT);
78+
}
79+
else if (type_id == double_id) {
80+
return INT2NUM(TYPE_DOUBLE);
81+
}
82+
else if (type_id == variadic_id) {
83+
return INT2NUM(TYPE_VARIADIC);
84+
}
85+
else if (type_id == const_string_id) {
86+
return INT2NUM(TYPE_CONST_STRING);
87+
}
88+
else if (type_id == size_t_id) {
89+
return INT2NUM(TYPE_SIZE_T);
90+
}
91+
else if (type_id == ssize_t_id) {
92+
return INT2NUM(TYPE_SSIZE_T);
93+
}
94+
else if (type_id == ptrdiff_t_id) {
95+
return INT2NUM(TYPE_PTRDIFF_T);
96+
}
97+
else if (type_id == intptr_t_id) {
98+
return INT2NUM(TYPE_INTPTR_T);
99+
}
100+
else if (type_id == uintptr_t_id) {
101+
return INT2NUM(TYPE_UINTPTR_T);
102+
}
103+
else {
104+
type = original_type;
105+
}
106+
}
107+
108+
return rb_to_int(type);
109+
}
110+
3111
ffi_type *
4112
rb_fiddle_int_to_ffi_type(int type)
5113
{

ext/fiddle/conversions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef union
2525
} fiddle_generic;
2626

2727
/* Deprecated. Use rb_fiddle_*() version. */
28+
VALUE rb_fiddle_type_ensure(VALUE type);
2829
ffi_type * rb_fiddle_int_to_ffi_type(int type);
2930
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
3031
VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval);

ext/fiddle/fiddle.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,6 @@
33
VALUE mFiddle;
44
VALUE rb_eFiddleError;
55

6-
#ifndef TYPE_SSIZE_T
7-
# if SIZEOF_SIZE_T == SIZEOF_INT
8-
# define TYPE_SSIZE_T TYPE_INT
9-
# elif SIZEOF_SIZE_T == SIZEOF_LONG
10-
# define TYPE_SSIZE_T TYPE_LONG
11-
# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
12-
# define TYPE_SSIZE_T TYPE_LONG_LONG
13-
# endif
14-
#endif
15-
#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
16-
17-
#ifndef TYPE_PTRDIFF_T
18-
# if SIZEOF_PTRDIFF_T == SIZEOF_INT
19-
# define TYPE_PTRDIFF_T TYPE_INT
20-
# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
21-
# define TYPE_PTRDIFF_T TYPE_LONG
22-
# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
23-
# define TYPE_PTRDIFF_T TYPE_LONG_LONG
24-
# endif
25-
#endif
26-
27-
#ifndef TYPE_INTPTR_T
28-
# if SIZEOF_INTPTR_T == SIZEOF_INT
29-
# define TYPE_INTPTR_T TYPE_INT
30-
# elif SIZEOF_INTPTR_T == SIZEOF_LONG
31-
# define TYPE_INTPTR_T TYPE_LONG
32-
# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
33-
# define TYPE_INTPTR_T TYPE_LONG_LONG
34-
# endif
35-
#endif
36-
#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
37-
386
void Init_fiddle_pointer(void);
397

408
/*

ext/fiddle/fiddle.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,38 @@
118118
#define TYPE_VARIADIC 9
119119
#define TYPE_CONST_STRING 10
120120

121+
#ifndef TYPE_SSIZE_T
122+
# if SIZEOF_SIZE_T == SIZEOF_INT
123+
# define TYPE_SSIZE_T TYPE_INT
124+
# elif SIZEOF_SIZE_T == SIZEOF_LONG
125+
# define TYPE_SSIZE_T TYPE_LONG
126+
# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
127+
# define TYPE_SSIZE_T TYPE_LONG_LONG
128+
# endif
129+
#endif
130+
#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
131+
132+
#ifndef TYPE_PTRDIFF_T
133+
# if SIZEOF_PTRDIFF_T == SIZEOF_INT
134+
# define TYPE_PTRDIFF_T TYPE_INT
135+
# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
136+
# define TYPE_PTRDIFF_T TYPE_LONG
137+
# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
138+
# define TYPE_PTRDIFF_T TYPE_LONG_LONG
139+
# endif
140+
#endif
141+
142+
#ifndef TYPE_INTPTR_T
143+
# if SIZEOF_INTPTR_T == SIZEOF_INT
144+
# define TYPE_INTPTR_T TYPE_INT
145+
# elif SIZEOF_INTPTR_T == SIZEOF_LONG
146+
# define TYPE_INTPTR_T TYPE_LONG
147+
# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
148+
# define TYPE_INTPTR_T TYPE_LONG_LONG
149+
# endif
150+
#endif
151+
#define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
152+
121153
#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
122154

123155
#define ALIGN_VOIDP ALIGN_OF(void*)

ext/fiddle/function.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ normalize_argument_types(const char *name,
106106
normalized_arg_types = rb_ary_new_capa(n_arg_types);
107107
for (i = 0; i < n_arg_types; i++) {
108108
VALUE arg_type = RARRAY_AREF(arg_types, i);
109-
int c_arg_type = NUM2INT(arg_type);
109+
int c_arg_type;
110+
arg_type = rb_fiddle_type_ensure(arg_type);
111+
c_arg_type = NUM2INT(arg_type);
110112
if (c_arg_type == TYPE_VARIADIC) {
111113
if (i != n_arg_types - 1) {
112114
rb_raise(rb_eArgError,
@@ -146,6 +148,7 @@ initialize(int argc, VALUE argv[], VALUE self)
146148
PTR2NUM(cfunc);
147149
c_ffi_abi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
148150
abi = INT2FIX(c_ffi_abi);
151+
ret_type = rb_fiddle_type_ensure(ret_type);
149152
c_ret_type = NUM2INT(ret_type);
150153
(void)INT2FFI_TYPE(c_ret_type); /* raise */
151154
ret_type = INT2FIX(c_ret_type);
@@ -256,7 +259,9 @@ function_call(int argc, VALUE argv[], VALUE self)
256259
arg_types = rb_ary_dup(fixed_arg_types);
257260
for (i = n_fixed_args; i < argc; i += 2) {
258261
VALUE arg_type = argv[i];
259-
int c_arg_type = NUM2INT(arg_type);
262+
int c_arg_type;
263+
arg_type = rb_fiddle_type_ensure(arg_type);
264+
c_arg_type = NUM2INT(arg_type);
260265
(void)INT2FFI_TYPE(c_arg_type); /* raise */
261266
rb_ary_push(arg_types, INT2FIX(c_arg_type));
262267
}

test/fiddle/test_func.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,22 @@ def test_snprintf
9696
end
9797
snprintf = Function.new(snprintf_pointer,
9898
[
99-
TYPE_VOIDP,
100-
TYPE_SIZE_T,
101-
TYPE_CONST_STRING,
102-
TYPE_VARIADIC,
99+
:voidp,
100+
:size_t,
101+
:const_string,
102+
:variadic,
103103
],
104-
TYPE_INT)
104+
:int)
105105
output_buffer = " " * 1024
106106
output = Pointer[output_buffer]
107107

108108
written = snprintf.call(output,
109109
output.size,
110110
"int: %d, string: %.*s, const string: %s\n",
111-
TYPE_INT, -29,
112-
TYPE_INT, 4,
113-
TYPE_VOIDP, "Hello",
114-
TYPE_CONST_STRING, "World")
111+
:int, -29,
112+
:int, 4,
113+
:voidp, "Hello",
114+
:const_string, "World")
115115
assert_equal("int: -29, string: Hell, const string: World\n",
116116
output_buffer[0, written])
117117

@@ -127,10 +127,10 @@ def to_str
127127
written = snprintf.call(output,
128128
output.size,
129129
"string: %.*s, const string: %s, uint: %u\n",
130-
TYPE_INT, 2,
131-
TYPE_VOIDP, "Hello",
132-
TYPE_CONST_STRING, string_like_class.new("World"),
133-
TYPE_INT, 29)
130+
:int, 2,
131+
:voidp, "Hello",
132+
:const_string, string_like_class.new("World"),
133+
:int, 29)
134134
assert_equal("string: He, const string: World, uint: 29\n",
135135
output_buffer[0, written])
136136
end

0 commit comments

Comments
 (0)