ffi-swig-generator 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|