fiddle 1.0.9 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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)