ffi-swig-generator 0.2.1 → 0.3.0
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/.hg/branch.cache +2 -0
- data/.hg/dirstate +0 -0
- data/.hg/store/00changelog.i +0 -0
- data/.hg/store/00manifest.i +0 -0
- data/.hg/store/data/.hgignore.i +0 -0
- data/.hg/store/data/.hgtags.i +0 -0
- data/.hg/store/data/_history.txt.i +0 -0
- data/.hg/store/data/_r_e_a_d_m_e.rdoc.i +0 -0
- data/.hg/store/data/_rakefile.i +0 -0
- data/.hg/store/data/cucumber.yml.i +0 -0
- data/.hg/store/data/examples/_rakefile.i +0 -0
- data/.hg/store/data/features/generate.feature.i +0 -0
- data/.hg/store/data/features/step__definitions/generate.rb.i +0 -0
- data/.hg/store/data/features/support/env.rb.i +0 -0
- data/.hg/store/data/features/support/results.rb.i +0 -0
- data/.hg/store/data/features/support/templates.rb.i +0 -0
- data/.hg/store/data/lib/ffi-swig-generator.rb.i +0 -0
- data/.hg/store/data/lib/generator/application.rb.i +0 -0
- data/.hg/store/data/lib/generator/constant.rb.i +0 -0
- data/.hg/store/data/lib/generator/enum.rb.i +0 -0
- data/.hg/store/data/lib/generator/function.rb.i +0 -0
- data/.hg/store/data/lib/generator/generator.rb.i +0 -0
- data/.hg/store/data/lib/generator/generatortask.rb.i +0 -0
- data/.hg/store/data/lib/generator/logger.rb.i +0 -0
- data/.hg/store/data/lib/generator/node.rb.i +0 -0
- data/.hg/store/data/lib/generator/parser.rb.i +0 -0
- data/.hg/store/data/lib/generator/struct.rb.i +0 -0
- data/.hg/store/data/lib/generator/type.rb.i +0 -0
- data/.hg/store/data/lib/generator/types.rb.i +0 -0
- data/.hg/store/data/spec/generator/constant__spec.rb.i +0 -0
- data/.hg/store/data/spec/generator/enum__spec.rb.i +0 -0
- data/.hg/store/data/spec/generator/function__spec.rb.i +0 -0
- data/.hg/store/data/spec/generator/generator__spec.rb.i +0 -0
- data/.hg/store/data/spec/generator/node__spec.rb.i +0 -0
- data/.hg/store/data/spec/generator/parser__spec.rb.i +0 -0
- data/.hg/store/data/spec/generator/struct__spec.rb.i +0 -0
- data/.hg/store/data/spec/generator/swig/constants.i.i +0 -0
- data/.hg/store/data/spec/generator/swig/functions.i.i +0 -0
- data/.hg/store/data/spec/generator/swig/testlib.i.i +0 -0
- data/.hg/store/data/spec/generator/swig/typedefs.i.i +0 -0
- data/.hg/store/data/spec/generator/swig/types.i.i +0 -0
- data/.hg/store/data/spec/generator/type__spec.rb.i +0 -0
- data/.hg/store/data/spec/spec__helper.rb.i +0 -0
- data/.hg/store/data/tasks/cucumber.rake.i +0 -0
- data/.hg/store/undo +0 -0
- data/.hg/undo.dirstate +0 -0
- data/.hgignore +3 -0
- data/.hgtags +1 -0
- data/History.txt +22 -2
- data/README.rdoc +26 -22
- data/Rakefile +2 -3
- data/cucumber.yml +1 -0
- data/examples/Rakefile +5 -3
- data/examples/generated/libc_wrap.rb +18 -0
- data/examples/generated/libc_wrap.xml +597 -0
- data/examples/generated/wiiuse_wrap.rb +322 -0
- data/examples/generated/wiiuse_wrap.xml +9025 -0
- data/features/generate.feature +45 -0
- data/features/step_definitions/generate.rb +32 -0
- data/features/support/env.rb +4 -0
- data/features/support/templates.rb +381 -0
- data/lib/ffi-swig-generator.rb +1 -1
- data/lib/generator/application.rb +1 -1
- data/lib/generator/constant.rb +24 -0
- data/lib/generator/enum.rb +38 -0
- data/lib/generator/function.rb +71 -0
- data/lib/generator/generatortask.rb +21 -9
- data/lib/generator/logger.rb +29 -0
- data/lib/generator/node.rb +19 -0
- data/lib/generator/parser.rb +168 -0
- data/lib/generator/struct.rb +76 -0
- data/lib/generator/type.rb +128 -0
- data/lib/generator/types.rb +36 -0
- data/spec/generator/constant_spec.rb +17 -0
- data/spec/generator/enum_spec.rb +29 -0
- data/spec/generator/function_spec.rb +66 -0
- data/spec/generator/parser_spec.rb +250 -0
- data/spec/generator/struct_spec.rb +77 -0
- data/spec/generator/swig/constants.i +5 -0
- data/spec/generator/swig/functions.i +8 -0
- data/spec/generator/swig/testlib.i +42 -0
- data/spec/generator/swig/typedefs.i +1 -0
- data/spec/generator/swig/types.i +1 -0
- data/spec/generator/type_spec.rb +38 -0
- data/spec/spec_helper.rb +6 -0
- data/tasks/cucumber.rake +8 -0
- metadata +58 -18
- data/lib/generator/generator.rb +0 -344
- data/spec/generator/generator_spec.rb +0 -248
@@ -0,0 +1,128 @@
|
|
1
|
+
module FFI
|
2
|
+
module Generator
|
3
|
+
require libpath('generator/node')
|
4
|
+
class Type < Node
|
5
|
+
attr_reader :full_decl
|
6
|
+
class Declaration
|
7
|
+
def initialize(declaration)
|
8
|
+
@full_decl = declaration
|
9
|
+
end
|
10
|
+
def is_native?
|
11
|
+
Generator::TYPES.has_key?(@full_decl)
|
12
|
+
end
|
13
|
+
def is_pointer?
|
14
|
+
@full_decl[/^p\./] and not is_inline_callback?
|
15
|
+
end
|
16
|
+
def is_enum?
|
17
|
+
@full_decl[/^enum/]
|
18
|
+
end
|
19
|
+
def is_array?
|
20
|
+
@full_decl and @full_decl[/\w+\(\d+\)/]
|
21
|
+
end
|
22
|
+
def is_struct?
|
23
|
+
@full_decl[/^struct/]
|
24
|
+
end
|
25
|
+
def is_union?
|
26
|
+
@full_decl[/^union/]
|
27
|
+
end
|
28
|
+
def is_constant?
|
29
|
+
@full_decl[/^q\(const\)/]
|
30
|
+
end
|
31
|
+
def is_volatile?
|
32
|
+
@full_decl[/^q\(volatile\)/]
|
33
|
+
end
|
34
|
+
def is_callback?
|
35
|
+
@full_decl[/^callback/]
|
36
|
+
end
|
37
|
+
def is_inline_callback?
|
38
|
+
@full_decl[/^p.f\(/]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def initialize(params = { })
|
42
|
+
super
|
43
|
+
params = { :declaration => get_full_decl, :typedefs => { } }.merge(params)
|
44
|
+
@full_decl = params[:declaration]
|
45
|
+
@typedefs = params[:typedefs] || { }
|
46
|
+
@declaration = Declaration.new(@full_decl)
|
47
|
+
@is_pointer = 0
|
48
|
+
end
|
49
|
+
def to_s
|
50
|
+
ffi_type_from(@full_decl)
|
51
|
+
end
|
52
|
+
private
|
53
|
+
def get_full_decl
|
54
|
+
get_attr('decl').to_s + get_attr('type').to_s if @node
|
55
|
+
end
|
56
|
+
def decl
|
57
|
+
get_attr('decl').to_s
|
58
|
+
end
|
59
|
+
def type
|
60
|
+
get_attr('type').to_s
|
61
|
+
end
|
62
|
+
def native
|
63
|
+
ffi_type_from(Generator::TYPES[@full_decl]) if @declaration.is_native?
|
64
|
+
end
|
65
|
+
def constant
|
66
|
+
ffi_type_from(@full_decl.scan(/^q\(const\)\.(.+)/).flatten[0]) if @declaration.is_constant?
|
67
|
+
end
|
68
|
+
def volatile
|
69
|
+
ffi_type_from(@full_decl.scan(/^q\(volatile\)\.(.+)/).flatten[0]) if @declaration.is_volatile?
|
70
|
+
end
|
71
|
+
def pointer
|
72
|
+
if @declaration.is_pointer? or @is_pointer > 0
|
73
|
+
@is_pointer += 1
|
74
|
+
if @full_decl.scan(/^p\.(.+)/).flatten[0]
|
75
|
+
ffi_type_from(@full_decl.scan(/^p\.(.+)/).flatten[0])
|
76
|
+
elsif @full_decl == 'char' and @is_pointer == 2
|
77
|
+
':string'
|
78
|
+
else
|
79
|
+
':pointer'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
def array
|
84
|
+
if @declaration.is_array?
|
85
|
+
num = @full_decl.scan(/\w+\((\d+)\)/).flatten[0]
|
86
|
+
"[#{ffi_type_from(@full_decl.gsub!(/\w+\(\d+\)\./, ''))}, #{num}]"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
def struct
|
90
|
+
Struct.camelcase(@full_decl.scan(/^struct\s(\w+)/).flatten[0]) if @declaration.is_struct?
|
91
|
+
end
|
92
|
+
def union
|
93
|
+
Union.camelcase(@full_decl.scan(/^union\s(\w+)/).flatten[0]) if @declaration.is_union?
|
94
|
+
end
|
95
|
+
def enum
|
96
|
+
ffi_type_from(Generator::TYPES['int']) if @declaration.is_enum?
|
97
|
+
end
|
98
|
+
def callback
|
99
|
+
":#{@full_decl.scan(/^callback\s(\w+)/).flatten[0]}" if @declaration.is_callback?
|
100
|
+
end
|
101
|
+
def inline_callback
|
102
|
+
Callback.new(:node => @node, :inline => true, :typedefs => @typedefs).to_s if @declaration.is_inline_callback?
|
103
|
+
end
|
104
|
+
def typedef
|
105
|
+
ffi_type_from(@typedefs[@full_decl]) if @typedefs.has_key?(@full_decl)
|
106
|
+
end
|
107
|
+
def undefined(type)
|
108
|
+
"#{type}"
|
109
|
+
end
|
110
|
+
def ffi_type_from(full_decl)
|
111
|
+
@full_decl = full_decl
|
112
|
+
@declaration = Declaration.new(full_decl)
|
113
|
+
constant || \
|
114
|
+
volatile || \
|
115
|
+
typedef || \
|
116
|
+
pointer || \
|
117
|
+
enum || \
|
118
|
+
native || \
|
119
|
+
struct || \
|
120
|
+
union || \
|
121
|
+
array || \
|
122
|
+
inline_callback || \
|
123
|
+
callback || \
|
124
|
+
undefined(full_decl)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module FFI
|
2
|
+
module Generator
|
3
|
+
TYPES = {
|
4
|
+
'char' => ':char',
|
5
|
+
'double' => ':double',
|
6
|
+
'float' => ':float',
|
7
|
+
'unsigned long' => ':ulong',
|
8
|
+
'unsigned char' => ':uchar',
|
9
|
+
'signed char' => ':char',
|
10
|
+
'unsigned char' => ':uchar',
|
11
|
+
'short' => ':short',
|
12
|
+
'signed short' => ':short',
|
13
|
+
'signed short int' => ':short',
|
14
|
+
'unsigned short' => ':ushort',
|
15
|
+
'unsigned short int' => ':ushort',
|
16
|
+
'int' => ':int',
|
17
|
+
'signed int' => ':int',
|
18
|
+
'unsigned int' => ':uint',
|
19
|
+
'long' => ':long',
|
20
|
+
'long int' => ':long',
|
21
|
+
'signed long' => ':long',
|
22
|
+
'signed long int' => ':long',
|
23
|
+
'unsigned long' => ':ulong',
|
24
|
+
'unsigned long int' => ':ulong',
|
25
|
+
'long unsigned int' => ':ulong',
|
26
|
+
'long long' => ':long_long',
|
27
|
+
'long long int' => ':long_long',
|
28
|
+
'signed long long' => ':long_long',
|
29
|
+
'signed long long int' => ':long_long',
|
30
|
+
'size_t' => ':uint',
|
31
|
+
'unsigned long long' => ':ulong_long',
|
32
|
+
'unsigned long long int' => ':ulong_long',
|
33
|
+
'void' => ':void'
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
include FFI
|
3
|
+
|
4
|
+
describe Generator::Constant do
|
5
|
+
it_should_behave_like 'All specs'
|
6
|
+
before :all do
|
7
|
+
@node = generate_xml_wrap_from('constants')
|
8
|
+
end
|
9
|
+
it 'should return a ruby constant assignment' do
|
10
|
+
Generator::Constant.new(:node => (@node / 'constant')[0]).to_s.should == "CONST_1 = 0x10"
|
11
|
+
end
|
12
|
+
it 'should ignore constant qualifiers' do
|
13
|
+
Generator::Constant.new(:node => (@node / 'constant')[1]).to_s.should == "CONST_2 = 1234"
|
14
|
+
Generator::Constant.new(:node => (@node / 'constant')[2]).to_s.should == "CONST_3 = 1234"
|
15
|
+
Generator::Constant.new(:node => (@node / 'constant')[3]).to_s.should == "CONST_4 = 1234"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
include FFI
|
3
|
+
|
4
|
+
describe Generator::Enum do
|
5
|
+
it_should_behave_like 'All specs'
|
6
|
+
before :all do
|
7
|
+
@node = generate_xml_wrap_from('enums')
|
8
|
+
end
|
9
|
+
it 'should generate constants' do
|
10
|
+
Generator::Enum.new(:node => (@node / 'enum')[0]).to_s.should == <<EOE
|
11
|
+
ENUM_1 = 0
|
12
|
+
ENUM_2 = 1
|
13
|
+
ENUM_3 = 2
|
14
|
+
EOE
|
15
|
+
end
|
16
|
+
it 'should generate constants starting from the latest assignment' do
|
17
|
+
Generator::Enum.new(:node => (@node / 'enum')[1]).to_s.should == <<EOE
|
18
|
+
ENUM_21 = 2
|
19
|
+
ENUM_22 = 3
|
20
|
+
ENUM_23 = 4
|
21
|
+
EOE
|
22
|
+
Generator::Enum.new(:node => (@node / 'enum')[2]).to_s.should == <<EOE
|
23
|
+
ENUM_31 = 0
|
24
|
+
ENUM_32 = 5
|
25
|
+
ENUM_33 = 6
|
26
|
+
EOE
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
include FFI
|
3
|
+
|
4
|
+
describe Generator::Function do
|
5
|
+
it_should_behave_like 'All specs'
|
6
|
+
before :all do
|
7
|
+
@node = generate_xml_wrap_from('functions')
|
8
|
+
end
|
9
|
+
it 'should return a properly generated attach_method' do
|
10
|
+
Generator::Function.new(:node => (@node / 'cdecl')[0]).to_s.should == "attach_function :func_1, [ :char, :int ], :int"
|
11
|
+
end
|
12
|
+
it 'should properly generate pointer arguments' do
|
13
|
+
Generator::Function.new(:node => (@node / 'cdecl')[1]).to_s.should == "attach_function :func_2, [ :pointer, :pointer, :pointer ], :uint"
|
14
|
+
end
|
15
|
+
it 'should properly generate string arguments' do
|
16
|
+
Generator::Function.new(:node => (@node / 'cdecl')[2]).to_s.should == "attach_function :func_3, [ :string ], :void"
|
17
|
+
end
|
18
|
+
it 'should properly generate string return type' do
|
19
|
+
Generator::Function.new(:node => (@node / 'cdecl')[3]).to_s.should == "attach_function :func_4, [ :int ], :string"
|
20
|
+
end
|
21
|
+
it 'should generate string type only in case of pointer of type char (char *)' do
|
22
|
+
Generator::Function.new(:node => (@node / 'cdecl')[17]).to_s.should == "attach_function :func_17, [ ], :pointer"
|
23
|
+
end
|
24
|
+
it 'should properly generate void return type' do
|
25
|
+
Generator::Function.new(:node => (@node / 'cdecl')[4]).to_s.should == "attach_function :func_5, [ ], :void"
|
26
|
+
end
|
27
|
+
it 'should properly generate pointer of pointer arguments' do
|
28
|
+
Generator::Function.new(:node => (@node / 'cdecl')[5]).to_s.should == "attach_function :func_6, [ :pointer ], :void"
|
29
|
+
end
|
30
|
+
it 'should properly generate enum arguments' do
|
31
|
+
Generator::Function.new(:node => (@node / 'cdecl')[6]).to_s.should == "attach_function :func_7, [ :int ], :void"
|
32
|
+
end
|
33
|
+
it 'should properly generate enum return type' do
|
34
|
+
Generator::Function.new(:node => (@node / 'cdecl')[7]).to_s.should == "attach_function :func_8, [ ], :int"
|
35
|
+
end
|
36
|
+
it 'should properly generate struct arguments' do
|
37
|
+
Generator::Function.new(:node => (@node / 'cdecl')[9]).to_s.should == "attach_function :func_9, [ TestStruct ], :void"
|
38
|
+
end
|
39
|
+
it 'should properly generate struct return type' do
|
40
|
+
Generator::Function.new(:node => (@node / 'cdecl')[10]).to_s.should == "attach_function :func_10, [ ], TestStruct"
|
41
|
+
end
|
42
|
+
it 'should properly generate a function with no parameters' do
|
43
|
+
Generator::Function.new(:node => (@node / 'cdecl')[11]).to_s.should == "attach_function :func_11, [ ], :void"
|
44
|
+
end
|
45
|
+
it 'should properly generate a function that takes a callback as argument' do
|
46
|
+
Generator::Function.new(:node => (@node / 'cdecl')[12]).to_s.should == "attach_function :func_12, [ callback([ :float ], :void) ], :void"
|
47
|
+
Generator::Function.new(:node => (@node / 'cdecl')[13]).to_s.should == "attach_function :func_13, [ callback([ :double, :float ], :int) ], :void"
|
48
|
+
Generator::Function.new(:node => (@node / 'cdecl')[14]).to_s.should == "attach_function :func_14, [ callback([ :string ], :void) ], :void"
|
49
|
+
Generator::Function.new(:node => (@node / 'cdecl')[15]).to_s.should == "attach_function :func_15, [ callback([ ], :void) ], :void"
|
50
|
+
end
|
51
|
+
it 'should handle const qualifier return type' do
|
52
|
+
Generator::Function.new(:node => (@node / 'cdecl')[16]).to_s.should == "attach_function :func_16, [ ], :string"
|
53
|
+
end
|
54
|
+
it 'should generate a function with variadic args' do
|
55
|
+
Generator::Function.new(:node => (@node / 'cdecl')[18]).to_s.should == "attach_function :func_18, [ :varargs ], :void"
|
56
|
+
end
|
57
|
+
it 'should generate a function with volatile args' do
|
58
|
+
Generator::Function.new(:node => (@node / 'cdecl')[19]).to_s.should == "attach_function :func_19, [ :int ], :void"
|
59
|
+
end
|
60
|
+
it 'should properly generate func_20' do
|
61
|
+
Generator::Function.new(:node => (@node / 'cdecl')[20]).to_s.should == "attach_function :func_20, [ :pointer, callback([ :string, :pointer, :pointer ], :void), :pointer ], :void"
|
62
|
+
end
|
63
|
+
it 'should properly generate func_20' do
|
64
|
+
Generator::Function.new(:node => (@node / 'cdecl')[21]).to_s.should == "attach_function :func_21, [ :pointer, callback([ :uchar, :pointer, :pointer ], :void), :pointer ], :void"
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
|
3
|
+
include FFI
|
4
|
+
|
5
|
+
describe Generator::Parser do
|
6
|
+
it_should_behave_like 'All specs'
|
7
|
+
before do
|
8
|
+
@node = generate_xml_wrap_from('testlib')
|
9
|
+
end
|
10
|
+
it 'should generate ruby ffi wrap code' do
|
11
|
+
Generator::Parser.new.generate(@node).should == <<EOC
|
12
|
+
|
13
|
+
module TestLib
|
14
|
+
extend FFI::Library
|
15
|
+
CONST_1 = 0x10
|
16
|
+
CONST_2 = 0x20
|
17
|
+
ENUM_1 = 0
|
18
|
+
ENUM_2 = 1
|
19
|
+
ENUM_3 = 2
|
20
|
+
|
21
|
+
class UnionT < FFI::Union
|
22
|
+
layout(
|
23
|
+
:c, :char,
|
24
|
+
:f, :float
|
25
|
+
)
|
26
|
+
end
|
27
|
+
class TestStruct < FFI::Struct
|
28
|
+
layout(
|
29
|
+
:i, :int,
|
30
|
+
:c, :char,
|
31
|
+
:b, :uchar
|
32
|
+
)
|
33
|
+
end
|
34
|
+
class CamelCaseStruct < FFI::Struct
|
35
|
+
layout(
|
36
|
+
:i, :int,
|
37
|
+
:c, :char,
|
38
|
+
:b, :uchar
|
39
|
+
)
|
40
|
+
end
|
41
|
+
class TestStruct3 < FFI::Struct
|
42
|
+
layout(
|
43
|
+
:c, :char
|
44
|
+
)
|
45
|
+
end
|
46
|
+
callback(:cb, [ :string, :string ], :void)
|
47
|
+
callback(:cb_2, [ :string, :string ], :pointer)
|
48
|
+
callback(:cb_3, [ :string, CamelCaseStruct ], CamelCaseStruct)
|
49
|
+
class TestStruct2 < FFI::Struct
|
50
|
+
layout(
|
51
|
+
:s, TestStruct,
|
52
|
+
:camel_case_struct, CamelCaseStruct,
|
53
|
+
:s_3, TestStruct3,
|
54
|
+
:e, :int,
|
55
|
+
:func, :cb,
|
56
|
+
:u, UnionT,
|
57
|
+
:callback, :cb,
|
58
|
+
:inline_callback, callback([ ], :void)
|
59
|
+
)
|
60
|
+
def func=(cb)
|
61
|
+
@func = cb
|
62
|
+
self[:func] = @func
|
63
|
+
end
|
64
|
+
def func
|
65
|
+
@func
|
66
|
+
end
|
67
|
+
def callback=(cb)
|
68
|
+
@callback = cb
|
69
|
+
self[:callback] = @callback
|
70
|
+
end
|
71
|
+
def callback
|
72
|
+
@callback
|
73
|
+
end
|
74
|
+
def inline_callback=(cb)
|
75
|
+
@inline_callback = cb
|
76
|
+
self[:inline_callback] = @inline_callback
|
77
|
+
end
|
78
|
+
def inline_callback
|
79
|
+
@inline_callback
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
class TestStruct4 < FFI::Struct
|
84
|
+
layout(
|
85
|
+
:string, :pointer,
|
86
|
+
:inline_callback, callback([ ], :void)
|
87
|
+
)
|
88
|
+
def string=(str)
|
89
|
+
@string = FFI::MemoryPointer.from_string(str)
|
90
|
+
self[:string] = @string
|
91
|
+
end
|
92
|
+
def string
|
93
|
+
@string.get_string(0)
|
94
|
+
end
|
95
|
+
def inline_callback=(cb)
|
96
|
+
@inline_callback = cb
|
97
|
+
self[:inline_callback] = @inline_callback
|
98
|
+
end
|
99
|
+
def inline_callback
|
100
|
+
@inline_callback
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
class TestStruct5BigUnionFieldNestedStructField1 < FFI::Struct
|
105
|
+
layout(
|
106
|
+
:a, :int,
|
107
|
+
:b, :int
|
108
|
+
)
|
109
|
+
end
|
110
|
+
class TestStruct5BigUnionFieldNestedStructField2 < FFI::Struct
|
111
|
+
layout(
|
112
|
+
:c, :int,
|
113
|
+
:d, :int
|
114
|
+
)
|
115
|
+
end
|
116
|
+
class TestStruct5BigUnionFieldNestedStructField3 < FFI::Struct
|
117
|
+
layout(
|
118
|
+
:e, :int,
|
119
|
+
:f, :int
|
120
|
+
)
|
121
|
+
end
|
122
|
+
class TestStruct5BigUnionFieldUnionField < FFI::Union
|
123
|
+
layout(
|
124
|
+
:l, :long,
|
125
|
+
:ll, :long_long
|
126
|
+
)
|
127
|
+
end
|
128
|
+
# FIXME: Nested structures are not correctly supported at the moment.
|
129
|
+
# Please check the order of the declarations in the structure below.
|
130
|
+
# class TestStruct5BigUnionField < FFI::Union
|
131
|
+
# layout(
|
132
|
+
# :f, :float,
|
133
|
+
# :union_field, TestStruct5BigUnionFieldUnionField,
|
134
|
+
# :nested_struct_field_3, TestStruct5BigUnionFieldNestedStructField3,
|
135
|
+
# :nested_struct_field_2, TestStruct5BigUnionFieldNestedStructField2,
|
136
|
+
# :nested_struct_field_1, TestStruct5BigUnionFieldNestedStructField1
|
137
|
+
# )
|
138
|
+
# end
|
139
|
+
# FIXME: Nested structures are not correctly supported at the moment.
|
140
|
+
# Please check the order of the declarations in the structure below.
|
141
|
+
# class TestStruct5 < FFI::Struct
|
142
|
+
# layout(
|
143
|
+
# :i, :int,
|
144
|
+
# :c, :char,
|
145
|
+
# :big_union_field, TestStruct5BigUnionField
|
146
|
+
# )
|
147
|
+
# end
|
148
|
+
attach_function :get_int, [ :pointer ], :int
|
149
|
+
attach_function :get_char, [ :pointer ], :char
|
150
|
+
attach_function :func_with_enum, [ :int ], :int
|
151
|
+
attach_function :func_with_enum_2, [ :int ], :int
|
152
|
+
attach_function :func_with_typedef, [ ], :uchar
|
153
|
+
|
154
|
+
end
|
155
|
+
EOC
|
156
|
+
end
|
157
|
+
it 'should ignore given declarations' do
|
158
|
+
parser = Generator::Parser.new
|
159
|
+
parser.ignore 'CONST_1', 'e_1', 'test_struct', 'test_struct_5'
|
160
|
+
parser.ignore 'func_with_enum_2'
|
161
|
+
parser.generate(@node).should == <<EOC
|
162
|
+
|
163
|
+
module TestLib
|
164
|
+
extend FFI::Library
|
165
|
+
CONST_2 = 0x20
|
166
|
+
class UnionT < FFI::Union
|
167
|
+
layout(
|
168
|
+
:c, :char,
|
169
|
+
:f, :float
|
170
|
+
)
|
171
|
+
end
|
172
|
+
class CamelCaseStruct < FFI::Struct
|
173
|
+
layout(
|
174
|
+
:i, :int,
|
175
|
+
:c, :char,
|
176
|
+
:b, :uchar
|
177
|
+
)
|
178
|
+
end
|
179
|
+
class TestStruct3 < FFI::Struct
|
180
|
+
layout(
|
181
|
+
:c, :char
|
182
|
+
)
|
183
|
+
end
|
184
|
+
callback(:cb, [ :string, :string ], :void)
|
185
|
+
callback(:cb_2, [ :string, :string ], :pointer)
|
186
|
+
callback(:cb_3, [ :string, CamelCaseStruct ], CamelCaseStruct)
|
187
|
+
class TestStruct2 < FFI::Struct
|
188
|
+
layout(
|
189
|
+
:s, TestStruct,
|
190
|
+
:camel_case_struct, CamelCaseStruct,
|
191
|
+
:s_3, TestStruct3,
|
192
|
+
:e, :int,
|
193
|
+
:func, :cb,
|
194
|
+
:u, UnionT,
|
195
|
+
:callback, :cb,
|
196
|
+
:inline_callback, callback([ ], :void)
|
197
|
+
)
|
198
|
+
def func=(cb)
|
199
|
+
@func = cb
|
200
|
+
self[:func] = @func
|
201
|
+
end
|
202
|
+
def func
|
203
|
+
@func
|
204
|
+
end
|
205
|
+
def callback=(cb)
|
206
|
+
@callback = cb
|
207
|
+
self[:callback] = @callback
|
208
|
+
end
|
209
|
+
def callback
|
210
|
+
@callback
|
211
|
+
end
|
212
|
+
def inline_callback=(cb)
|
213
|
+
@inline_callback = cb
|
214
|
+
self[:inline_callback] = @inline_callback
|
215
|
+
end
|
216
|
+
def inline_callback
|
217
|
+
@inline_callback
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
class TestStruct4 < FFI::Struct
|
222
|
+
layout(
|
223
|
+
:string, :pointer,
|
224
|
+
:inline_callback, callback([ ], :void)
|
225
|
+
)
|
226
|
+
def string=(str)
|
227
|
+
@string = FFI::MemoryPointer.from_string(str)
|
228
|
+
self[:string] = @string
|
229
|
+
end
|
230
|
+
def string
|
231
|
+
@string.get_string(0)
|
232
|
+
end
|
233
|
+
def inline_callback=(cb)
|
234
|
+
@inline_callback = cb
|
235
|
+
self[:inline_callback] = @inline_callback
|
236
|
+
end
|
237
|
+
def inline_callback
|
238
|
+
@inline_callback
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
attach_function :get_int, [ :pointer ], :int
|
243
|
+
attach_function :get_char, [ :pointer ], :char
|
244
|
+
attach_function :func_with_enum, [ :int ], :int
|
245
|
+
attach_function :func_with_typedef, [ ], :uchar
|
246
|
+
|
247
|
+
end
|
248
|
+
EOC
|
249
|
+
end
|
250
|
+
end
|