diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c index af18f8b31edda0..b0dcf84873a72a 100644 --- a/ext/fiddle/conversions.c +++ b/ext/fiddle/conversions.c @@ -1,5 +1,24 @@ #include +VALUE +rb_fiddle_type_bool(void) +{ + if (sizeof(bool) == sizeof(char)) { + return INT2NUM(TYPE_UCHAR); + } else if (sizeof(bool) == sizeof(short)) { + return INT2NUM(TYPE_USHORT); + } else if (sizeof(bool) == sizeof(int)) { + return INT2NUM(TYPE_UINT); + } else if (sizeof(bool) == sizeof(long)) { + return INT2NUM(TYPE_ULONG); + } else { + rb_raise(rb_eNotImpError, + "bool isn't supported: %u", + (unsigned int)sizeof(bool)); + return RUBY_Qnil; + } +} + VALUE rb_fiddle_type_ensure(VALUE type) { @@ -44,6 +63,7 @@ rb_fiddle_type_ensure(VALUE type) ID ptrdiff_t_id; ID intptr_t_id; ID uintptr_t_id; + ID bool_id; RUBY_CONST_ID(void_id, "void"); RUBY_CONST_ID(voidp_id, "voidp"); RUBY_CONST_ID(char_id, "char"); @@ -74,6 +94,7 @@ rb_fiddle_type_ensure(VALUE type) RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t"); RUBY_CONST_ID(intptr_t_id, "intptr_t"); RUBY_CONST_ID(uintptr_t_id, "uintptr_t"); + RUBY_CONST_ID(bool_id, "bool"); if (type_id == void_id) { return INT2NUM(TYPE_VOID); } @@ -144,6 +165,9 @@ rb_fiddle_type_ensure(VALUE type) else if (type_id == uintptr_t_id) { return INT2NUM(TYPE_UINTPTR_T); } + else if (type_id == bool_id) { + return rb_fiddle_type_bool(); + } else { type = original_type; } diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h index c7c12a92347d25..5ea569e3ff9851 100644 --- a/ext/fiddle/conversions.h +++ b/ext/fiddle/conversions.h @@ -24,6 +24,7 @@ typedef union void * pointer; /* ffi_type_pointer */ } fiddle_generic; +VALUE rb_fiddle_type_bool(void); 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); diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c index 9ab1283ba3a558..c285bc20de40cd 100644 --- a/ext/fiddle/fiddle.c +++ b/ext/fiddle/fiddle.c @@ -357,6 +357,12 @@ Init_fiddle(void) */ rb_define_const(mFiddleTypes, "UINTPTR_T", INT2NUM(TYPE_UINTPTR_T)); + /* Document-const: Fiddle::Types::BOOL + * + * C type - bool + */ + rb_define_const(mFiddleTypes, "BOOL" , rb_fiddle_type_bool()); + /* Document-const: ALIGN_VOIDP * * The alignment size of a void* @@ -635,6 +641,12 @@ Init_fiddle(void) */ rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*))); + /* Document-const: SIZEOF_BOOL + * + * size of a bool + */ + rb_define_const(mFiddle, "SIZEOF_BOOL", INT2NUM(sizeof(bool))); + /* Document-const: RUBY_FREE * * Address of the ruby_xfree() function diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb index bde50a3f6b80c5..264ca166dddb7a 100644 --- a/ext/fiddle/lib/fiddle/cparser.rb +++ b/ext/fiddle/lib/fiddle/cparser.rb @@ -247,6 +247,8 @@ def parse_ctype(ty, tymap=nil) return TYPE_INTPTR_T when /\Auintptr_t(?:\s+\w+)?\z/ return TYPE_UINTPTR_T + when "bool" + return TYPE_BOOL when /\*/, /\[[\s\d]*\]/ return TYPE_VOIDP when "..." diff --git a/test/fiddle/test_cparser.rb b/test/fiddle/test_cparser.rb index bb4bc0b8e054ff..f1b67476ba8c04 100644 --- a/test/fiddle/test_cparser.rb +++ b/test/fiddle/test_cparser.rb @@ -121,6 +121,10 @@ def test_uintptr_t_ctype assert_equal(TYPE_UINTPTR_T, parse_ctype("const uintptr_t")) end + def test_bool_ctype + assert_equal(TYPE_BOOL, parse_ctype('bool')) + end + def test_undefined_ctype assert_raise(DLError) { parse_ctype('DWORD') } end