fiddle 1.0.9 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/fiddle/handle.c CHANGED
@@ -50,8 +50,13 @@ fiddle_handle_memsize(const void *ptr)
50
50
  }
51
51
 
52
52
  static const rb_data_type_t fiddle_handle_data_type = {
53
- "fiddle/handle",
54
- {0, fiddle_handle_free, fiddle_handle_memsize,},
53
+ .wrap_struct_name = "fiddle/handle",
54
+ .function = {
55
+ .dmark = 0,
56
+ .dfree = fiddle_handle_free,
57
+ .dsize = fiddle_handle_memsize
58
+ },
59
+ .flags = RUBY_TYPED_WB_PROTECTED,
55
60
  };
56
61
 
57
62
  /*
@@ -259,7 +264,21 @@ rb_fiddle_handle_to_i(VALUE self)
259
264
  struct dl_handle *fiddle_handle;
260
265
 
261
266
  TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
262
- return PTR2NUM(fiddle_handle);
267
+ return PTR2NUM(fiddle_handle->ptr);
268
+ }
269
+
270
+ /*
271
+ * call-seq: to_ptr
272
+ *
273
+ * Returns the Fiddle::Pointer of this handle.
274
+ */
275
+ static VALUE
276
+ rb_fiddle_handle_to_ptr(VALUE self)
277
+ {
278
+ struct dl_handle *fiddle_handle;
279
+
280
+ TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
281
+ return rb_fiddle_ptr_new_wrap(fiddle_handle->ptr, 0, 0, self, 0);
263
282
  }
264
283
 
265
284
  static VALUE fiddle_handle_sym(void *handle, VALUE symbol);
@@ -307,8 +326,10 @@ rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
307
326
  return fiddle_handle_sym(RTLD_NEXT, sym);
308
327
  }
309
328
 
310
- static VALUE
311
- fiddle_handle_sym(void *handle, VALUE symbol)
329
+ typedef void (*fiddle_void_func)(void);
330
+
331
+ static fiddle_void_func
332
+ fiddle_handle_find_func(void *handle, VALUE symbol)
312
333
  {
313
334
  #if defined(HAVE_DLERROR)
314
335
  const char *err;
@@ -316,13 +337,13 @@ fiddle_handle_sym(void *handle, VALUE symbol)
316
337
  #else
317
338
  # define CHECK_DLERROR
318
339
  #endif
319
- void (*func)();
340
+ fiddle_void_func func;
320
341
  const char *name = StringValueCStr(symbol);
321
342
 
322
343
  #ifdef HAVE_DLERROR
323
344
  dlerror();
324
345
  #endif
325
- func = (void (*)())(VALUE)dlsym(handle, name);
346
+ func = (fiddle_void_func)(VALUE)dlsym(handle, name);
326
347
  CHECK_DLERROR;
327
348
  #if defined(FUNC_STDCALL)
328
349
  if( !func ){
@@ -365,6 +386,53 @@ fiddle_handle_sym(void *handle, VALUE symbol)
365
386
  xfree(name_n);
366
387
  }
367
388
  #endif
389
+
390
+ return func;
391
+ }
392
+
393
+ static VALUE
394
+ rb_fiddle_handle_s_sym_defined(VALUE self, VALUE sym)
395
+ {
396
+ fiddle_void_func func;
397
+
398
+ func = fiddle_handle_find_func(RTLD_NEXT, sym);
399
+
400
+ if( func ) {
401
+ return PTR2NUM(func);
402
+ }
403
+ else {
404
+ return Qnil;
405
+ }
406
+ }
407
+
408
+ static VALUE
409
+ rb_fiddle_handle_sym_defined(VALUE self, VALUE sym)
410
+ {
411
+ struct dl_handle *fiddle_handle;
412
+ fiddle_void_func func;
413
+
414
+ TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
415
+ if( ! fiddle_handle->open ){
416
+ rb_raise(rb_eFiddleDLError, "closed handle");
417
+ }
418
+
419
+ func = fiddle_handle_find_func(fiddle_handle->ptr, sym);
420
+
421
+ if( func ) {
422
+ return PTR2NUM(func);
423
+ }
424
+ else {
425
+ return Qnil;
426
+ }
427
+ }
428
+
429
+ static VALUE
430
+ fiddle_handle_sym(void *handle, VALUE symbol)
431
+ {
432
+ fiddle_void_func func;
433
+
434
+ func = fiddle_handle_find_func(handle, symbol);
435
+
368
436
  if( !func ){
369
437
  rb_raise(rb_eFiddleDLError, "unknown symbol \"%"PRIsVALUE"\"", symbol);
370
438
  }
@@ -372,6 +440,48 @@ fiddle_handle_sym(void *handle, VALUE symbol)
372
440
  return PTR2NUM(func);
373
441
  }
