ffi 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

data/Rakefile CHANGED
@@ -75,7 +75,7 @@ PROJ.name = 'ffi'
75
75
  PROJ.authors = 'Wayne Meissner'
76
76
  PROJ.email = 'wmeissner@gmail.com'
77
77
  PROJ.url = 'http://wiki.github.com/ffi/ffi'
78
- PROJ.version = '0.6.2'
78
+ PROJ.version = '0.6.3'
79
79
  PROJ.rubyforge.name = 'ffi'
80
80
  PROJ.readme_file = 'README.rdoc'
81
81
 
@@ -147,6 +147,7 @@ task :distclean => :clobber do
147
147
  FileUtils.rm_rf(Dir["lib/**/ffi_c.#{Config::CONFIG['DLEXT']}"])
148
148
  FileUtils.rm_rf('lib/1.8')
149
149
  FileUtils.rm_rf('lib/1.9')
150
+ FileUtils.rm_rf('lib/ffi/types.conf')
150
151
  FileUtils.rm_rf('conftest.dSYM')
151
152
  FileUtils.rm_rf('pkg')
152
153
  end
@@ -142,10 +142,10 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, NativeType* paramTy
142
142
 
143
143
  case NATIVE_BOOL:
144
144
  if (type != T_TRUE && type != T_FALSE) {
145
- rb_raise(rb_eTypeError, "Expected a Boolean parameter");
145
+ rb_raise(rb_eTypeError, "wrong argument type (expected a boolean parameter)");
146
146
  }
147
- param->s32 = argv[argidx++] == Qtrue;
148
- ADJ(param, INT32);
147
+ param->s8 = argv[argidx++] == Qtrue;
148
+ ADJ(param, INT8);
149
149
  break;
150
150
 
151
151
 
@@ -374,7 +374,7 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
374
374
  param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
375
375
  break;
376
376
  case NATIVE_BOOL:
377
- param = (*(void **) parameters[i]) ? Qtrue : Qfalse;
377
+ param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse;
378
378
  break;
379
379
 
380
380
  case NATIVE_FUNCTION:
@@ -428,8 +428,9 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
428
428
  *((void **) retval) = NULL;
429
429
  }
430
430
  break;
431
+
431
432
  case NATIVE_BOOL:
432
- *((ffi_sarg *) retval) = TYPE(rbReturnValue) == T_TRUE ? 1 : 0;
433
+ *((ffi_arg *) retval) = rbReturnValue == Qtrue;
433
434
  break;
434
435
 
435
436
  case NATIVE_FUNCTION:
@@ -71,6 +71,8 @@ typedef struct InlineArray_ {
71
71
  static void struct_mark(Struct *);
72
72
  static void struct_layout_builder_mark(StructLayoutBuilder *);
73
73
  static void struct_layout_builder_free(StructLayoutBuilder *);
74
+ static VALUE struct_class_layout(VALUE klass);
75
+ static void struct_malloc(Struct* s);
74
76
  static void inline_array_mark(InlineArray *);
75
77
 
76
78
  static inline int align(int offset, int align);
@@ -116,10 +118,8 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
116
118
  /* Call up into ruby code to adjust the layout */
117
119
  if (nargs > 1) {
118
120
  s->rbLayout = rb_funcall2(CLASS_OF(self), id_layout, RARRAY_LEN(rest), RARRAY_PTR(rest));
119
- } else if (rb_cvar_defined(klass, id_layout_ivar)) {
120
- s->rbLayout = rb_cvar_get(klass, id_layout_ivar);
121
121
  } else {
122
- rb_raise(rb_eRuntimeError, "No Struct layout configured");
122
+ s->rbLayout = struct_class_layout(klass);
123
123
  }
124
124
 
125
125
  if (!rb_obj_is_kind_of(s->rbLayout, rbffi_StructLayoutClass)) {
@@ -132,13 +132,74 @@ struct_initialize(int argc, VALUE* argv, VALUE self)
132
132
  s->pointer = MEMORY(rbPointer);
133
133
  s->rbPointer = rbPointer;
134
134
  } else {
135
- s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);
136
- s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
135
+ struct_malloc(s);
137
136
  }
