summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/fiddle/conversions.c24
-rw-r--r--ext/fiddle/conversions.h1
-rw-r--r--ext/fiddle/fiddle.c12
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb2
-rw-r--r--test/fiddle/test_cparser.rb4
5 files changed, 43 insertions, 0 deletions
diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c
index af18f8b31e..b0dcf84873 100644
--- a/ext/fiddle/conversions.c
+++ b/ext/fiddle/conversions.c
@@ -1,6 +1,25 @@
#include <fiddle.h>
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)
{
VALUE original_type = 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 c7c12a9234..5ea569e3ff 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 9ab1283ba3..c285bc20de 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 bde50a3f6b..264ca166dd 100644
--- a/ext/fiddle/lib/fiddle/cparser.rb
+++ b/ext/fiddle/lib/fiddle/cparser.rb
@@ -247,6 +247,8 @@ module Fiddle
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 bb4bc0b8e0..f1b67476ba 100644
--- a/test/fiddle/test_cparser.rb
+++ b/test/fiddle/test_cparser.rb
@@ -121,6 +121,10 @@ module Fiddle
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