374
442
 
443
+ /*
444
+ * call-seq: file_name
445
+ *
446
+ * Returns the file name of this handle.
447
+ */
448
+ static VALUE
449
+ rb_fiddle_handle_file_name(VALUE self)
450
+ {
451
+ struct dl_handle *fiddle_handle;
452
+
453
+ TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
454
+
455
+ #if defined(HAVE_DLINFO) && defined(HAVE_CONST_RTLD_DI_LINKMAP)
456
+ {
457
+ struct link_map *lm = NULL;
458
+ int res = dlinfo(fiddle_handle->ptr, RTLD_DI_LINKMAP, &lm);
459
+ if (res == 0 && lm != NULL) {
460
+ return rb_str_new_cstr(lm->l_name);
461
+ }
462
+ else {
463
+ #if defined(HAVE_DLERROR)
464
+ rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
465
+ #else
466
+ rb_raise(rb_eFiddleDLError, "could not get handle file name");
467
+ #endif
468
+ }
469
+ }
470
+ #elif defined(HAVE_GETMODULEFILENAME)
471
+ {
472
+ char filename[MAX_PATH];
473
+ DWORD res = GetModuleFileName(fiddle_handle->ptr, filename, MAX_PATH);
474
+ if (res == 0) {
475
+ rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
476
+ }
477
+ return rb_str_new_cstr(filename);
478
+ }
479
+ #else
480
+ (void)fiddle_handle;
481
+ return Qnil;
482
+ #endif
483
+ }
484
+
375
485
  void
376
486
  Init_fiddle_handle(void)
377
487
  {
@@ -412,6 +522,7 @@ Init_fiddle_handle(void)
412
522
  rb_cHandle = rb_define_class_under(mFiddle, "Handle", rb_cObject);
413
523
  rb_define_alloc_func(rb_cHandle, rb_fiddle_handle_s_allocate);
414
524
  rb_define_singleton_method(rb_cHandle, "sym", rb_fiddle_handle_s_sym, 1);
525
+ rb_define_singleton_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_s_sym_defined, 1);
415
526
  rb_define_singleton_method(rb_cHandle, "[]", rb_fiddle_handle_s_sym, 1);
416
527
 
417
528
  /* Document-const: NEXT
@@ -466,9 +577,12 @@ Init_fiddle_handle(void)
466
577
 
467
578
  rb_define_method(rb_cHandle, "initialize", rb_fiddle_handle_initialize, -1);
468
579
  rb_define_method(rb_cHandle, "to_i", rb_fiddle_handle_to_i, 0);
580
+ rb_define_method(rb_cHandle, "to_ptr", rb_fiddle_handle_to_ptr, 0);
469
581
  rb_define_method(rb_cHandle, "close", rb_fiddle_handle_close, 0);
470
582
  rb_define_method(rb_cHandle, "sym", rb_fiddle_handle_sym, 1);
471
583
  rb_define_method(rb_cHandle, "[]", rb_fiddle_handle_sym, 1);
584
+ rb_define_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_sym_defined, 1);
585
+ rb_define_method(rb_cHandle, "file_name", rb_fiddle_handle_file_name, 0);
472
586
  rb_define_method(rb_cHandle, "disable_close", rb_fiddle_handle_disable_close, 0);
473
587
  rb_define_method(rb_cHandle, "enable_close", rb_fiddle_handle_enable_close, 0);
474
588
  rb_define_method(rb_cHandle, "close_enabled?", rb_fiddle_handle_close_enabled_p, 0);
@@ -1,10 +1,11 @@
1
+ #include <fiddle.h>
2
+
3
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
4
+
1
5
  #include <stdbool.h>
2
6
  #include <ruby/ruby.h>
3
7
  #include <ruby/encoding.h>
4
-
5
- #ifdef HAVE_RUBY_MEMORY_VIEW_H
6
- # include <ruby/memory_view.h>
7
- #endif
8
+ #include <ruby/memory_view.h>
8
9
 
9
10
  #if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
10
11
  # define INTPTR2NUM LL2NUM
@@ -17,9 +18,6 @@
17
18
  # define UINTPTR2NUM UINT2NUM
18
19
  #endif
19
20
 
20
- #include <fiddle.h>
21
-
22
- #ifdef FIDDLE_MEMORY_VIEW
23
21
  VALUE rb_cMemoryView = Qnil;
24
22
 
25
23
  struct memview_data {
@@ -320,4 +318,4 @@ Init_fiddle_memory_view(void)
320
318
  rb_define_method(rb_cMemoryView, "to_s", rb_fiddle_memview_to_s, 0);
321
319
  }
322
320
 
323
- #endif /* FIDDLE_MEMORY_VIEW */
321
+ #endif /* HAVE_RUBY_MEMORY_VIEW_H */
data/ext/fiddle/pointer.c CHANGED
@@ -6,13 +6,13 @@
6
6
  #include <ruby/ruby.h>