138
137
 
139
138
  return self;
140
139
  }
141
140
 
141
+ static VALUE
142
+ struct_class_layout(VALUE klass)
143
+ {
144
+ VALUE layout;
145
+ if (!rb_cvar_defined(klass, id_layout_ivar)) {
146
+ rb_raise(rb_eRuntimeError, "no Struct layout configured for %s", rb_class2name(klass));
147
+ }
148
+
149
+ layout = rb_cvar_get(klass, id_layout_ivar);
150
+ if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
151
+ rb_raise(rb_eRuntimeError, "invalid Struct layout for %s", rb_class2name(klass));
152
+ }
153
+
154
+ return layout;
155
+ }
156
+
157
+ static StructLayout*
158
+ struct_layout(VALUE self)
159
+ {
160
+ Struct* s = (Struct *) DATA_PTR(self);
161
+ if (s->layout != NULL) {
162
+ return s->layout;
163
+ }
164
+
165
+ if (s->layout == NULL) {
166
+ s->rbLayout = struct_class_layout(CLASS_OF(self));
167
+ Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
168
+ }
169
+
170
+ return s->layout;
171
+ }
172
+
173
+ static Struct*
174
+ struct_validate(VALUE self)
175
+ {
176
+ Struct* s;
177
+ Data_Get_Struct(self, Struct, s);
178
+
179
+ if (struct_layout(self) == NULL) {
180
+ rb_raise(rb_eRuntimeError, "struct layout == null");
181
+ }
182
+
183
+ if (s->pointer == NULL) {
184
+ struct_malloc(s);
185
+ }
186
+
187
+ return s;
188
+ }
189
+
190
+ static void
191
+ struct_malloc(Struct* s)
192
+ {
193
+ if (s->rbPointer == Qnil) {
194
+ s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);
195
+
196
+ } else if (!rb_obj_is_kind_of(s->rbPointer, rbffi_AbstractMemoryClass)) {
197
+ rb_raise(rb_eRuntimeError, "invalid pointer in struct");
198
+ }
199
+
200
+ s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
201
+ }
202
+
142
203
  static void
143
204
  struct_mark(Struct *s)
