ffi 1.0.9-x86-mingw32 → 1.0.12.pre-x86-mingw32
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 +16 -16
- data/ext/ffi_c/AbstractMemory.c +376 -14
- data/ext/ffi_c/AbstractMemory.h +8 -0
- data/ext/ffi_c/ArrayType.c +28 -0
- data/ext/ffi_c/Buffer.c +109 -25
- data/ext/ffi_c/Call.c +16 -5
- data/ext/ffi_c/ClosurePool.c +21 -8
- data/ext/ffi_c/DataConverter.c +29 -0
- data/ext/ffi_c/DynamicLibrary.c +71 -2
- data/ext/ffi_c/Function.c +122 -11
- data/ext/ffi_c/Function.h +6 -0
- data/ext/ffi_c/FunctionInfo.c +21 -1
- data/ext/ffi_c/LastError.c +24 -0
- data/ext/ffi_c/MappedType.c +22 -0
- data/ext/ffi_c/MemoryPointer.c +19 -1
- data/ext/ffi_c/MemoryPointer.h +6 -0
- data/ext/ffi_c/MethodHandle.c +26 -11
- data/ext/ffi_c/Platform.c +17 -3
- data/ext/ffi_c/Pointer.c +106 -0
- data/ext/ffi_c/Pointer.h +6 -0
- data/ext/ffi_c/Struct.c +10 -4
- data/ext/ffi_c/Struct.h +2 -1
- data/ext/ffi_c/StructByReference.c +8 -0
- data/ext/ffi_c/StructByValue.c +8 -0
- data/ext/ffi_c/StructLayout.c +8 -2
- data/ext/ffi_c/Thread.c +131 -1
- data/ext/ffi_c/Thread.h +6 -0
- data/ext/ffi_c/Type.c +111 -17
- data/ext/ffi_c/Types.c +9 -2
- data/ext/ffi_c/Types.h +4 -0
- data/ext/ffi_c/Variadic.c +13 -4
- data/ext/ffi_c/compat.h +8 -0
- data/ext/ffi_c/endian.h +10 -1
- data/ext/ffi_c/extconf.rb +51 -35
- data/ext/ffi_c/ffi.c +5 -0
- data/ext/ffi_c/libffi.darwin.mk +15 -15
- data/ext/ffi_c/libffi.gnu.mk +3 -3
- data/ext/ffi_c/libffi.mk +4 -4
- data/ext/ffi_c/libffi.vc.mk +26 -0
- data/ext/ffi_c/libffi.vc64.mk +26 -0
- data/ext/ffi_c/libffi/ChangeLog +541 -0
- data/ext/ffi_c/libffi/ChangeLog.libffi +13 -87
- data/ext/ffi_c/libffi/LICENSE +3 -3
- data/ext/ffi_c/libffi/Makefile.am +41 -32
- data/ext/ffi_c/libffi/Makefile.in +95 -66
- data/ext/ffi_c/libffi/Makefile.vc +141 -0
- data/ext/ffi_c/libffi/Makefile.vc64 +141 -0
- data/ext/ffi_c/libffi/README +40 -4
- data/ext/ffi_c/libffi/aclocal.m4 +729 -7854
- data/ext/ffi_c/libffi/build-ios.sh +67 -0
- data/ext/ffi_c/libffi/compile +11 -10
- data/ext/ffi_c/libffi/config.guess +4 -1
- data/ext/ffi_c/libffi/config.sub +6 -3
- data/ext/ffi_c/libffi/configure +6264 -6354
- data/ext/ffi_c/libffi/configure.ac +155 -63
- data/ext/ffi_c/libffi/depcomp +81 -35
- data/ext/ffi_c/libffi/doc/libffi.info +78 -18
- data/ext/ffi_c/libffi/doc/libffi.texi +64 -5
- data/ext/ffi_c/libffi/doc/stamp-vti +4 -4
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +18 -0
- data/ext/ffi_c/libffi/fficonfig.hw +57 -0
- data/ext/ffi_c/libffi/include/Makefile.in +21 -3
- data/ext/ffi_c/libffi/include/ffi.h.in +42 -14
- data/ext/ffi_c/libffi/include/ffi.h.vc +427 -0
- data/ext/ffi_c/libffi/include/ffi.h.vc64 +427 -0
- data/ext/ffi_c/libffi/include/ffi_common.h +9 -5
- data/ext/ffi_c/libffi/install-sh +364 -167
- data/ext/ffi_c/libffi/ltmain.sh +2599 -1369
- data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +176 -0
- data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +195 -0
- data/ext/ffi_c/libffi/m4/ax_check_compiler_flags.m4 +76 -0
- data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +63 -0
- data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +70 -0
- data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +300 -0
- data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +215 -0
- data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +79 -0
- data/ext/ffi_c/libffi/m4/libtool.m4 +1239 -768
- data/ext/ffi_c/libffi/m4/ltoptions.m4 +7 -6
- data/ext/ffi_c/libffi/m4/ltversion.m4 +6 -6
- data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +9 -3
- data/ext/ffi_c/libffi/man/Makefile.in +21 -3
- data/ext/ffi_c/libffi/mdate-sh +0 -0
- data/ext/ffi_c/libffi/missing +60 -44
- data/ext/ffi_c/libffi/msvcc.sh +197 -0
- data/ext/ffi_c/libffi/src/alpha/osf.S +39 -18
- data/ext/ffi_c/libffi/src/arm/ffi.c +443 -24
- data/ext/ffi_c/libffi/src/arm/ffitarget.h +17 -1
- data/ext/ffi_c/libffi/src/arm/gentramp.sh +118 -0
- data/ext/ffi_c/libffi/src/arm/sysv.S +206 -15
- data/ext/ffi_c/libffi/src/arm/trampoline.S +4450 -0
- data/ext/ffi_c/libffi/src/avr32/ffi.c +4 -2
- data/ext/ffi_c/libffi/src/avr32/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/closures.c +17 -35
- data/ext/ffi_c/libffi/src/cris/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/cris/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/dlmalloc.c +66 -4
- data/ext/ffi_c/libffi/src/frv/ffitarget.h +2 -6
- data/ext/ffi_c/libffi/src/ia64/ffi.c +7 -5
- data/ext/ffi_c/libffi/src/ia64/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/java_raw_api.c +1 -1
- data/ext/ffi_c/libffi/src/m32r/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/m68k/ffi.c +10 -0
- data/ext/ffi_c/libffi/src/m68k/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/m68k/sysv.S +36 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +12 -5
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +18 -11
- data/ext/ffi_c/libffi/src/mips/n32.S +4 -4
- data/ext/ffi_c/libffi/src/moxie/eabi.S +128 -0
- data/ext/ffi_c/libffi/src/moxie/ffi.c +276 -0
- data/ext/ffi_c/libffi/src/pa/ffi.c +7 -4
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +6 -5
- data/ext/ffi_c/libffi/src/powerpc/aix.S +5 -1
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +2 -0
- data/ext/ffi_c/libffi/src/powerpc/asm.h +1 -1
- data/ext/ffi_c/libffi/src/powerpc/darwin.S +215 -77
- data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +358 -100
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +11 -5
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +603 -172
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +17 -4
- data/ext/ffi_c/libffi/src/prep_cif.c +16 -13
- data/ext/ffi_c/libffi/src/s390/ffitarget.h +4 -2
- data/ext/ffi_c/libffi/src/sh/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/sh64/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/sparc/ffi.c +55 -11
- data/ext/ffi_c/libffi/src/sparc/ffitarget.h +5 -3
- data/ext/ffi_c/libffi/src/x86/ffi.c +54 -92
- data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -14
- data/ext/ffi_c/libffi/src/x86/sysv.S +40 -26
- data/ext/ffi_c/libffi/src/x86/unix64.S +4 -0
- data/ext/ffi_c/libffi/src/x86/win32.S +379 -191
- data/ext/ffi_c/libffi/src/x86/win64.S +15 -7
- data/ext/ffi_c/libffi/testsuite/Makefile.am +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.in +22 -4
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +350 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +1 -5
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +3 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +3 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +2 -3
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +17 -17
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +1 -3
- data/ext/ffi_c/win32/stdint.h +199 -0
- data/gen/Rakefile +18 -2
- data/lib/1.8/ffi_c.so +0 -0
- data/lib/ffi.rb +13 -9
- data/lib/ffi/autopointer.rb +88 -26
- data/lib/ffi/enum.rb +42 -0
- data/lib/ffi/errno.rb +6 -1
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/io.rb +13 -2
- data/lib/ffi/library.rb +219 -24
- data/lib/ffi/memorypointer.rb +1 -33
- data/lib/ffi/platform.rb +21 -7
- data/lib/ffi/platform/arm-linux/types.conf +102 -0
- data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
- data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
- data/lib/ffi/platform/i486-gnu/types.conf +107 -0
- data/lib/ffi/platform/ia64-linux/types.conf +102 -0
- data/lib/ffi/platform/mips-linux/types.conf +102 -0
- data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
- data/lib/ffi/platform/powerpc-linux/types.conf +100 -0
- data/lib/ffi/platform/s390-linux/types.conf +102 -0
- data/lib/ffi/platform/s390x-linux/types.conf +102 -0
- data/lib/ffi/platform/sparc-linux/types.conf +102 -0
- data/lib/ffi/platform/x86_64-freebsd/types.conf +126 -0
- data/lib/ffi/platform/x86_64-netbsd/types.conf +126 -0
- data/lib/ffi/pointer.rb +44 -0
- data/lib/ffi/struct.rb +2 -6
- data/lib/ffi/struct_layout_builder.rb +2 -1
- data/lib/ffi/tools/const_generator.rb +78 -26
- data/lib/ffi/tools/types_generator.rb +8 -1
- data/lib/ffi/types.rb +21 -1
- data/spec/ffi/async_callback_spec.rb +2 -2
- data/spec/ffi/bool_spec.rb +6 -6
- data/spec/ffi/buffer_spec.rb +23 -23
- data/spec/ffi/callback_spec.rb +101 -102
- data/spec/ffi/custom_type_spec.rb +20 -24
- data/spec/ffi/dup_spec.rb +7 -7
- data/spec/ffi/enum_spec.rb +127 -127
- data/spec/ffi/errno_spec.rb +2 -2
- data/spec/ffi/ffi_spec.rb +3 -3
- data/spec/ffi/function_spec.rb +10 -10
- data/spec/ffi/library_spec.rb +30 -12
- data/spec/ffi/managed_struct_spec.rb +4 -4
- data/spec/ffi/number_spec.rb +40 -40
- data/spec/ffi/pointer_spec.rb +21 -24
- data/spec/ffi/rbx/memory_pointer_spec.rb +17 -15
- data/spec/ffi/rbx/struct_spec.rb +2 -2
- data/spec/ffi/spec_helper.rb +1 -1
- data/spec/ffi/string_spec.rb +9 -9
- data/spec/ffi/strptr_spec.rb +3 -3
- data/spec/ffi/struct_callback_spec.rb +7 -7
- data/spec/ffi/struct_initialize_spec.rb +2 -2
- data/spec/ffi/struct_packed_spec.rb +6 -6
- data/spec/ffi/struct_spec.rb +94 -84
- data/spec/ffi/typedef_spec.rb +15 -4
- data/spec/ffi/union_spec.rb +3 -3
- data/spec/ffi/variadic_spec.rb +17 -14
- data/tasks/extension.rake +0 -1
- data/tasks/gem.rake +0 -1
- data/tasks/rdoc.rake +1 -1
- data/tasks/yard.rake +11 -0
- metadata +50 -11
- data/lib/1.9/ffi_c.so +0 -0
data/lib/ffi/pointer.rb
CHANGED
@@ -21,13 +21,20 @@
|
|
21
21
|
require 'ffi/platform'
|
22
22
|
module FFI
|
23
23
|
class Pointer
|
24
|
+
|
25
|
+
# Pointer size
|
24
26
|
SIZE = Platform::ADDRESS_SIZE / 8
|
25
27
|
|
26
28
|
# Return the size of a pointer on the current platform, in bytes
|
29
|
+
# @return [Numeric]
|
27
30
|
def self.size
|
28
31
|
SIZE
|
29
32
|
end
|
30
33
|
|
34
|
+
# @param [nil,Numeric] len length of string to return
|
35
|
+
# @return [String]
|
36
|
+
# Read pointer's contents as a string, or the first +len+ bytes of the
|
37
|
+
# equivalent string if +len+ is not +nil+.
|
31
38
|
def read_string(len=nil)
|
32
39
|
if len
|
33
40
|
get_bytes(0, len)
|
@@ -36,24 +43,54 @@ module FFI
|
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
46
|
+
# @param [Numeric] len length of string to return
|
47
|
+
# @return [String]
|
48
|
+
# Read the first +len+ bytes of pointer's contents as a string.
|
49
|
+
#
|
50
|
+
# Same as:
|
51
|
+
# ptr.read_string(len) # with len not nil
|
39
52
|
def read_string_length(len)
|
40
53
|
get_bytes(0, len)
|
41
54
|
end
|
42
55
|
|
56
|
+
# @return [String]
|
57
|
+
# Read pointer's contents as a string.
|
58
|
+
#
|
59
|
+
# Same as:
|
60
|
+
# ptr.read_string # with no len
|
43
61
|
def read_string_to_null
|
44
62
|
get_string(0)
|
45
63
|
end
|
46
64
|
|
65
|
+
# @param [String] str string to write
|
66
|
+
# @param [Numeric] len length of string to return
|
67
|
+
# @return [self]
|
68
|
+
# Write +len+ first bytes of +str+ in pointer's contents.
|
69
|
+
#
|
70
|
+
# Same as:
|
71
|
+
# ptr.write_string(str, len) # with len not nil
|
47
72
|
def write_string_length(str, len)
|
48
73
|
put_bytes(0, str, 0, len)
|
49
74
|
end
|
50
75
|
|
76
|
+
# @param [String] str string to write
|
77
|
+
# @param [Numeric] len length of string to return
|
78
|
+
# @return [self]
|
79
|
+
# Write +str+ in pointer's contents, or first +len+ bytes if
|
80
|
+
# +len+ is not +nil+.
|
51
81
|
def write_string(str, len=nil)
|
52
82
|
len = str.bytesize unless len
|
53
83
|
# Write the string data without NUL termination
|
54
84
|
put_bytes(0, str, 0, len)
|
55
85
|
end
|
56
86
|
|
87
|
+
# @param [Type] type type of data to read from pointer's contents
|
88
|
+
# @param [Symbol] reader method to send to +self+ to read +type+
|
89
|
+
# @param [Numeric] length
|
90
|
+
# @return [Array]
|
91
|
+
# Read an array of +type+ of length +length+.
|
92
|
+
# @example
|
93
|
+
# ptr.write_array_of_type(TYPE_UINT8, :get_uint8, 4) # -> [1, 2, 3, 4]
|
57
94
|
def read_array_of_type(type, reader, length)
|
58
95
|
ary = []
|
59
96
|
size = FFI.type_size(type)
|
@@ -65,6 +102,13 @@ module FFI
|
|
65
102
|
ary
|
66
103
|
end
|
67
104
|
|
105
|
+
# @param [Type] type type of data to write to pointer's contents
|
106
|
+
# @param [Symbol] writer method to send to +self+ to write +type+
|
107
|
+
# @param [Array] ary
|
108
|
+
# @return [self]
|
109
|
+
# Write +ary+ in pointer's contents as +type+.
|
110
|
+
# @example
|
111
|
+
# ptr.write_array_of_type(TYPE_UINT8, :put_uint8, [1, 2, 3 ,4])
|
68
112
|
def write_array_of_type(type, writer, ary)
|
69
113
|
size = FFI.type_size(type)
|
70
114
|
tmp = self
|
data/lib/ffi/struct.rb
CHANGED
@@ -123,10 +123,6 @@ module FFI
|
|
123
123
|
@layout.alignment
|
124
124
|
end
|
125
125
|
|
126
|
-
def self.align
|
127
|
-
@layout.alignment
|
128
|
-
end
|
129
|
-
|
130
126
|
def self.members
|
131
127
|
@layout.members
|
132
128
|
end
|
@@ -222,13 +218,13 @@ module FFI
|
|
222
218
|
def aligned(alignment = 1)
|
223
219
|
@min_alignment = alignment
|
224
220
|
end
|
225
|
-
|
221
|
+
alias :align :aligned
|
226
222
|
|
227
223
|
def enclosing_module
|
228
224
|
begin
|
229
225
|
mod = self.name.split("::")[0..-2].inject(Object) { |obj, c| obj.const_get(c) }
|
230
226
|
mod.respond_to?(:find_type) ? mod : nil
|
231
|
-
rescue Exception
|
227
|
+
rescue Exception
|
232
228
|
nil
|
233
229
|
end
|
234
230
|
end
|
@@ -3,25 +3,40 @@ require 'open3'
|
|
3
3
|
|
4
4
|
module FFI
|
5
5
|
|
6
|
-
##
|
7
6
|
# ConstGenerator turns C constants into ruby values.
|
8
|
-
|
7
|
+
#
|
8
|
+
# @example a simple example for stdio
|
9
|
+
# cg = FFI::ConstGenerator.new('stdio') do |gen|
|
10
|
+
# gen.const(:SEEK_SET)
|
11
|
+
# gen.const('SEEK_CUR')
|
12
|
+
# gen.const('seek_end') # this constant does not exist
|
13
|
+
# end # #calculate called automatically at the end of the block
|
14
|
+
#
|
15
|
+
# cg['SEEK_SET'] # => 0
|
16
|
+
# cg['SEEK_CUR'] # => 1
|
17
|
+
# cg['seek_end'] # => nil
|
18
|
+
# cg.to_ruby # => "SEEK_SET = 0\nSEEK_CUR = 1\n# seek_end not available"
|
9
19
|
class ConstGenerator
|
10
20
|
@options = {}
|
11
21
|
attr_reader :constants
|
12
22
|
|
13
|
-
##
|
14
23
|
# Creates a new constant generator that uses +prefix+ as a name, and an
|
15
24
|
# options hash.
|
16
25
|
#
|
17
|
-
# The only option is
|
26
|
+
# The only option is +:required+, which if set to +true+ raises an error if a
|
18
27
|
# constant you have requested was not found.
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
|
28
|
+
#
|
29
|
+
# @param [#to_s] prefix
|
30
|
+
# @param [Hash] options
|
31
|
+
# @return
|
32
|
+
# @option options [Boolean] :required
|
33
|
+
# @overload initialize(prefix, options)
|
34
|
+
# @overload initialize(prefix, options) { |gen| ... }
|
35
|
+
# @yieldparam [ConstGenerator] gen new generator is passed to the block
|
36
|
+
# When passed a block, {#calculate} is automatically called at the end of
|
37
|
+
# the block, otherwise you must call it yourself.
|
23
38
|
def initialize(prefix = nil, options = {})
|
24
|
-
@includes = []
|
39
|
+
@includes = ['stdio.h', 'stddef.h']
|
25
40
|
@constants = {}
|
26
41
|
@prefix = prefix
|
27
42
|
|
@@ -33,23 +48,40 @@ module FFI
|
|
33
48
|
calculate self.class.options.merge(options)
|
34
49
|
end
|
35
50
|
end
|
51
|
+
# Set class options
|
52
|
+
# These options are merged with {#initialize} options when it is called with a block.
|
53
|
+
# @param [Hash] options
|
54
|
+
# @return [Hash] class options
|
36
55
|
def self.options=(options)
|
37
56
|
@options = options
|
38
57
|
end
|
58
|
+
# Get class options.
|
59
|
+
# @return [Hash] class options
|
39
60
|
def self.options
|
40
61
|
@options
|
41
62
|
end
|
63
|
+
# @param [String] name
|
64
|
+
# @return constant value (converted if a +converter+ was defined).
|
65
|
+
# Access a constant by name.
|
42
66
|
def [](name)
|
43
|
-
@constants[name].
|
67
|
+
@constants[name].converted_value
|
44
68
|
end
|
45
69
|
|
46
|
-
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
|
70
|
+
# Request the value for C constant +name+.
|
71
|
+
#
|
72
|
+
# @param [#to_s] name C constant name
|
73
|
+
# @param [String] format a printf format string to print the value out
|
74
|
+
# @param [String] cast a C cast for the value
|
75
|
+
# @param ruby_name alternate ruby name for {#to_ruby}
|
76
|
+
#
|
77
|
+
# @overload const(name, format=nil, cast='', ruby_name=nil, converter=nil)
|
78
|
+
# +converter+ is a Method or a Proc.
|
79
|
+
# @param [#call] converter convert the value from a string to the appropriate
|
80
|
+
# type for {#to_ruby}.
|
81
|
+
# @overload const(name, format=nil, cast='', ruby_name=nil) { |value| ... }
|
82
|
+
# Use a converter block. This block convert the value from a string to the
|
83
|
+
# appropriate type for {#to_ruby}.
|
84
|
+
# @yieldparam value constant value
|
53
85
|
def const(name, format = nil, cast = '', ruby_name = nil, converter = nil,
|
54
86
|
&converter_proc)
|
55
87
|
format ||= '%d'
|
@@ -66,18 +98,19 @@ module FFI
|
|
66
98
|
return const
|
67
99
|
end
|
68
100
|
|
101
|
+
# Calculate constants values.
|
102
|
+
# @param [Hash] options
|
103
|
+
# @option options [String] :cppflags flags for C compiler
|
104
|
+
# @return [nil]
|
105
|
+
# @raise if a constant is missing and +:required+ was set to +true+ (see {#initialize})
|
69
106
|
def calculate(options = {})
|
70
107
|
binary = File.join Dir.tmpdir, "rb_const_gen_bin_#{Process.pid}"
|
71
108
|
|
72
109
|
Tempfile.open("#{@prefix}.const_generator") do |f|
|
73
|
-
f.puts "#include <stdio.h>"
|
74
|
-
|
75
110
|
@includes.each do |inc|
|
76
111
|
f.puts "#include <#{inc}>"
|
77
112
|
end
|
78
|
-
|
79
|
-
f.puts "#include <stddef.h>\n\n"
|
80
|
-
f.puts "int main(int argc, char **argv)\n{"
|
113
|
+
f.puts "\nint main(int argc, char **argv)\n{"
|
81
114
|
|
82
115
|
@constants.each_value do |const|
|
83
116
|
f.puts <<-EOF
|
@@ -115,6 +148,9 @@ module FFI
|
|
115
148
|
end
|
116
149
|
end
|
117
150
|
|
151
|
+
# Dump constants to +io+.
|
152
|
+
# @param [#puts] io
|
153
|
+
# @return [nil]
|
118
154
|
def dump_constants(io)
|
119
155
|
@constants.each do |name, constant|
|
120
156
|
name = [@prefix, name].join '.' if @prefix
|
@@ -122,10 +158,9 @@ module FFI
|
|
122
158
|
end
|
123
159
|
end
|
124
160
|
|
125
|
-
##
|
126
161
|
# Outputs values for discovered constants. If the constant's value was
|
127
162
|
# not discovered it is not omitted.
|
128
|
-
|
163
|
+
# @return [String]
|
129
164
|
def to_ruby
|
130
165
|
@constants.sort_by { |name,| name }.map do |name, constant|
|
131
166
|
if constant.value.nil? then
|
@@ -136,17 +171,28 @@ module FFI
|
|
136
171
|
end.join "\n"
|
137
172
|
end
|
138
173
|
|
139
|
-
|
140
|
-
|
174
|
+
# Add additional C include file(s) to calculate constants from.
|
175
|
+
# @note +stdio.h+ and +stddef.h+ automatically included
|
176
|
+
# @param [List<String>, Array<String>] i include file(s)
|
177
|
+
# @return [Array<String>] array of include files
|
178
|
+
def include(*i)
|
179
|
+
@includes |= i.flatten
|
141
180
|
end
|
142
181
|
|
143
182
|
end
|
144
183
|
|
184
|
+
# This class hold constants for {ConstGenerator}
|
145
185
|
class ConstGenerator::Constant
|
146
186
|
|
147
187
|
attr_reader :name, :format, :cast
|
148
188
|
attr_accessor :value
|
149
189
|
|
190
|
+
# @param [#to_s] name
|
191
|
+
# @param [String] format a printf format string to print the value out
|
192
|
+
# @param [String] cast a C cast for the value
|
193
|
+
# @param ruby_name alternate ruby name for {#to_ruby}
|
194
|
+
# @param [#call] converter convert the value from a string to the appropriate
|
195
|
+
# type for {#to_ruby}.
|
150
196
|
def initialize(name, format, cast, ruby_name = nil, converter=nil)
|
151
197
|
@name = name
|
152
198
|
@format = format
|
@@ -156,6 +202,8 @@ module FFI
|
|
156
202
|
@value = nil
|
157
203
|
end
|
158
204
|
|
205
|
+
# Return constant value (converted if a +converter+ was defined).
|
206
|
+
# @return constant value.
|
159
207
|
def converted_value
|
160
208
|
if @converter
|
161
209
|
@converter.call(@value)
|
@@ -164,10 +212,14 @@ module FFI
|
|
164
212
|
end
|
165
213
|
end
|
166
214
|
|
215
|
+
# get constant ruby name
|
216
|
+
# @return [String]
|
167
217
|
def ruby_name
|
168
218
|
@ruby_name || @name
|
169
219
|
end
|
170
220
|
|
221
|
+
# Get an evaluable string from constant.
|
222
|
+
# @return [String]
|
171
223
|
def to_ruby
|
172
224
|
"#{ruby_name} = #{converted_value}"
|
173
225
|
end
|
@@ -51,7 +51,14 @@ module FFI
|
|
51
51
|
C
|
52
52
|
|
53
53
|
io.close
|
54
|
-
|
54
|
+
cmd = "gcc -E -x c #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -c"
|
55
|
+
if options[:input]
|
56
|
+
typedefs = File.read(options[:input])
|
57
|
+
elsif options[:remote]
|
58
|
+
typedefs = `ssh #{options[:remote]} #{cmd} - < #{io.path}`
|
59
|
+
else
|
60
|
+
typedefs = `#{cmd} #{io.path}`
|
61
|
+
end
|
55
62
|
end
|
56
63
|
|
57
64
|
code = ""
|
data/lib/ffi/types.rb
CHANGED
@@ -17,17 +17,29 @@
|
|
17
17
|
# version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
19
|
|
20
|
+
# see {file:README}
|
20
21
|
module FFI
|
21
22
|
|
23
|
+
# @param [Type, DataConverter, Symbol] old type definition used by {FFI.find_type}
|
24
|
+
# @param [Symbol] add new type definition's name to add
|
25
|
+
# @return [Type]
|
26
|
+
# Add a definition type to type definitions.
|
22
27
|
def self.typedef(old, add)
|
23
28
|
TypeDefs[add] = self.find_type(old)
|
24
29
|
end
|
25
30
|
|
31
|
+
# (see FFI.typedef)
|
26
32
|
def self.add_typedef(old, add)
|
27
33
|
typedef old, add
|
28
34
|
end
|
29
35
|
|
30
36
|
|
37
|
+
# @param [Type, DataConverter, Symbol] name
|
38
|
+
# @param [Hash] type_map if nil, {FFI::TypeDefs} is used
|
39
|
+
# @return [Type]
|
40
|
+
# Find a type in +type_map+ ({FFI::TypeDefs}, by default) from
|
41
|
+
# a type objet, a type name (symbol). If +name+ is a {DataConverter},
|
42
|
+
# a new {Type::Mapped} is created.
|
31
43
|
def self.find_type(name, type_map = nil)
|
32
44
|
if name.is_a?(Type)
|
33
45
|
name
|
@@ -46,6 +58,7 @@ module FFI
|
|
46
58
|
end
|
47
59
|
end
|
48
60
|
|
61
|
+
# List of type definitions
|
49
62
|
TypeDefs.merge!({
|
50
63
|
# The C void type; only useful for function return types
|
51
64
|
:void => Type::VOID,
|
@@ -120,11 +133,15 @@ module FFI
|
|
120
133
|
:varargs => Type::VARARGS,
|
121
134
|
})
|
122
135
|
|
123
|
-
|
136
|
+
|
124
137
|
class StrPtrConverter
|
125
138
|
extend DataConverter
|
126
139
|
native_type Type::POINTER
|
127
140
|
|
141
|
+
# @param [Pointer] val
|
142
|
+
# @param [] ctx
|
143
|
+
# @return [Array(String, Pointer)]
|
144
|
+
# Returns a [ String, Pointer ] tuple so the C memory for the string can be freed
|
128
145
|
def self.from_native(val, ctx)
|
129
146
|
[ val.null? ? nil : val.get_string(0), val ]
|
130
147
|
end
|
@@ -133,6 +150,9 @@ module FFI
|
|
133
150
|
|
134
151
|
typedef(StrPtrConverter, :strptr)
|
135
152
|
|
153
|
+
# @param type +type+ is an instance of class accepted by {FFI.find_type}
|
154
|
+
# @return [Numeric]
|
155
|
+
# Get +type+ size, in bytes.
|
136
156
|
def self.type_size(type)
|
137
157
|
find_type(type).size
|
138
158
|
end
|
@@ -32,7 +32,7 @@ describe "async callback" do
|
|
32
32
|
cb = Proc.new {|i| v = i; called = true }
|
33
33
|
LibTest.testAsyncCallback(cb, 0x7fffffff)
|
34
34
|
called.should be_true
|
35
|
-
v.should
|
35
|
+
v.should eq 0x7fffffff
|
36
36
|
end
|
37
37
|
|
38
38
|
it "called a second time" do
|
@@ -41,6 +41,6 @@ describe "async callback" do
|
|
41
41
|
cb = Proc.new {|i| v = i; called = true }
|
42
42
|
LibTest.testAsyncCallback(cb, 0x7fffffff)
|
43
43
|
called.should be_true
|
44
|
-
v.should
|
44
|
+
v.should eq 0x7fffffff
|
45
45
|
end
|
46
46
|
end
|
data/spec/ffi/bool_spec.rb
CHANGED
@@ -25,14 +25,14 @@ describe "Function with primitive boolean arguments and return values" do
|
|
25
25
|
attach_function :bool_reverse_val, [ :bool ], :bool
|
26
26
|
end
|
27
27
|
it "bools" do
|
28
|
-
LibTest.bool_return_true.should
|
29
|
-
LibTest.bool_return_false.should
|
28
|
+
LibTest.bool_return_true.should eq true
|
29
|
+
LibTest.bool_return_false.should eq false
|
30
30
|
|
31
|
-
LibTest.bool_return_val(true).should
|
32
|
-
LibTest.bool_return_val(false).should
|
31
|
+
LibTest.bool_return_val(true).should eq true
|
32
|
+
LibTest.bool_return_val(false).should eq false
|
33
33
|
|
34
|
-
LibTest.bool_reverse_val(true).should
|
35
|
-
LibTest.bool_reverse_val(false).should
|
34
|
+
LibTest.bool_reverse_val(true).should eq false
|
35
|
+
LibTest.bool_reverse_val(false).should eq true
|
36
36
|
end
|
37
37
|
it "raise error on invalid types" do
|
38
38
|
lambda { LibTest.bool_return_val(nil) }.should raise_error(::TypeError)
|
data/spec/ffi/buffer_spec.rb
CHANGED
@@ -23,13 +23,13 @@ describe "Buffer#total" do
|
|
23
23
|
:long_long => 8, :ulong_long => 8, :float => 4, :double => 8
|
24
24
|
}.each_pair do |t, s|
|
25
25
|
it "Buffer.alloc_in(#{t}, #{i}).total == #{i * s}" do
|
26
|
-
FFI::Buffer.alloc_in(t, i).total.should
|
26
|
+
FFI::Buffer.alloc_in(t, i).total.should eq i * s
|
27
27
|
end
|
28
28
|
it "Buffer.alloc_out(#{t}, #{i}).total == #{i * s}" do
|
29
|
-
FFI::Buffer.alloc_out(t, i).total.should
|
29
|
+
FFI::Buffer.alloc_out(t, i).total.should eq i * s
|
30
30
|
end
|
31
31
|
it "Buffer.alloc_inout(#{t}, #{i}).total == #{i * s}" do
|
32
|
-
FFI::Buffer.alloc_inout(t, i).total.should
|
32
|
+
FFI::Buffer.alloc_inout(t, i).total.should eq i * s
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -40,7 +40,7 @@ describe "Buffer#put_char" do
|
|
40
40
|
(0..127).each do |i|
|
41
41
|
(0..bufsize-1).each do |offset|
|
42
42
|
it "put_char(#{offset}, #{i}).get_char(#{offset}) == #{i}" do
|
43
|
-
FFI::Buffer.alloc_in(bufsize).put_char(offset, i).get_char(offset).should
|
43
|
+
FFI::Buffer.alloc_in(bufsize).put_char(offset, i).get_char(offset).should eq i
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -50,7 +50,7 @@ describe "Buffer#put_uchar" do
|
|
50
50
|
(0..255).each do |i|
|
51
51
|
(0..bufsize-1).each do |offset|
|
52
52
|
it "Buffer.put_uchar(#{offset}, #{i}).get_uchar(#{offset}) == #{i}" do
|
53
|
-
FFI::Buffer.alloc_in(bufsize).put_uchar(offset, i).get_uchar(offset).should
|
53
|
+
FFI::Buffer.alloc_in(bufsize).put_uchar(offset, i).get_uchar(offset).should eq i
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -60,7 +60,7 @@ describe "Buffer#put_short" do
|
|
60
60
|
[0, 1, 128, 32767].each do |i|
|
61
61
|
(0..bufsize-2).each do |offset|
|
62
62
|
it "put_short(#{offset}, #{i}).get_short(#{offset}) == #{i}" do
|
63
|
-
FFI::Buffer.alloc_in(bufsize).put_short(offset, i).get_short(offset).should
|
63
|
+
FFI::Buffer.alloc_in(bufsize).put_short(offset, i).get_short(offset).should eq i
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -70,7 +70,7 @@ describe "Buffer#put_ushort" do
|
|
70
70
|
[ 0, 1, 128, 32767, 65535, 0xfee1, 0xdead, 0xbeef, 0xcafe ].each do |i|
|
71
71
|
(0..bufsize-2).each do |offset|
|
72
72
|
it "put_ushort(#{offset}, #{i}).get_ushort(#{offset}) == #{i}" do
|
73
|
-
FFI::Buffer.alloc_in(bufsize).put_ushort(offset, i).get_ushort(offset).should
|
73
|
+
FFI::Buffer.alloc_in(bufsize).put_ushort(offset, i).get_ushort(offset).should eq i
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -80,7 +80,7 @@ describe "Buffer#put_int" do
|
|
80
80
|
[0, 1, 128, 32767, 0x7ffffff ].each do |i|
|
81
81
|
(0..bufsize-4).each do |offset|
|
82
82
|
it "put_int(#{offset}, #{i}).get_int(#{offset}) == #{i}" do
|
83
|
-
FFI::Buffer.alloc_in(bufsize).put_int(offset, i).get_int(offset).should
|
83
|
+
FFI::Buffer.alloc_in(bufsize).put_int(offset, i).get_int(offset).should eq i
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -90,7 +90,7 @@ describe "Buffer#put_uint" do
|
|
90
90
|
[ 0, 1, 128, 32767, 65535, 0xfee1dead, 0xcafebabe, 0xffffffff ].each do |i|
|
91
91
|
(0..bufsize-4).each do |offset|
|
92
92
|
it "put_uint(#{offset}, #{i}).get_uint(#{offset}) == #{i}" do
|
93
|
-
FFI::Buffer.alloc_in(bufsize).put_uint(offset, i).get_uint(offset).should
|
93
|
+
FFI::Buffer.alloc_in(bufsize).put_uint(offset, i).get_uint(offset).should eq i
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -100,7 +100,7 @@ describe "Buffer#put_long" do
|
|
100
100
|
[0, 1, 128, 32767, 0x7ffffff ].each do |i|
|
101
101
|
(0..bufsize-FFI::Type::LONG.size).each do |offset|
|
102
102
|
it "put_long(#{offset}, #{i}).get_long(#{offset}) == #{i}" do
|
103
|
-
FFI::Buffer.alloc_in(bufsize).put_long(offset, i).get_long(offset).should
|
103
|
+
FFI::Buffer.alloc_in(bufsize).put_long(offset, i).get_long(offset).should eq i
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
@@ -110,7 +110,7 @@ describe "Buffer#put_ulong" do
|
|
110
110
|
[ 0, 1, 128, 32767, 65535, 0xfee1dead, 0xcafebabe, 0xffffffff ].each do |i|
|
111
111
|
(0..bufsize-FFI::Type::LONG.size).each do |offset|
|
112
112
|
it "put_ulong(#{offset}, #{i}).get_ulong(#{offset}) == #{i}" do
|
113
|
-
FFI::Buffer.alloc_in(bufsize).put_ulong(offset, i).get_ulong(offset).should
|
113
|
+
FFI::Buffer.alloc_in(bufsize).put_ulong(offset, i).get_ulong(offset).should eq i
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
@@ -120,7 +120,7 @@ describe "Buffer#put_long_long" do
|
|
120
120
|
[0, 1, 128, 32767, 0x7ffffffffffffff ].each do |i|
|
121
121
|
(0..bufsize-8).each do |offset|
|
122
122
|
it "put_long_long(#{offset}, #{i}).get_long_long(#{offset}) == #{i}" do
|
123
|
-
FFI::Buffer.alloc_in(bufsize).put_long_long(offset, i).get_long_long(offset).should
|
123
|
+
FFI::Buffer.alloc_in(bufsize).put_long_long(offset, i).get_long_long(offset).should eq i
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
@@ -130,7 +130,7 @@ describe "Buffer#put_ulong_long" do
|
|
130
130
|
[ 0, 1, 128, 32767, 65535, 0xdeadcafebabe, 0x7fffffffffffffff ].each do |i|
|
131
131
|
(0..bufsize-8).each do |offset|
|
132
132
|
it "put_ulong_long(#{offset}, #{i}).get_ulong_long(#{offset}) == #{i}" do
|
133
|
-
FFI::Buffer.alloc_in(bufsize).put_ulong_long(offset, i).get_ulong_long(offset).should
|
133
|
+
FFI::Buffer.alloc_in(bufsize).put_ulong_long(offset, i).get_ulong_long(offset).should eq i
|
134
134
|
end
|
135
135
|
end
|
136
136
|
end
|
@@ -141,21 +141,21 @@ describe "Reading/Writing binary strings" do
|
|
141
141
|
buf = FFI::Buffer.new 1024
|
142
142
|
buf.put_bytes(0, str);
|
143
143
|
s2 = buf.get_bytes(0, 11);
|
144
|
-
s2.should
|
144
|
+
s2.should eq str
|
145
145
|
end
|
146
146
|
it "Buffer#put_bytes with index and length" do
|
147
147
|
str = "hello\0world"
|
148
148
|
buf = FFI::Buffer.new 1024
|
149
149
|
buf.put_bytes(0, str, 5, 6);
|
150
150
|
s2 = buf.get_bytes(0, 6);
|
151
|
-
s2.should
|
151
|
+
s2.should eq str[5..-1]
|
152
152
|
end
|
153
153
|
it "Buffer#put_bytes with only index" do
|
154
154
|
str = "hello\0world"
|
155
155
|
buf = FFI::Buffer.new 1024
|
156
156
|
buf.put_bytes(0, str, 5);
|
157
157
|
s2 = buf.get_bytes(0, 6);
|
158
|
-
s2.should
|
158
|
+
s2.should eq str[5..-1]
|
159
159
|
end
|
160
160
|
it "Buffer#put_bytes with index > str.length" do
|
161
161
|
str = "hello\0world"
|
@@ -179,21 +179,21 @@ describe "Reading/Writing ascii strings" do
|
|
179
179
|
buf = FFI::Buffer.new 1024
|
180
180
|
buf.put_string(0, str);
|
181
181
|
s2 = buf.get_bytes(0, 11);
|
182
|
-
s2.should
|
182
|
+
s2.should eq str
|
183
183
|
end
|
184
184
|
it "Buffer#get_string with string containing zero byte" do
|
185
185
|
str = "hello\0world"
|
186
186
|
buf = FFI::Buffer.new 1024
|
187
187
|
buf.put_bytes(0, str);
|
188
188
|
s2 = buf.get_string(0, 11);
|
189
|
-
s2.should
|
189
|
+
s2.should eq "hello"
|
190
190
|
end
|
191
191
|
it "Buffer#put_string without length should NUL terminate" do
|
192
192
|
str = "hello"
|
193
193
|
buf = FFI::Buffer.new 1024
|
194
194
|
buf.put_string(0, str);
|
195
195
|
s2 = buf.get_bytes(0, 6);
|
196
|
-
s2.should
|
196
|
+
s2.should eq "hello\0"
|
197
197
|
end
|
198
198
|
end
|
199
199
|
describe "Buffer#put_pointer" do
|
@@ -203,13 +203,13 @@ describe "Buffer#put_pointer" do
|
|
203
203
|
buf = FFI::Buffer.alloc_inout 8
|
204
204
|
p2 = buf.put_pointer(0, p).get_pointer(0)
|
205
205
|
p2.should_not be_nil
|
206
|
-
p2.should
|
207
|
-
p2.get_uint(0).should
|
206
|
+
p2.should eq p
|
207
|
+
p2.get_uint(0).should eq 0xdeadbeef
|
208
208
|
end
|
209
209
|
end
|
210
210
|
describe "Buffer#size" do
|
211
211
|
it "should return size" do
|
212
212
|
buf = FFI::Buffer.new 14
|
213
|
-
buf.size.should
|
213
|
+
buf.size.should eq 14
|
214
214
|
end
|
215
|
-
end
|
215
|
+
end
|