7
7
  #include <ruby/io.h>
8
8
 
9
+ #include <ctype.h>
10
+ #include <fiddle.h>
11
+
9
12
  #ifdef HAVE_RUBY_MEMORY_VIEW_H
10
13
  # include <ruby/memory_view.h>
11
14
  #endif
12
15
 
13
- #include <ctype.h>
14
- #include <fiddle.h>
15
-
16
16
  #ifdef PRIsVALUE
17
17
  # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
18
18
  # define RB_OBJ_STRING(obj) (obj)
@@ -24,7 +24,7 @@
24
24
 
25
25
  VALUE rb_cPointer;
26
26
 
27
- typedef void (*freefunc_t)(void*);
27
+ typedef rb_fiddle_freefunc_t freefunc_t;
28
28
 
29
29
  struct ptr_data {
30
30
  void *ptr;
@@ -88,11 +88,16 @@ fiddle_ptr_memsize(const void *ptr)
88
88
  }
89
89
 
90
90
  static const rb_data_type_t fiddle_ptr_data_type = {
91
- "fiddle/pointer",
92
- {fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,},
91
+ .wrap_struct_name = "fiddle/pointer",
92
+ .function = {
93
+ .dmark = fiddle_ptr_mark,
94
+ .dfree = fiddle_ptr_free,
95
+ .dsize = fiddle_ptr_memsize,
96
+ },
97
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
93
98
  };
94
99
 
95
- #ifdef FIDDLE_MEMORY_VIEW
100
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
96
101
  static struct ptr_data *
97
102
  fiddle_ptr_check_memory_view(VALUE obj)
98
103
  {
@@ -125,7 +130,7 @@ static const rb_memory_view_entry_t fiddle_ptr_memory_view_entry = {
125
130
  #endif
126
131
 
127
132
  static VALUE
128
- rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
133
+ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1)
129
134
  {
130
135
  struct ptr_data *data;
131
136
  VALUE val;
@@ -135,14 +140,22 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
135
140
  data->free = func;
136
141
  data->freed = false;
137
142
  data->size = size;
143
+ RB_OBJ_WRITE(val, &data->wrap[0], wrap0);
144
+ RB_OBJ_WRITE(val, &data->wrap[1], wrap1);
138
145
 
139
146
  return val;
140
147
  }
141
148
 
149
+ VALUE
150
+ rb_fiddle_ptr_new_wrap(void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1)
151
+ {
152
+ return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, wrap0, wrap1);
153
+ }
154
+
142
155
  static VALUE
143
156
  rb_fiddle_ptr_new(void *ptr, long size, freefunc_t func)
144
157
  {
145
- return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func);
158
+ return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, 0, 0);
146
159
  }
147
160
 
148
161
  static VALUE
@@ -152,7 +165,7 @@ rb_fiddle_ptr_malloc(VALUE klass, long size, freefunc_t func)
152
165
 
153
166
  ptr = ruby_xmalloc((size_t)size);
154
167
  memset(ptr,0,(size_t)size);
155
- return rb_fiddle_ptr_new2(klass, ptr, size, func);
168
+ return rb_fiddle_ptr_new2(klass, ptr, size, func, 0, 0);
156
169
  }