144
205
  {
@@ -151,9 +212,6 @@ struct_field(Struct* s, VALUE fieldName)
151
212
  {
152
213
  StructLayout* layout = s->layout;
153
214
  VALUE rbField;
154
- if (layout == NULL) {
155
- rb_raise(rb_eRuntimeError, "layout not set for Struct");
156
- }
157
215
 
158
216
  rbField = rb_hash_aref(layout->rbFieldMap, fieldName);
159
217
  if (rbField == Qnil) {
@@ -170,8 +228,9 @@ struct_aref(VALUE self, VALUE fieldName)
170
228
  Struct* s;
171
229
  VALUE rbField;
172
230
  StructField* f;
173
-
174
- Data_Get_Struct(self, Struct, s);
231
+
232
+ s = struct_validate(self);
233
+
175
234
  rbField = struct_field(s, fieldName);
176
235
  f = (StructField *) DATA_PTR(rbField);
177
236
 
@@ -196,7 +255,8 @@ struct_aset(VALUE self, VALUE fieldName, VALUE value)
196
255
  StructField* f;
197
256
 
198
257
 
199
- Data_Get_Struct(self, Struct, s);
258
+ s = struct_validate(self);
259
+
200
260
  rbField = struct_field(s, fieldName);
201
261
  f = (StructField *) DATA_PTR(rbField);
202
262
  if (f->put != NULL) {
@@ -221,12 +281,25 @@ static VALUE
221
281
  struct_set_pointer(VALUE self, VALUE pointer)
222
282
  {
223
283
  Struct* s;
284
+ StructLayout* layout;
285
+ AbstractMemory* memory;
224
286
 
225
287
  if (!rb_obj_is_kind_of(pointer, rbffi_AbstractMemoryClass)) {
226
- rb_raise(rb_eArgError, "Invalid pointer");
288
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Pointer or Buffer)",
289
+ rb_obj_classname(pointer));
290
+ return Qnil;
227
291
  }
228
292
 
293
+
229
294
  Data_Get_Struct(self, Struct, s);
295
+ Data_Get_Struct(pointer, AbstractMemory, memory);
296
+ layout = struct_layout(self);
297
+
298
+ if (layout->base.ffiType->size > memory->size) {
299
+ rb_raise(rb_eArgError, "memory of %d bytes too small for struct %s (expected at least %d)",
300
+ memory->size, rb_obj_classname(self), layout->base.ffiType->size);
301
+ }
302
+
230
303
  s->pointer = MEMORY(pointer);
231
304
  s->rbPointer = pointer;
232
305
  rb_ivar_set(self, id_pointer_ivar, pointer);
@@ -251,7 +324,9 @@ struct_set_layout(VALUE self, VALUE layout)
251
324
  Data_Get_Struct(self, Struct, s);
252
325
 
253
326
  if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
254
- rb_raise(rb_eArgError, "Invalid Struct layout");
327
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
328
+ rb_obj_classname(layout), rb_class2name(rbffi_StructLayoutClass));
329
+ return Qnil;
255
330
  }
256
331
 
257
332
  Data_Get_Struct(layout, StructLayout, s->layout);
@@ -76,7 +76,7 @@ rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr, VALUE enums)
76
76
  case NATIVE_POINTER:
77
77
  return rbffi_Pointer_NewInstance(*(void **) ptr);
78
78
  case NATIVE_BOOL:
79
- return ((int) *(ffi_arg *) ptr) ? Qtrue : Qfalse;
79
+ return ((unsigned char) *(ffi_arg *) ptr) ? Qtrue : Qfalse;
80
80
  case NATIVE_ENUM:
81
81
  return rb_funcall(rbType, id_find, 1, INT2NUM((unsigned int) *(ffi_arg *) ptr));
82
82
 
@@ -7,7 +7,7 @@ $(LIBFFI):
7
7
  @if [ ! -f $(LIBFFI_BUILD_DIR)/Makefile ]; then \
8
8
  echo "Configuring libffi"; \
9
9
  cd $(LIBFFI_BUILD_DIR) && \
10
- /usr/bin/env CC="$(CC)" LD="$(LD)" CFLAGS="$(LIBFFI_CFLAGS)" \
10
+ /usr/bin/env CFLAGS="$(LIBFFI_CFLAGS)" \
11
11
  /bin/sh $(LIBFFI_CONFIGURE) $(LIBFFI_HOST) > /dev/null; \
12
12
  fi
13
13
  cd $(LIBFFI_BUILD_DIR) && $(MAKE)
@@ -9021,7 +9021,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
9021
9021
  old_archive_from_new_cmds='true'
9022
9022
  # FIXME: Should let the user specify the lib program.
9023
9023
  old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
9024
- fix_srcfile_path='`cygpath -w "$srcfile"`'
9024
+ # fix_srcfile_path='`cygpath -w "$srcfile"`'
9025
9025
  enable_shared_with_static_runtimes=yes
9026
9026
  ;;
9027
9027
 
@@ -1,6 +1,7 @@
1
1
  require 'fileutils'
2
- require "#{File.join(ENV['RUBYLIBDIR'], 'ffi', 'tools', 'types_generator.rb')}"
3
- types_conf = File.join(ENV['RUBYLIBDIR'], 'ffi', 'types.conf')
2
+ require "#{File.join(File.dirname(__FILE__), '..', 'lib', 'ffi', 'tools', 'types_generator.rb')}"
3
+ types_conf = File.join(File.dirname(__FILE__), '..', 'lib', 'ffi', 'types.conf')
4
+
4
5
  file types_conf do |task|
