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,77 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
|
3
|
+
include FFI
|
4
|
+
|
5
|
+
describe Generator::Struct do
|
6
|
+
it_should_behave_like 'All specs'
|
7
|
+
before :all do
|
8
|
+
@node = generate_xml_wrap_from('structs')
|
9
|
+
end
|
10
|
+
it 'should properly generate the layout of a FFI::Struct class' do
|
11
|
+
Generator::Struct.new(:node => (@node / 'class')[0]).to_s.should == <<EOC
|
12
|
+
class TestStruct1 < FFI::Struct
|
13
|
+
layout(
|
14
|
+
:i, :int,
|
15
|
+
:c, :char,
|
16
|
+
:s, :pointer,
|
17
|
+
:a, [:char, 5]
|
18
|
+
)
|
19
|
+
def s=(str)
|
20
|
+
@s = FFI::MemoryPointer.from_string(str)
|
21
|
+
self[:s] = @s
|
22
|
+
end
|
23
|
+
def s
|
24
|
+
@s.get_string(0)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
EOC
|
29
|
+
|
30
|
+
end
|
31
|
+
it 'should properly generate the layout of a FFI::Struct containing pointer field' do
|
32
|
+
Generator::Struct.new(:node => (@node / 'class')[1]).to_s.should == <<EOC
|
33
|
+
class TestStruct2 < FFI::Struct
|
34
|
+
layout(
|
35
|
+
:ptr, :pointer
|
36
|
+
)
|
37
|
+
end
|
38
|
+
EOC
|
39
|
+
end
|
40
|
+
it 'should properly generate the layout of a FFI::Struct containing array field' do
|
41
|
+
Generator::Struct.new(:node => (@node / 'class')[2]).to_s.should == <<EOC
|
42
|
+
class TestStruct3 < FFI::Struct
|
43
|
+
layout(
|
44
|
+
:c, [:char, 5]
|
45
|
+
)
|
46
|
+
end
|
47
|
+
EOC
|
48
|
+
|
49
|
+
end
|
50
|
+
it 'should properly generate the layout of a FFI::Struct containing array field' do
|
51
|
+
Generator::Struct.new(:node => (@node / 'class')[3]).to_s.should == <<EOC
|
52
|
+
class TestStruct4 < FFI::Struct
|
53
|
+
layout(
|
54
|
+
:s, [TestStruct3, 5]
|
55
|
+
)
|
56
|
+
end
|
57
|
+
EOC
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe Generator::Union do
|
63
|
+
it_should_behave_like 'All specs'
|
64
|
+
before :all do
|
65
|
+
@node = generate_xml_wrap_from('unions')
|
66
|
+
end
|
67
|
+
it 'should properly generate the layout of a FFI::Union class' do
|
68
|
+
Generator::Union.new(:node => (@node / 'class')[0]).to_s.should == <<EOC
|
69
|
+
class UnionT < FFI::Union
|
70
|
+
layout(
|
71
|
+
:c, :char,
|
72
|
+
:f, :float
|
73
|
+
)
|
74
|
+
end
|
75
|
+
EOC
|
76
|
+
end
|
77
|
+
end
|
@@ -19,6 +19,14 @@ void func_12(void (*callback)(float));
|
|
19
19
|
void func_13(int (*callback)(double, float));
|
20
20
|
void func_14(void (*callback)(char* str));
|
21
21
|
void func_15(void (*callback)(void));
|
22
|
+
const char* func_16();
|
23
|
+
const unsigned char * func_17();
|
24
|
+
void func_18(...);
|
25
|
+
volatile void func_19(volatile int value);
|
26
|
+
void func_20(void *p1, void (*callback)(const char* str, void *p2, void *p3 ), void *p4);
|
27
|
+
void func_21(void *p1, void (*callback)(const unsigned char uc, void *p2, void *p3 ), void *p4);
|
28
|
+
|
29
|
+
|
22
30
|
|
23
31
|
|
24
32
|
|
@@ -24,18 +24,60 @@ struct test_struct {
|
|
24
24
|
byte b;
|
25
25
|
};
|
26
26
|
|
27
|
+
struct CamelCaseStruct {
|
28
|
+
int i;
|
29
|
+
char c;
|
30
|
+
byte b;
|
31
|
+
};
|
32
|
+
|
27
33
|
typedef struct {
|
28
34
|
char c;
|
29
35
|
} test_struct_3;
|
30
36
|
|
31
37
|
typedef void (*cb)(char*, char*);
|
38
|
+
typedef void * (*cb_2)(char*, const char *);
|
39
|
+
typedef CamelCaseStruct (*cb_3)(char*, CamelCaseStruct);
|
32
40
|
|
33
41
|
struct test_struct_2 {
|
34
42
|
struct test_struct s;
|
43
|
+
CamelCaseStruct camel_case_struct;
|
35
44
|
test_struct_3 s_3;
|
36
45
|
enum_t e;
|
37
46
|
cb func;
|
38
47
|
union_t u;
|
48
|
+
cb callback;
|
49
|
+
void (*inline_callback)();
|
50
|
+
};
|
51
|
+
|
52
|
+
// struct with getter/setter method for strings and callbacks
|
53
|
+
|
54
|
+
struct _test_struct_4 {
|
55
|
+
char* string;
|
56
|
+
void (*inline_callback)();
|
57
|
+
};
|
58
|
+
|
59
|
+
struct test_struct_5 {
|
60
|
+
int i;
|
61
|
+
union {
|
62
|
+
struct {
|
63
|
+
int a;
|
64
|
+
int b;
|
65
|
+
} nested_struct_field_1;
|
66
|
+
struct {
|
67
|
+
int c;
|
68
|
+
int d;
|
69
|
+
} nested_struct_field_2;
|
70
|
+
struct {
|
71
|
+
int e;
|
72
|
+
int f;
|
73
|
+
} nested_struct_field_3;
|
74
|
+
union {
|
75
|
+
long l;
|
76
|
+
long long ll;
|
77
|
+
} union_field;
|
78
|
+
float f;
|
79
|
+
} big_union_field;
|
80
|
+
char c;
|
39
81
|
};
|
40
82
|
|
41
83
|
int get_int(struct test_struct* s);
|
data/spec/generator/swig/types.i
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. spec_helper])
|
2
|
+
include FFI
|
3
|
+
|
4
|
+
describe Generator::Type do
|
5
|
+
it_should_behave_like 'All specs'
|
6
|
+
before :all do
|
7
|
+
@node = generate_xml_wrap_from('types')
|
8
|
+
end
|
9
|
+
it 'should generate string type' do
|
10
|
+
Generator::Type.new(:node => (@node / 'cdecl')[0]).to_s.should == ':string'
|
11
|
+
end
|
12
|
+
it 'should generate pointer type' do
|
13
|
+
Generator::Type.new(:node => (@node / 'cdecl')[1]).to_s.should == ':pointer'
|
14
|
+
Generator::Type.new(:node => (@node / 'cdecl')[2]).to_s.should == ':pointer'
|
15
|
+
end
|
16
|
+
it 'should generate array type' do
|
17
|
+
Generator::Type.new(:node => (@node / 'cdecl')[3]).to_s.should == '[:int, 5]'
|
18
|
+
Generator::Type.new(:node => (@node / 'cdecl')[4]).to_s.should == '[:string, 5]'
|
19
|
+
end
|
20
|
+
it 'should generate struct type' do
|
21
|
+
Generator::Type.new(:node => (@node / 'cdecl')[6]).to_s.should == 'TestStruct'
|
22
|
+
end
|
23
|
+
it 'should generate struct array type' do
|
24
|
+
Generator::Type.new(:node => (@node / 'cdecl')[7]).to_s.should == '[TestStruct, 5]'
|
25
|
+
end
|
26
|
+
it 'should generate enum array type' do
|
27
|
+
Generator::Type.new(:node => (@node / 'cdecl')[8]).to_s.should == '[:int, 5]'
|
28
|
+
end
|
29
|
+
it 'should generate const type' do
|
30
|
+
Generator::Type.new(:node => (@node / 'cdecl')[9]).to_s.should == ':int'
|
31
|
+
Generator::Type.new(:node => (@node / 'cdecl')[10]).to_s.should == ':string'
|
32
|
+
end
|
33
|
+
Generator::TYPES.sort.each_with_index do |type, i|
|
34
|
+
it "should generate #{type[0]} type" do
|
35
|
+
Generator::Type.new(:node => (@node / 'cdecl')[i + 11]).to_s.should == type[1]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/tasks/cucumber.rake
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi-swig-generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrea Fazzi
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-04-20 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,17 +32,7 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.1.1
|
34
34
|
version:
|
35
|
-
-
|
36
|
-
name: bones
|
37
|
-
type: :development
|
38
|
-
version_requirement:
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: 2.4.0
|
44
|
-
version:
|
45
|
-
description: ffi-swig-generator is a ruby-ffi wrapper code generator based on SWIG interface files. ffi-swig-generator is able to traverse a XML parse tree file generated by the +swig+ command and to produce a ruby-ffi interface file from it. ffi-swig-generator is shipped with a command line tool (ffi-gen) and a rake task that automates the code generation process. ffi-swig-generator XML capabilities are provided by nokogiri.
|
35
|
+
description: ffi-swig-generator is a ruby-ffi wrapper code generator that produce ruby-ffi glue code parsing C header files through SWIG. ffi-swig-generator is able to traverse an XML parse tree generated by the +swig+ command and to produce a ruby-ffi code from it. ffi-swig-generator is shipped with a command line tool and a rake task that automates the code generation process. ffi-swig-generator XML capabilities are provided by nokogiri.
|
46
36
|
email: andrea.fazzi@alcacoop.it
|
47
37
|
executables:
|
48
38
|
- ffi-gen
|
@@ -55,22 +45,40 @@ extra_rdoc_files:
|
|
55
45
|
files:
|
56
46
|
- .hg/00changelog.i
|
57
47
|
- .hg/branch
|
48
|
+
- .hg/branch.cache
|
58
49
|
- .hg/dirstate
|
59
50
|
- .hg/hgrc
|
60
51
|
- .hg/requires
|
61
52
|
- .hg/store/00changelog.i
|
62
53
|
- .hg/store/00manifest.i
|
54
|
+
- .hg/store/data/.hgignore.i
|
55
|
+
- .hg/store/data/.hgtags.i
|
63
56
|
- .hg/store/data/_history.txt.i
|
64
57
|
- .hg/store/data/_r_e_a_d_m_e.rdoc.i
|
65
58
|
- .hg/store/data/_rakefile.i
|
66
59
|
- .hg/store/data/bin/ffi-gen.i
|
60
|
+
- .hg/store/data/cucumber.yml.i
|
67
61
|
- .hg/store/data/examples/_rakefile.i
|
68
62
|
- .hg/store/data/examples/interfaces/libc.i.i
|
69
63
|
- .hg/store/data/examples/interfaces/wiiuse.i.i
|
64
|
+
- .hg/store/data/features/generate.feature.i
|
65
|
+
- .hg/store/data/features/step__definitions/generate.rb.i
|
66
|
+
- .hg/store/data/features/support/env.rb.i
|
67
|
+
- .hg/store/data/features/support/results.rb.i
|
68
|
+
- .hg/store/data/features/support/templates.rb.i
|
70
69
|
- .hg/store/data/lib/ffi-swig-generator.rb.i
|
71
70
|
- .hg/store/data/lib/generator/application.rb.i
|
71
|
+
- .hg/store/data/lib/generator/constant.rb.i
|
72
|
+
- .hg/store/data/lib/generator/enum.rb.i
|
73
|
+
- .hg/store/data/lib/generator/function.rb.i
|
72
74
|
- .hg/store/data/lib/generator/generator.rb.i
|
73
75
|
- .hg/store/data/lib/generator/generatortask.rb.i
|
76
|
+
- .hg/store/data/lib/generator/logger.rb.i
|
77
|
+
- .hg/store/data/lib/generator/node.rb.i
|
78
|
+
- .hg/store/data/lib/generator/parser.rb.i
|
79
|
+
- .hg/store/data/lib/generator/struct.rb.i
|
80
|
+
- .hg/store/data/lib/generator/type.rb.i
|
81
|
+
- .hg/store/data/lib/generator/types.rb.i
|
74
82
|
- .hg/store/data/pkg/ffi-swig-generator-0.2.1.gem.i
|
75
83
|
- .hg/store/data/pkg/ffi-swig-generator-0.2.1.tgz.i
|
76
84
|
- .hg/store/data/pkg/ffi-swig-generator-0.2.1/.gitignore.i
|
@@ -111,7 +119,13 @@ files:
|
|
111
119
|
- .hg/store/data/pkg/ffi-swig-generator-0.2.1/tasks/svn.rake.i
|
112
120
|
- .hg/store/data/pkg/ffi-swig-generator-0.2.1/tasks/test.rake.i
|
113
121
|
- .hg/store/data/spec/ffi-swig-generator__spec.rb.i
|
122
|
+
- .hg/store/data/spec/generator/constant__spec.rb.i
|
123
|
+
- .hg/store/data/spec/generator/enum__spec.rb.i
|
124
|
+
- .hg/store/data/spec/generator/function__spec.rb.i
|
114
125
|
- .hg/store/data/spec/generator/generator__spec.rb.i
|
126
|
+
- .hg/store/data/spec/generator/node__spec.rb.i
|
127
|
+
- .hg/store/data/spec/generator/parser__spec.rb.i
|
128
|
+
- .hg/store/data/spec/generator/struct__spec.rb.i
|
115
129
|
- .hg/store/data/spec/generator/swig/constants.i.i
|
116
130
|
- .hg/store/data/spec/generator/swig/enums.i.i
|
117
131
|
- .hg/store/data/spec/generator/swig/functions.i.i
|
@@ -120,10 +134,12 @@ files:
|
|
120
134
|
- .hg/store/data/spec/generator/swig/typedefs.i.i
|
121
135
|
- .hg/store/data/spec/generator/swig/types.i.i
|
122
136
|
- .hg/store/data/spec/generator/swig/unions.i.i
|
137
|
+
- .hg/store/data/spec/generator/type__spec.rb.i
|
123
138
|
- .hg/store/data/spec/spec.opts.i
|
124
139
|
- .hg/store/data/spec/spec__helper.rb.i
|
125
140
|
- .hg/store/data/tasks/ann.rake.i
|
126
141
|
- .hg/store/data/tasks/bones.rake.i
|
142
|
+
- .hg/store/data/tasks/cucumber.rake.i
|
127
143
|
- .hg/store/data/tasks/gem.rake.i
|
128
144
|
- .hg/store/data/tasks/git.rake.i
|
129
145
|
- .hg/store/data/tasks/notes.rake.i
|
@@ -138,19 +154,41 @@ files:
|
|
138
154
|
- .hg/undo.branch
|
139
155
|
- .hg/undo.dirstate
|
140
156
|
- .hgignore
|
157
|
+
- .hgtags
|
141
158
|
- History.txt
|
142
159
|
- README.rdoc
|
143
160
|
- Rakefile
|
144
161
|
- bin/ffi-gen
|
162
|
+
- cucumber.yml
|
145
163
|
- examples/Rakefile
|
164
|
+
- examples/generated/libc_wrap.rb
|
165
|
+
- examples/generated/libc_wrap.xml
|
166
|
+
- examples/generated/wiiuse_wrap.rb
|
167
|
+
- examples/generated/wiiuse_wrap.xml
|
146
168
|
- examples/interfaces/libc.i
|
147
169
|
- examples/interfaces/wiiuse.i
|
170
|
+
- features/generate.feature
|
171
|
+
- features/step_definitions/generate.rb
|
172
|
+
- features/support/env.rb
|
173
|
+
- features/support/templates.rb
|
148
174
|
- lib/ffi-swig-generator.rb
|
149
175
|
- lib/generator/application.rb
|
150
|
-
- lib/generator/
|
176
|
+
- lib/generator/constant.rb
|
177
|
+
- lib/generator/enum.rb
|
178
|
+
- lib/generator/function.rb
|
151
179
|
- lib/generator/generatortask.rb
|
180
|
+
- lib/generator/logger.rb
|
181
|
+
- lib/generator/node.rb
|
182
|
+
- lib/generator/parser.rb
|
183
|
+
- lib/generator/struct.rb
|
184
|
+
- lib/generator/type.rb
|
185
|
+
- lib/generator/types.rb
|
152
186
|
- spec/ffi-swig-generator_spec.rb
|
153
|
-
- spec/generator/
|
187
|
+
- spec/generator/constant_spec.rb
|
188
|
+
- spec/generator/enum_spec.rb
|
189
|
+
- spec/generator/function_spec.rb
|
190
|
+
- spec/generator/parser_spec.rb
|
191
|
+
- spec/generator/struct_spec.rb
|
154
192
|
- spec/generator/swig/constants.i
|
155
193
|
- spec/generator/swig/enums.i
|
156
194
|
- spec/generator/swig/functions.i
|
@@ -159,10 +197,12 @@ files:
|
|
159
197
|
- spec/generator/swig/typedefs.i
|
160
198
|
- spec/generator/swig/types.i
|
161
199
|
- spec/generator/swig/unions.i
|
200
|
+
- spec/generator/type_spec.rb
|
162
201
|
- spec/spec.opts
|
163
202
|
- spec/spec_helper.rb
|
164
203
|
- tasks/ann.rake
|
165
204
|
- tasks/bones.rake
|
205
|
+
- tasks/cucumber.rake
|
166
206
|
- tasks/gem.rake
|
167
207
|
- tasks/git.rake
|
168
208
|
- tasks/notes.rake
|
@@ -174,7 +214,7 @@ files:
|
|
174
214
|
- tasks/svn.rake
|
175
215
|
- tasks/test.rake
|
176
216
|
has_rdoc: true
|
177
|
-
homepage: http://kenai.com/projects/ruby-ffi
|
217
|
+
homepage: http://kenai.com/projects/ruby-ffi/sources/swig-generator/show
|
178
218
|
post_install_message:
|
179
219
|
rdoc_options:
|
180
220
|
- --main
|
@@ -196,9 +236,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
236
|
requirements: []
|
197
237
|
|
198
238
|
rubyforge_project: ffi-swig-gen
|
199
|
-
rubygems_version: 1.3.
|
239
|
+
rubygems_version: 1.3.1
|
200
240
|
signing_key:
|
201
241
|
specification_version: 2
|
202
|
-
summary: ffi-swig-generator is a ruby-ffi wrapper code generator
|
242
|
+
summary: ffi-swig-generator is a ruby-ffi wrapper code generator that produce ruby-ffi glue code parsing C header files through SWIG
|
203
243
|
test_files: []
|
204
244
|
|
data/lib/generator/generator.rb
DELETED
@@ -1,344 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'nokogiri'
|
3
|
-
|
4
|
-
module FFI
|
5
|
-
module Generator
|
6
|
-
@typedefs = {}
|
7
|
-
TYPES = {
|
8
|
-
'char' => ':char',
|
9
|
-
'double' => ':double',
|
10
|
-
'float' => ':float',
|
11
|
-
'unsigned long' => ':ulong',
|
12
|
-
'unsigned char' => ':uchar',
|
13
|
-
'signed char' => ':char',
|
14
|
-
'unsigned char' => ':uchar',
|
15
|
-
'short' => ':short',
|
16
|
-
'signed short' => ':short',
|
17
|
-
'signed short int' => ':short',
|
18
|
-
'unsigned short' => ':ushort',
|
19
|
-
'unsigned short int' => ':ushort',
|
20
|
-
'int' => ':int',
|
21
|
-
'signed int' => ':int',
|
22
|
-
'unsigned int' => ':uint',
|
23
|
-
'long' => ':long',
|
24
|
-
'long int' => ':long',
|
25
|
-
'signed long' => ':long',
|
26
|
-
'signed long int' => ':long',
|
27
|
-
'unsigned long' => ':ulong',
|
28
|
-
'unsigned long int' => ':ulong',
|
29
|
-
'long unsigned int' => ':ulong',
|
30
|
-
'long long' => ':long_long',
|
31
|
-
'long long int' => ':long_long',
|
32
|
-
'signed long long' => ':long_long',
|
33
|
-
'signed long long int' => ':long_long',
|
34
|
-
'unsigned long long' => ':ulong_long',
|
35
|
-
'unsigned long long int' => ':ulong_long',
|
36
|
-
'void' => ':void'
|
37
|
-
}
|
38
|
-
class << self
|
39
|
-
attr_reader :typedefs
|
40
|
-
def add_type(ctype, rtype)
|
41
|
-
@typedefs[ctype] = rtype
|
42
|
-
end
|
43
|
-
end
|
44
|
-
class Node
|
45
|
-
attr_reader :symname
|
46
|
-
def initialize(params = { })
|
47
|
-
params = { :indent => 0 }.merge(params)
|
48
|
-
@node, @indent = params[:node], params[:indent]
|
49
|
-
@indent_str = ' ' * @indent
|
50
|
-
@symname = get_attr('name')
|
51
|
-
end
|
52
|
-
def get_attr(name)
|
53
|
-
if @node
|
54
|
-
attr = (@node / "./attributelist/attribute[@name='#{name}']").first
|
55
|
-
attr['value'] if attr
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
class Type < Node
|
60
|
-
def initialize(params = { })
|
61
|
-
super
|
62
|
-
@statement = params[:statement] || get_statement
|
63
|
-
end
|
64
|
-
def to_s
|
65
|
-
get_type
|
66
|
-
end
|
67
|
-
private
|
68
|
-
def get_statement
|
69
|
-
get_attr('decl').to_s + get_attr('type').to_s if @node
|
70
|
-
end
|
71
|
-
def is_native?
|
72
|
-
Generator::TYPES.has_key?(@statement)
|
73
|
-
end
|
74
|
-
def is_pointer?
|
75
|
-
@statement[/^p\./] and not is_callback?
|
76
|
-
end
|
77
|
-
def is_enum?
|
78
|
-
@statement[/^enum/]
|
79
|
-
end
|
80
|
-
def is_array?
|
81
|
-
@statement and @statement[/\w+\(\d+\)/]
|
82
|
-
end
|
83
|
-
def is_struct?
|
84
|
-
@statement[/^struct/]
|
85
|
-
end
|
86
|
-
def is_union?
|
87
|
-
@statement[/^union/]
|
88
|
-
end
|
89
|
-
def is_constant?
|
90
|
-
@statement[/^q\(const\)/]
|
91
|
-
end
|
92
|
-
def is_callback?
|
93
|
-
@statement[/^p.f\(/]
|
94
|
-
end
|
95
|
-
def native
|
96
|
-
if is_native?
|
97
|
-
@statement = Generator::TYPES[@statement]
|
98
|
-
get_type
|
99
|
-
end
|
100
|
-
end
|
101
|
-
def constant
|
102
|
-
if is_constant?
|
103
|
-
@statement = @statement.scan(/^q\(const\)\.(.+)/).flatten[0]
|
104
|
-
get_type
|
105
|
-
end
|
106
|
-
end
|
107
|
-
def pointer
|
108
|
-
if is_pointer?
|
109
|
-
if @statement[/char/] and @statement.scan(/p\./).size == 1
|
110
|
-
@statement = ':string'
|
111
|
-
# @decl.gsub!(/p\./, '')
|
112
|
-
get_type
|
113
|
-
else
|
114
|
-
return ':pointer'
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
def array
|
119
|
-
if is_array?
|
120
|
-
num = @statement.scan(/\w+\((\d+)\)/).flatten[0]
|
121
|
-
@statement.gsub!(/\w+\(\d+\)\./, '')
|
122
|
-
"[#{get_type}, #{num}]"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
def struct
|
126
|
-
if is_struct?
|
127
|
-
@statement = Structure.camelcase(@statement.scan(/^struct\s(\w+)/).flatten[0])
|
128
|
-
get_type
|
129
|
-
end
|
130
|
-
end
|
131
|
-
def union
|
132
|
-
if is_union?
|
133
|
-
@statement = Union.camelcase(@statement.scan(/^union\s(\w+)/).flatten[0])
|
134
|
-
get_type
|
135
|
-
end
|
136
|
-
end
|
137
|
-
def enum
|
138
|
-
if is_enum?
|
139
|
-
@statement = Generator::TYPES['int']
|
140
|
-
get_type
|
141
|
-
end
|
142
|
-
end
|
143
|
-
def callback
|
144
|
-
Callback.new(:node => @node).to_s if is_callback?
|
145
|
-
end
|
146
|
-
def typedef
|
147
|
-
if Generator.typedefs.has_key?(@statement)
|
148
|
-
@statement = Generator.typedefs[@statement]
|
149
|
-
get_type
|
150
|
-
end
|
151
|
-
end
|
152
|
-
def get_type
|
153
|
-
constant || pointer || enum || typedef || native || struct || union || array || callback || "#{@statement}"
|
154
|
-
end
|
155
|
-
end
|
156
|
-
class Typedef < Type
|
157
|
-
attr_reader :symname, :statement
|
158
|
-
def initialize(params = { })
|
159
|
-
super
|
160
|
-
@symname = get_attr('name')
|
161
|
-
# @type = is_pointer? ? ':pointer' : get_attr('type')
|
162
|
-
# p @statement
|
163
|
-
end
|
164
|
-
end
|
165
|
-
class Constant < Node
|
166
|
-
def initialize(params = { })
|
167
|
-
super
|
168
|
-
@name, @value = get_attr('sym_name'), get_attr('value')
|
169
|
-
end
|
170
|
-
def to_s
|
171
|
-
@indent_str + "#{@name} = #{@value}"
|
172
|
-
end
|
173
|
-
end
|
174
|
-
class Enum < Node
|
175
|
-
def initialize(params = { })
|
176
|
-
super
|
177
|
-
eval_items
|
178
|
-
end
|
179
|
-
def to_s
|
180
|
-
@items.sort { |i1, i2| i1[1] <=> i2[1] }.inject("") do |result, item|
|
181
|
-
result << assignment_str(item[0], item[1]) << "\n"
|
182
|
-
end
|
183
|
-
end
|
184
|
-
private
|
185
|
-
def assignment_str(name, value)
|
186
|
-
@indent_str + "#{name} = #{value}"
|
187
|
-
end
|
188
|
-
def eval_expr(expr)
|
189
|
-
if expr.include?('+')
|
190
|
-
(@items[expr[/\w+/]].to_i + 1).to_s
|
191
|
-
else
|
192
|
-
0.to_s
|
193
|
-
end
|
194
|
-
end
|
195
|
-
def eval_items
|
196
|
-
@items = {}
|
197
|
-
get_items.each do |i|
|
198
|
-
node = Node.new(:node => i)
|
199
|
-
@items[node.get_attr('name')] = node.get_attr('enumvalueex') ? eval_expr(node.get_attr('enumvalueex')) : node.get_attr('enumvalue')
|
200
|
-
end
|
201
|
-
@items
|
202
|
-
end
|
203
|
-
def get_items
|
204
|
-
@node / './enumitem'
|
205
|
-
end
|
206
|
-
end
|
207
|
-
class Structure < Node
|
208
|
-
def self.camelcase(name)
|
209
|
-
name.gsub(/^\w|\_\w/).each {|c| c.upcase }.delete('_')
|
210
|
-
end
|
211
|
-
def initialize(params = { })
|
212
|
-
super
|
213
|
-
@name = self.class.camelcase(@symname)
|
214
|
-
end
|
215
|
-
def to_s
|
216
|
-
fields_str = fields.inject("") do |str, f|
|
217
|
-
str << @indent_str + ' ' * 9 << f.join(', ') << ",\n"
|
218
|
-
end
|
219
|
-
code = klass_string + @indent_str + " layout(\n" + fields_str.chomp.chomp(',') + "\n" + @indent_str + " )\n" + @indent_str + "end\n"
|
220
|
-
end
|
221
|
-
private
|
222
|
-
def klass_string
|
223
|
-
@indent_str + "class #{@name} < FFI::Struct\n"
|
224
|
-
end
|
225
|
-
def fields
|
226
|
-
(@node / 'cdecl').inject([]) do |array, field|
|
227
|
-
array << [":#{Node.new(:node => field).symname}", "#{Type.new(:node => field)}"]
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
class Union < Structure
|
232
|
-
private
|
233
|
-
def klass_string
|
234
|
-
@indent_str + "class #{@name} < FFI::Union\n"
|
235
|
-
end
|
236
|
-
end
|
237
|
-
class Function < Type
|
238
|
-
class Argument < Type
|
239
|
-
def to_s
|
240
|
-
get_attr('type') == 'void' ? nil : super
|
241
|
-
end
|
242
|
-
end
|
243
|
-
def initialize(params = { })
|
244
|
-
super
|
245
|
-
@type = get_attr('type')
|
246
|
-
end
|
247
|
-
def to_s
|
248
|
-
params = get_params(@node).inject([]) do |array, node|
|
249
|
-
array << Argument.new(:node => node).to_s
|
250
|
-
end.collect { |p| "#{p}" }
|
251
|
-
@indent_str + "attach_function :#{@symname}, [ #{params.join(', ')} ], #{get_rvalue}"
|
252
|
-
end
|
253
|
-
private
|
254
|
-
def get_params(node)
|
255
|
-
parmlist = node / './attributelist/parmlist/parm'
|
256
|
-
end
|
257
|
-
def get_rvalue
|
258
|
-
Type.new(:node => @node, :statement => @statement.scan(/^f\(.*\)\.(.+)/).flatten[0]).to_s
|
259
|
-
end
|
260
|
-
end
|
261
|
-
class Callback < Type
|
262
|
-
def to_s
|
263
|
-
params = get_params.inject([]) do |array, type|
|
264
|
-
array << (type == 'void' ? '' : Type.new(:statement => type).to_s)
|
265
|
-
end
|
266
|
-
@indent_str + "callback(:#{@symname}, [ #{params.join(', ')} ], #{get_rtype})"
|
267
|
-
end
|
268
|
-
private
|
269
|
-
def get_params
|
270
|
-
@statement.scan(/p.f\((.*)\)/).flatten[0].split(',')
|
271
|
-
end
|
272
|
-
def get_rtype
|
273
|
-
Type.new(:statement => @statement.scan(/\)\.(\w+)/).flatten[0]).to_s
|
274
|
-
end
|
275
|
-
end
|
276
|
-
class Parser
|
277
|
-
@indent = 2
|
278
|
-
class << self
|
279
|
-
def get_verbatim(node)
|
280
|
-
node.xpath("./attributelist/attribute[@name='code']").first['value']
|
281
|
-
end
|
282
|
-
def is_insert_runtime?(node)
|
283
|
-
section = node.xpath("./attributelist/attribute[@name='section']")
|
284
|
-
section.first['value'] == 'runtime' if section.first
|
285
|
-
end
|
286
|
-
def is_constant?(node)
|
287
|
-
node.name == 'constant'
|
288
|
-
end
|
289
|
-
def is_enum?(node)
|
290
|
-
node.name == 'enum'
|
291
|
-
end
|
292
|
-
def is_function_decl?(node)
|
293
|
-
node.name == 'cdecl' and (node / "./attributelist/attribute[@name='kind']").first['value'] == 'function'
|
294
|
-
end
|
295
|
-
def is_struct?(node)
|
296
|
-
node.name == 'class' and (node / "./attributelist/attribute[@name='kind']").first['value'] == 'struct'
|
297
|
-
end
|
298
|
-
def is_union?(node)
|
299
|
-
node.name == 'class' and (node / "./attributelist/attribute[@name='kind']").first['value'] == 'union'
|
300
|
-
end
|
301
|
-
def is_typedef?(node)
|
302
|
-
node.name == 'cdecl' and (node / "./attributelist/attribute[@name='kind']").first['value'] == 'typedef'
|
303
|
-
end
|
304
|
-
def is_callback?(node)
|
305
|
-
(node / "./attributelist/attribute[@name='decl']").first['value'] =~ /^p\.f\(/
|
306
|
-
end
|
307
|
-
def generate(node)
|
308
|
-
result = ""
|
309
|
-
node.traverse do |node|
|
310
|
-
if is_constant?(node)
|
311
|
-
result << Constant.new(:node => node, :indent => @indent).to_s << "\n"
|
312
|
-
elsif is_typedef?(node)
|
313
|
-
typedef = Typedef.new(:node => node)
|
314
|
-
Generator.add_type(typedef.symname, typedef.statement)
|
315
|
-
if is_callback?(node)
|
316
|
-
cb = Callback.new(:node => node, :indent => @indent).to_s << "\n"
|
317
|
-
Generator.add_type(typedef.symname, ":#{typedef.symname}")
|
318
|
-
result << cb.to_s
|
319
|
-
end
|
320
|
-
elsif is_enum?(node)
|
321
|
-
e = Enum.new(:node => node, :indent => @indent)
|
322
|
-
Generator.add_type(e.symname, Generator::TYPES['int'])
|
323
|
-
result << e.to_s << "\n"
|
324
|
-
elsif is_struct?(node)
|
325
|
-
s = Structure.new(:node => node, :indent => @indent)
|
326
|
-
Generator.add_type(s.symname, "struct #{s.symname}")
|
327
|
-
result << s.to_s
|
328
|
-
elsif is_union?(node)
|
329
|
-
s = Union.new(:node => node, :indent => @indent)
|
330
|
-
Generator.add_type(s.symname, "union #{s.symname}")
|
331
|
-
result << s.to_s
|
332
|
-
elsif is_function_decl?(node)
|
333
|
-
result << Function.new(:node => node, :indent => @indent).to_s << "\n"
|
334
|
-
elsif node.name == 'insert' and not is_insert_runtime?(node)
|
335
|
-
result << get_verbatim(node)
|
336
|
-
end
|
337
|
-
end
|
338
|
-
result
|
339
|
-
end
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|