157
170
 
158
171
  static void *
@@ -227,8 +240,8 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
227
240
  /* Free previous memory. Use of inappropriate initialize may cause SEGV. */
228
241
  (*(data->free))(data->ptr);
229
242
  }
230
- data->wrap[0] = wrap;
231
- data->wrap[1] = funcwrap;
243
+ RB_OBJ_WRITE(self, &data->wrap[0], wrap);
244
+ RB_OBJ_WRITE(self, &data->wrap[1], funcwrap);
232
245
  data->ptr = p;
233
246
  data->size = s;
234
247
  data->free = f;
@@ -306,7 +319,7 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
306
319
  }
307
320
 
308
321
  obj = rb_fiddle_ptr_malloc(klass, s,f);
309
- if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
322
+ if (wrap) RB_OBJ_WRITE(obj, &RPTR_DATA(obj)->wrap[1], wrap);
310
323
 
311
324
  if (rb_block_given_p()) {
312
325
  if (!f) {
@@ -787,10 +800,37 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
787
800
  if (num == val) wrap = 0;
788
801
  ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
789
802
  }
790
- if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
803
+ if (wrap) RB_OBJ_WRITE(ptr, &RPTR_DATA(ptr)->wrap[0], wrap);
791
804
  return ptr;
792
805
  }
793
806
 
807
+ /*
808
+ * call-seq:
809
+ * Fiddle::Pointer.read(address, len) => string
810
+ *
811
+ * Or read the memory at address +address+ with length +len+ and return a
812
+ * string with that memory
813
+ */
814
+
815
+ static VALUE
816
+ rb_fiddle_ptr_read_mem(VALUE klass, VALUE address, VALUE len)
817
+ {
818
+ return rb_str_new((char *)NUM2PTR(address), NUM2ULONG(len));
819
+ }
820
+
821
+ /*
822
+ * call-seq:
823
+ * Fiddle::Pointer.write(address, str)
824
+ *
825
+ * Write bytes in +str+ to the location pointed to by +address+.
826
+ */
827
+ static VALUE
828
+ rb_fiddle_ptr_write_mem(VALUE klass, VALUE addr, VALUE str)
829
+ {
830
+ memcpy(NUM2PTR(addr), StringValuePtr(str), RSTRING_LEN(str));
831
+ return str;
832
+ }
833
+
794
834
  void
795
835
  Init_fiddle_pointer(void)
796
836
  {
@@ -807,6 +847,8 @@ Init_fiddle_pointer(void)
807
847
  rb_define_singleton_method(rb_cPointer, "malloc", rb_fiddle_ptr_s_malloc, -1);
808
848
  rb_define_singleton_method(rb_cPointer, "to_ptr", rb_fiddle_ptr_s_to_ptr, 1);
809
849
  rb_define_singleton_method(rb_cPointer, "[]", rb_fiddle_ptr_s_to_ptr, 1);
850
+ rb_define_singleton_method(rb_cPointer, "read", rb_fiddle_ptr_read_mem, 2);
851
+ rb_define_singleton_method(rb_cPointer, "write", rb_fiddle_ptr_write_mem, 2);
810
852
  rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1);
811
853
  rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1);
812
854
  rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0);
@@ -833,7 +875,7 @@ Init_fiddle_pointer(void)
833
875
  rb_define_method(rb_cPointer, "size", rb_fiddle_ptr_size_get, 0);
834
876
  rb_define_method(rb_cPointer, "size=", rb_fiddle_ptr_size_set, 1);
835
877
 
836
- #ifdef FIDDLE_MEMORY_VIEW
878
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
837
879
  rb_memory_view_register(rb_cPointer, &fiddle_ptr_memory_view_entry);
838
880
  #endif
839
881
 
@@ -23,7 +23,7 @@ until ARGV.empty?
23
23
  end
24
24
  end
25
25
 
26
- IO.foreach("#{srcdir}/configure.ac") do |line|
26
+ File.foreach("#{srcdir}/configure.ac") do |line|
27
27
  if /^AC_INIT\((.*)\)/ =~ line
28
28
  version = $1.split(/,\s*/)[1]
29
29
  version.gsub!(/\A\[|\]\z/, '')