5
6
  options = {}
6
7
  FileUtils.mkdir_p(File.dirname(task.name), { :mode => 0755 })
@@ -8,5 +9,6 @@ file types_conf do |task|
8
9
  f.puts FFI::TypesGenerator.generate(options)
9
10
  end
10
11
  end
12
+
11
13
  task :default => types_conf do
12
14
  end
@@ -57,6 +57,7 @@ module FFI
57
57
 
58
58
  def self.map_library_name(lib)
59
59
  # Mangle the library name to reflect the native library naming conventions
60
+ lib = lib.to_s unless lib.kind_of?(String)
60
61
  lib = Platform::LIBC if Platform::IS_LINUX && lib == 'c'
61
62
  if lib && File.basename(lib) == lib
62
63
  ext = ".#{Platform::LIBSUFFIX}"
@@ -42,7 +42,7 @@ module FFI
42
42
 
43
43
  ffi_libs = names.map do |name|
44
44
  if name == FFI::CURRENT_PROCESS
45
- FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
45
+ FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
46
46
  else
47
47
  libnames = (name.is_a?(::Array) ? name : [ name ]).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact
48
48
  lib = nil
@@ -50,7 +50,7 @@ module FFI
50
50
 
51
51
  libnames.each do |libname|
52
52
  begin
53
- lib = FFI::DynamicLibrary.open(libname, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
53
+ lib = FFI::DynamicLibrary.open(libname, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
54
54
  break if lib
55
55
  rescue Exception => ex
56
56
  errors[libname] = ex
@@ -133,6 +133,24 @@ describe "Struct tests" do
133
133
  mp.get_int64(ll_off).should == 0xfee1deadbeef
134
134
  end
135
135
  end
136
+
137
+ it "subclass overrides initialize without calling super" do
138
+ class InitializeWithoutSuper < FFI::Struct
139
+ layout :a, :int, :b, :long_long, :d, [:double, 2]
140
+
141
+ def initialize(a, b)
142
+ self[:a] = a
143
+ self[:b] = b
144
+ self[:d][0] = 1.2
145
+ self[:d][1] = 3.4
146
+ end
147
+
148
+ end
149
+ s = InitializeWithoutSuper.new(0x1eefbeef, 0xdeadcafebabe)
150
+ s[:a].should == 0x1eefbeef
151
+ s[:b].should == 0xdeadcafebabe
152
+ end
153
+
136
154
  it "Can use Struct subclass as parameter type" do
137
155
  module StructParam
138
156
  extend FFI::Library
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wayne Meissner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-16 00:00:00 +10:00
12
+ date: 2010-03-10 00:00:00 +10:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,16 +22,6 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 0.8.7
24
24
  version:
25
- - !ruby/object:Gem::Dependency
26
- name: bones
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 3.2.1
34
- version:
35
25
  description: |-
36
26
  Ruby-FFI is a ruby extension for programmatically loading dynamic
37
27
  libraries, binding functions within them, and calling those functions
@@ -47,7 +37,6 @@ extensions:
47
37
  extra_rdoc_files:
48
38
  - History.txt
49
39
  - README.rdoc
50
- - lib/ffi_c.so
51
40
  files:
52
41
  - History.txt
53
42
  - LICENSE
@@ -372,7 +361,6 @@ files:
372
361
  - lib/ffi/types.rb
373
362
  - lib/ffi/union.rb
374
363
  - lib/ffi/variadic.rb
375
- - lib/ffi_c.so
376
364
  - spec/ffi/bool_spec.rb
377
365
  - spec/ffi/buffer_spec.rb
378
366
  - spec/ffi/callback_spec.rb
Binary file