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.
Files changed (89) hide show
  1. data/.hg/branch.cache +2 -0
  2. data/.hg/dirstate +0 -0
  3. data/.hg/store/00changelog.i +0 -0
  4. data/.hg/store/00manifest.i +0 -0
  5. data/.hg/store/data/.hgignore.i +0 -0
  6. data/.hg/store/data/.hgtags.i +0 -0
  7. data/.hg/store/data/_history.txt.i +0 -0
  8. data/.hg/store/data/_r_e_a_d_m_e.rdoc.i +0 -0
  9. data/.hg/store/data/_rakefile.i +0 -0
  10. data/.hg/store/data/cucumber.yml.i +0 -0
  11. data/.hg/store/data/examples/_rakefile.i +0 -0
  12. data/.hg/store/data/features/generate.feature.i +0 -0
  13. data/.hg/store/data/features/step__definitions/generate.rb.i +0 -0
  14. data/.hg/store/data/features/support/env.rb.i +0 -0
  15. data/.hg/store/data/features/support/results.rb.i +0 -0
  16. data/.hg/store/data/features/support/templates.rb.i +0 -0
  17. data/.hg/store/data/lib/ffi-swig-generator.rb.i +0 -0
  18. data/.hg/store/data/lib/generator/application.rb.i +0 -0
  19. data/.hg/store/data/lib/generator/constant.rb.i +0 -0
  20. data/.hg/store/data/lib/generator/enum.rb.i +0 -0
  21. data/.hg/store/data/lib/generator/function.rb.i +0 -0
  22. data/.hg/store/data/lib/generator/generator.rb.i +0 -0
  23. data/.hg/store/data/lib/generator/generatortask.rb.i +0 -0
  24. data/.hg/store/data/lib/generator/logger.rb.i +0 -0
  25. data/.hg/store/data/lib/generator/node.rb.i +0 -0
  26. data/.hg/store/data/lib/generator/parser.rb.i +0 -0
  27. data/.hg/store/data/lib/generator/struct.rb.i +0 -0
  28. data/.hg/store/data/lib/generator/type.rb.i +0 -0
  29. data/.hg/store/data/lib/generator/types.rb.i +0 -0
  30. data/.hg/store/data/spec/generator/constant__spec.rb.i +0 -0
  31. data/.hg/store/data/spec/generator/enum__spec.rb.i +0 -0
  32. data/.hg/store/data/spec/generator/function__spec.rb.i +0 -0
  33. data/.hg/store/data/spec/generator/generator__spec.rb.i +0 -0
  34. data/.hg/store/data/spec/generator/node__spec.rb.i +0 -0
  35. data/.hg/store/data/spec/generator/parser__spec.rb.i +0 -0
  36. data/.hg/store/data/spec/generator/struct__spec.rb.i +0 -0
  37. data/.hg/store/data/spec/generator/swig/constants.i.i +0 -0
  38. data/.hg/store/data/spec/generator/swig/functions.i.i +0 -0
  39. data/.hg/store/data/spec/generator/swig/testlib.i.i +0 -0
  40. data/.hg/store/data/spec/generator/swig/typedefs.i.i +0 -0
  41. data/.hg/store/data/spec/generator/swig/types.i.i +0 -0
  42. data/.hg/store/data/spec/generator/type__spec.rb.i +0 -0
  43. data/.hg/store/data/spec/spec__helper.rb.i +0 -0
  44. data/.hg/store/data/tasks/cucumber.rake.i +0 -0
  45. data/.hg/store/undo +0 -0
  46. data/.hg/undo.dirstate +0 -0
  47. data/.hgignore +3 -0
  48. data/.hgtags +1 -0
  49. data/History.txt +22 -2
  50. data/README.rdoc +26 -22
  51. data/Rakefile +2 -3
  52. data/cucumber.yml +1 -0
  53. data/examples/Rakefile +5 -3
  54. data/examples/generated/libc_wrap.rb +18 -0
  55. data/examples/generated/libc_wrap.xml +597 -0
  56. data/examples/generated/wiiuse_wrap.rb +322 -0
  57. data/examples/generated/wiiuse_wrap.xml +9025 -0
  58. data/features/generate.feature +45 -0
  59. data/features/step_definitions/generate.rb +32 -0
  60. data/features/support/env.rb +4 -0
  61. data/features/support/templates.rb +381 -0
  62. data/lib/ffi-swig-generator.rb +1 -1
  63. data/lib/generator/application.rb +1 -1
  64. data/lib/generator/constant.rb +24 -0
  65. data/lib/generator/enum.rb +38 -0
  66. data/lib/generator/function.rb +71 -0
  67. data/lib/generator/generatortask.rb +21 -9
  68. data/lib/generator/logger.rb +29 -0
  69. data/lib/generator/node.rb +19 -0
  70. data/lib/generator/parser.rb +168 -0
  71. data/lib/generator/struct.rb +76 -0
  72. data/lib/generator/type.rb +128 -0
  73. data/lib/generator/types.rb +36 -0
  74. data/spec/generator/constant_spec.rb +17 -0
  75. data/spec/generator/enum_spec.rb +29 -0
  76. data/spec/generator/function_spec.rb +66 -0
  77. data/spec/generator/parser_spec.rb +250 -0
  78. data/spec/generator/struct_spec.rb +77 -0
  79. data/spec/generator/swig/constants.i +5 -0
  80. data/spec/generator/swig/functions.i +8 -0
  81. data/spec/generator/swig/testlib.i +42 -0
  82. data/spec/generator/swig/typedefs.i +1 -0
  83. data/spec/generator/swig/types.i +1 -0
  84. data/spec/generator/type_spec.rb +38 -0
  85. data/spec/spec_helper.rb +6 -0
  86. data/tasks/cucumber.rake +8 -0
  87. metadata +58 -18
  88. data/lib/generator/generator.rb +0 -344
  89. 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
@@ -1,3 +1,8 @@
1
1
  %module constant_wrap
2
2
 
3
3
  #define CONST_1 0x10
4
+ #define CONST_2 1234U
5
+ #define CONST_3 1234L
6
+ #define CONST_4 1234UL
7
+
8
+
@@ -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);
@@ -3,3 +3,4 @@
3
3
  typedef unsigned char byte;
4
4
  byte b;
5
5
  typedef int *(PTF)(char*, char*)
6
+
@@ -38,6 +38,7 @@ signed long long sll;
38
38
  signed long long int slli;
39
39
  signed short ss;
40
40
  signed short int ssi;
41
+ size_t sizet;
41
42
  unsigned char uc;
42
43
  unsigned int ui;
43
44
  unsigned long ul;
@@ -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
@@ -24,4 +24,10 @@ def remove_xml
24
24
  FileUtils.rm(Dir.glob('spec/generator/swig/*.xml'))
25
25
  end
26
26
 
27
+ share_examples_for "All specs" do
28
+ after :all do
29
+ remove_xml
30
+ end
31
+ end
32
+
27
33
  # EOF
@@ -0,0 +1,8 @@
1
+ begin
2
+ require 'cucumber/rake/task'
3
+ Cucumber::Rake::Task.new(:features) do |t|
4
+ t.cucumber_opts = "--format pretty"
5
+ end
6
+ rescue LoadError
7
+ nil
8
+ end
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.2.1
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-03-09 00:00:00 +01:00
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
- - !ruby/object:Gem::Dependency
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/generator.rb
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/generator_spec.rb
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.0
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 based on SWIG interface files
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
 
@@ -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
-