@@ -38,11 +38,11 @@ conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32"
38
38
  FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"])
39
39
  FileUtils.cp("#{basedir}/fficonfig.h", ".", preserve: true)
40
40
 
41
- hdr = IO.binread("#{srcdir}/include/ffi.h.in")
41
+ hdr = File.binread("#{srcdir}/include/ffi.h.in")
42
42
  hdr.gsub!(/@(\w+)@/) {conf[$1] || $&}
43
43
  hdr.gsub!(/^(#if\s+)@\w+@/, '\10')
44
- IO.binwrite("#{builddir}/include/ffi.h", hdr)
44
+ File.binwrite("#{builddir}/include/ffi.h", hdr)
45
45
 
46
- mk = IO.binread("#{basedir}/libffi.mk.tmpl")
46
+ mk = File.binread("#{basedir}/libffi.mk.tmpl")
47
47
  mk.gsub!(/@(\w+)@/) {conf[$1] || $&}
48
- IO.binwrite("Makefile", mk)
48
+ File.binwrite("Makefile", mk)
data/fiddle.gemspec CHANGED
@@ -20,15 +20,12 @@ Gem::Specification.new do |spec|
20
20
  "LICENSE.txt",
21
21
  "README.md",
22
22
  "Rakefile",
23
- "bin/downloader.rb",
24
- "bin/extlibs.rb",
25
23
  "ext/fiddle/closure.c",
26
24
  "ext/fiddle/closure.h",
27
25
  "ext/fiddle/conversions.c",
28
26
  "ext/fiddle/conversions.h",
29
27
  "ext/fiddle/depend",
30
28
  "ext/fiddle/extconf.rb",
31
- "ext/fiddle/extlibs",
32
29
  "ext/fiddle/fiddle.c",
33
30
  "ext/fiddle/fiddle.h",
34
31
  "ext/fiddle/function.c",
@@ -56,11 +53,7 @@ Gem::Specification.new do |spec|
56
53
  spec.require_paths = ["lib"]
57
54
  spec.extensions = ["ext/fiddle/extconf.rb"]
58
55
 
59
- spec.required_ruby_version = ">= 2.3.0"
60
-
61
- spec.add_development_dependency "bundler"
62
- spec.add_development_dependency "rake"
63
- spec.add_development_dependency "rake-compiler"
56
+ spec.required_ruby_version = ">= 2.5.0"
64
57
 
65
58
  spec.metadata["msys2_mingw_dependencies"] = "libffi"
66
59
  end
@@ -1,6 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
  module Fiddle
3
3
  class Closure
4
+ class << self
5
+ # Create a new closure. If a block is given, the created closure
6
+ # is automatically freed after the given block is executed.
7
+ #
8
+ # The all given arguments are passed to Fiddle::Closure.new. So
9
+ # using this method without block equals to Fiddle::Closure.new.
10
+ #
11
+ # == Example
12
+ #
13
+ # Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure|
14
+ # # closure is freed automatically when this block is finished.
15
+ # end
16
+ def create(*args)
17
+ if block_given?
18
+ closure = new(*args)
19
+ begin
20
+ yield(closure)
21
+ ensure
22
+ closure.free
23
+ end
24
+ else
25
+ new(*args)
26
+ end
27
+ end
28
+ end
4
29
 
5
30
  # the C type of the return of the FFI closure
6
31
  attr_reader :ctype
@@ -164,23 +164,35 @@ module Fiddle
164
164
  unless Fiddle.const_defined?(:TYPE_LONG_LONG)
165
165
  raise(RuntimeError, "unsupported type: #{ty}")
166
166
  end
167
- return -TYPE_LONG_LONG
168
- when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/
167
+ return TYPE_ULONG_LONG
168
+ when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/,
169
+ /\Aunsigned\s+int\s+long(?:\s+\w+)?\z/,
170
+ /\Along(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
171
+ /\Aint\s+unsigned\s+long(?:\s+\w+)?\z/,
172
+ /\A(?:int\s+)?long\s+unsigned(?:\s+\w+)?\z/
173
+ return TYPE_ULONG
174
+ when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/,
175
+ /\A(?:signed\s+)?int\s+long(?:\s+\w+)?\z/,
176
+ /\Along(?:\s+int)?\s+signed(?:\s+\w+)?\z/
169
177
  return TYPE_LONG
170
- when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/
171
- return -TYPE_LONG
178
+ when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/,
179
+ /\Aunsigned\s+int\s+short(?:\s+\w+)?\z/,
180
+ /\Ashort(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
181
+ /\Aint\s+unsigned\s+short(?:\s+\w+)?\z/,
182
+ /\A(?:int\s+)?short\s+unsigned(?:\s+\w+)?\z/
183
+ return TYPE_USHORT
184
+ when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/,
185
+ /\A(?:signed\s+)?int\s+short(?:\s+\w+)?\z/,
186
+ /\Aint\s+(?:signed\s+)?short(?:\s+\w+)?\z/
187
+ return TYPE_SHORT
172
188
  when /\A(?:signed\s+)?int(?:\s+\w+)?\z/
173
189
  return TYPE_INT
174
190
  when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/
175
- return -TYPE_INT
176
- when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/
177
- return TYPE_SHORT
178
- when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/
179
- return -TYPE_SHORT
191
+ return TYPE_UINT
180
192
  when /\A(?:signed\s+)?char(?:\s+\w+)?\z/
181
193
  return TYPE_CHAR
182
194
  when /\Aunsigned\s+char(?:\s+\w+)?\z/
183
- return -TYPE_CHAR
195
+ return TYPE_UCHAR
184
196
  when /\Aint8_t(?:\s+\w+)?\z/
185
197
  unless Fiddle.const_defined?(:TYPE_INT8_T)
186
198
  raise(RuntimeError, "unsupported type: #{ty}")
@@ -190,7 +202,7 @@ module Fiddle
190
202
  unless Fiddle.const_defined?(:TYPE_INT8_T)
191
203
  raise(RuntimeError, "unsupported type: #{ty}")
192
204
  end
193
- return -TYPE_INT8_T
205
+ return TYPE_UINT8_T
194
206
  when /\Aint16_t(?:\s+\w+)?\z/
195
207
  unless Fiddle.const_defined?(:TYPE_INT16_T)
196
208
  raise(RuntimeError, "unsupported type: #{ty}")
@@ -200,7 +212,7 @@ module Fiddle
200
212
  unless Fiddle.const_defined?(:TYPE_INT16_T)
201
213
  raise(RuntimeError, "unsupported type: #{ty}")
202
214
  end
203
- return -TYPE_INT16_T
215
+ return TYPE_UINT16_T
204
216
  when /\Aint32_t(?:\s+\w+)?\z/
205
217
  unless Fiddle.const_defined?(:TYPE_INT32_T)
206
218
  raise(RuntimeError, "unsupported type: #{ty}")
@@ -210,7 +222,7 @@ module Fiddle
210
222
  unless Fiddle.const_defined?(:TYPE_INT32_T)
211
223
  raise(RuntimeError, "unsupported type: #{ty}")
212
224
  end
213
- return -TYPE_INT32_T
225
+ return TYPE_UINT32_T
214
226
  when /\Aint64_t(?:\s+\w+)?\z/
215
227
  unless Fiddle.const_defined?(:TYPE_INT64_T)
216
228
  raise(RuntimeError, "unsupported type: #{ty}")
@@ -220,7 +232,7 @@ module Fiddle
220
232
  unless Fiddle.const_defined?(:TYPE_INT64_T)
221
233
  raise(RuntimeError, "unsupported type: #{ty}")
222
234
  end
223
- return -TYPE_INT64_T
235
+ return TYPE_UINT64_T
224
236
  when /\Afloat(?:\s+\w+)?\z/
225
237
  return TYPE_FLOAT
226
238
  when /\Adouble(?:\s+\w+)?\z/
@@ -235,6 +247,8 @@ module Fiddle
235
247
  return TYPE_INTPTR_T
236
248
  when /\Auintptr_t(?:\s+\w+)?\z/
237
249
  return TYPE_UINTPTR_T
250
+ when "bool"
251
+ return TYPE_BOOL
238
252
  when /\*/, /\[[\s\d]*\]/
239
253
  return TYPE_VOIDP
240
254
  when "..."
data/lib/fiddle/import.rb CHANGED
@@ -119,6 +119,8 @@ module Fiddle
119
119
  return SIZEOF_VOIDP
120
120
  when TYPE_CONST_STRING
121
121
  return SIZEOF_CONST_STRING
122
+ when TYPE_BOOL
123
+ return SIZEOF_BOOL
122
124
  else
123
125
  if defined?(TYPE_LONG_LONG) and
124
126
  ty == TYPE_LONG_LONG
data/lib/fiddle/pack.rb CHANGED
@@ -11,25 +11,36 @@ module Fiddle
11
11
  TYPE_LONG => ALIGN_LONG,
12
12
  TYPE_FLOAT => ALIGN_FLOAT,
13
13
  TYPE_DOUBLE => ALIGN_DOUBLE,
14
- -TYPE_CHAR => ALIGN_CHAR,
15
- -TYPE_SHORT => ALIGN_SHORT,
16
- -TYPE_INT => ALIGN_INT,
17
- -TYPE_LONG => ALIGN_LONG,
14
+ TYPE_UCHAR => ALIGN_CHAR,
15
+ TYPE_USHORT => ALIGN_SHORT,
16
+ TYPE_UINT => ALIGN_INT,
17
+ TYPE_ULONG => ALIGN_LONG,
18
+ TYPE_BOOL => ALIGN_BOOL,
18
19
  }
19
20
 
20
21
  PACK_MAP = {
21
- TYPE_VOIDP => "l!",
22
+ TYPE_VOIDP => "L!",
22
23
  TYPE_CHAR => "c",
23
24
  TYPE_SHORT => "s!",
24
25
  TYPE_INT => "i!",
25
26
  TYPE_LONG => "l!",
26
27
  TYPE_FLOAT => "f",
27
28
  TYPE_DOUBLE => "d",
28
- -TYPE_CHAR => "c",
29
- -TYPE_SHORT => "s!",
30
- -TYPE_INT => "i!",
31
- -TYPE_LONG => "l!",
29
+ TYPE_UCHAR => "C",
30
+ TYPE_USHORT => "S!",
31
+ TYPE_UINT => "I!",
32
+ TYPE_ULONG => "L!",
32
33
  }
34
+ case SIZEOF_BOOL
35
+ when SIZEOF_CHAR
36
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UCHAR]
37
+ when SIZEOF_SHORT
38
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_USHORT]
39
+ when SIZEOF_INT
40
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UINT]
41
+ when SIZEOF_LONG
42
+ PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_ULONG]
43
+ end
33
44
 
34
45
  SIZE_MAP = {
35
46
  TYPE_VOIDP => SIZEOF_VOIDP,
@@ -39,16 +50,18 @@ module Fiddle
39
50
  TYPE_LONG => SIZEOF_LONG,
40
51
  TYPE_FLOAT => SIZEOF_FLOAT,
41
52
  TYPE_DOUBLE => SIZEOF_DOUBLE,
42
- -TYPE_CHAR => SIZEOF_CHAR,
43
- -TYPE_SHORT => SIZEOF_SHORT,
44
- -TYPE_INT => SIZEOF_INT,
45
- -TYPE_LONG => SIZEOF_LONG,
53
+ TYPE_UCHAR => SIZEOF_CHAR,
54
+ TYPE_USHORT => SIZEOF_SHORT,
55
+ TYPE_UINT => SIZEOF_INT,
56
+ TYPE_ULONG => SIZEOF_LONG,
57
+ TYPE_BOOL => SIZEOF_BOOL,
46
58
  }
47
59
  if defined?(TYPE_LONG_LONG)
48
- ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[-TYPE_LONG_LONG] = ALIGN_LONG_LONG
49
- PACK_MAP[TYPE_LONG_LONG] = PACK_MAP[-TYPE_LONG_LONG] = "q"
50
- SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[-TYPE_LONG_LONG] = SIZEOF_LONG_LONG
51
- PACK_MAP[TYPE_VOIDP] = "q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
60
+ ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[TYPE_ULONG_LONG] = ALIGN_LONG_LONG
61
+ PACK_MAP[TYPE_LONG_LONG] = "q"
62
+ PACK_MAP[TYPE_ULONG_LONG] = "Q"
63
+ SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[TYPE_ULONG_LONG] = SIZEOF_LONG_LONG
64
+ PACK_MAP[TYPE_VOIDP] = "Q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
52
65
  end
53
66
 
54
67
  def align(addr, align)