ffidb 0.12.0 → 0.13.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 832a289161ba25e274a8a6d3a20a1592ec40bff4e3774400e6d7f5b3286335c5
4
- data.tar.gz: 6b27cb31d52109e2a44c5c8a72f830b772d306206acec33add96eb8faf23e464
3
+ metadata.gz: b3d376934e5941a0509caeef0ec2b8c0fd2726234b62b499098097b501889012
4
+ data.tar.gz: 311ba10e14c9c50818cf8a3ffa928c55a989f285c599cd08e56c70caeed73319
5
5
  SHA512:
6
- metadata.gz: 3b6bc06df8f1d94ded39f0370874d6c02c2f6dc33321f8a7affc51a3f53e2db5300b9291447b5528758a9ba5b22e3402a45b01f5ee17cca5acb642db531298ea
7
- data.tar.gz: 4fba31365dbb2b0567dd381075b8f36c3d3bcf07324c9edf143f19e7472e7eabe1c6a17a00fff7b945e55ca47db33b81d1c7eb034e28de32753bff0adb1da820
6
+ metadata.gz: abfe03bcad1996b4eca15e62e8eacb0486b5a826d75e34c05ec63d500efbe74087b12259dc82fab13d934d4b573add37bc122a63a091a4ee3a6735d9605434a1
7
+ data.tar.gz: 0aa715b38545c0e4d09558b251ba198efa24bcd1bc6cc3c0e162aa75b8baf85cfd5e9f85319a71502d7d6885d3688aeff071fd9ab13a9d6b3cef60534fdc5c08
data/README.md CHANGED
@@ -18,6 +18,22 @@ After installation, download and initialize the FFI DB registry as follows:
18
18
 
19
19
  Your local FFI DB registry is located at the path `$HOME/.ffidb/`.
20
20
 
21
+ Features
22
+ --------
23
+
24
+ ### Code generation
25
+
26
+ | ID | Language | typedefs | enums | structs | unions | functions |
27
+ | :------ | :---------- | :------- | :---- | :------ | :----- | :-------- |
28
+ | c | C | | ✔ | ✔ | | ✔ |
29
+ | c++ | C++ | | ✔ | ✔ | | ✔ |
30
+ | dart | Dart | | ✔ | ✔ | | ✔ |
31
+ | go | Go | | ✔ | ✔ | | ✔ |
32
+ | java | Java | | ✔ | ✔ | | ✔ |
33
+ | lisp | Common Lisp | | ✔ | ✔ | | ✔ |
34
+ | python | Python | | ✔ | ✔ | | ✔ |
35
+ | ruby | Ruby | | ✔ | ✔ | | ✔ |
36
+
21
37
  Examples (API)
22
38
  --------------
23
39
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.12.0
1
+ 0.13.0
@@ -15,7 +15,7 @@
15
15
  <% for enum in @enums[library] || [] %>
16
16
 
17
17
  <% if enum.comment %>
18
- // <%= enum.comment %>
18
+ <%= format_comment(enum.comment, '//') %>
19
19
  <% end %>
20
20
  enum <%= enum.name %> {
21
21
  <% for name, value in enum.values || {} %>
@@ -26,7 +26,7 @@ enum <%= enum.name %> {
26
26
  <% for struct in @structs[library] || [] %>
27
27
 
28
28
  <% if struct.comment %>
29
- // <%= struct.comment %>
29
+ <%= format_comment(struct.comment, '//') %>
30
30
  <% end %>
31
31
  struct <%= struct.name %> {
32
32
  <% for name, type in struct.fields || {} %>
@@ -37,7 +37,7 @@ struct <%= struct.name %> {
37
37
  <% for function in @functions[library] || [] %>
38
38
 
39
39
  <% if function.comment %>
40
- // <%= function.comment %>
40
+ <%= format_comment(function.comment, '//') %>
41
41
  <% end %>
42
42
  extern <%= function.type %> <%= function.name %>(<%=
43
43
  function.parameters.each_value.map { |p| "#{p.type} #{p.name}" }.join(', ')
@@ -13,7 +13,7 @@ namespace <%= self.options[:module] || library&.name || :lib %> {
13
13
  <% for enum in @enums[library] || [] %>
14
14
 
15
15
  <% if enum.comment %>
16
- // <%= enum.comment %>
16
+ <%= format_comment(enum.comment, ' //') %>
17
17
  <% end %>
18
18
  enum <%= enum.name %> {
19
19
  <% for name, value in enum.values || {} %>
@@ -24,7 +24,7 @@ namespace <%= self.options[:module] || library&.name || :lib %> {
24
24
  <% for struct in @structs[library] || [] %>
25
25
 
26
26
  <% if struct.comment %>
27
- // <%= struct.comment %>
27
+ <%= format_comment(struct.comment, ' //') %>
28
28
  <% end %>
29
29
  struct <%= struct.name %> {
30
30
  <% for name, type in struct.fields || {} %>
@@ -35,7 +35,7 @@ namespace <%= self.options[:module] || library&.name || :lib %> {
35
35
  <% for function in @functions[library] || [] %>
36
36
 
37
37
  <% if function.comment %>
38
- // <%= function.comment %>
38
+ <%= format_comment(function.comment, ' //') %>
39
39
  <% end %>
40
40
  extern "C" <%= function.type %> <%= function.name %>(<%=
41
41
  function.parameters.each_value.map { |p| "#{p.type} #{p.name}" }.join(', ')
@@ -16,7 +16,7 @@ final <%= library&.name || :lib %> = DynamicLibrary.open('<%= dlopen_paths_for(l
16
16
  <% for enum in @enums[library] || [] %>
17
17
 
18
18
  <% if enum.comment %>
19
- /// <%= enum.comment %>
19
+ <%= format_comment(enum.comment, '///') %>
20
20
  <% end %>
21
21
  abstract class <%= enum.name %> {
22
22
  <%= enum.name %>._();
@@ -29,11 +29,12 @@ abstract class <%= enum.name %> {
29
29
  <% for struct in @structs[library] || [] %>
30
30
 
31
31
  <% if struct.comment %>
32
- /// <%= struct.comment %>
32
+ <%= format_comment(struct.comment, '///') %>
33
33
  <% end %>
34
34
  <% if struct.opaque? %>
35
35
  class <%= struct.name %> extends Struct {
36
- Int8 _opaque;
36
+ @Uint8()
37
+ int _opaque;
37
38
  <% else %>
38
39
  class <%= struct.name %> extends Struct {
39
40
  <% for (name, type), i in (struct.fields || {}).each_with_index %>
@@ -51,7 +52,7 @@ class <%= struct.name %> extends Struct {
51
52
  <% for function in @functions[library] || [] %>
52
53
 
53
54
  <% if function.comment %>
54
- /// <%= function.comment %>
55
+ <%= format_comment(function.comment, '///') %>
55
56
  <% end %>
56
57
  final <%= dart_param_type(function.type) %> Function(<%=
57
58
  function.parameters.each_value.map { |p| dart_param_type(p.type) }.join(', ')
@@ -17,7 +17,7 @@
17
17
  <% for enum in @enums[library] || [] %>
18
18
 
19
19
  <% if enum.comment %>
20
- // <%= enum.comment %>
20
+ <%= format_comment(enum.comment, '//') %>
21
21
  <% end %>
22
22
  enum <%= enum.name %> {
23
23
  <% for name, value in enum.values || {} %>
@@ -28,7 +28,7 @@ enum <%= enum.name %> {
28
28
  <% for struct in @structs[library] || [] %>
29
29
 
30
30
  <% if struct.comment %>
31
- // <%= struct.comment %>
31
+ <%= format_comment(struct.comment, '//') %>
32
32
  <% end %>
33
33
  struct <%= struct.name %> {
34
34
  <% for name, type in struct.fields || {} %>
@@ -39,7 +39,7 @@ struct <%= struct.name %> {
39
39
  <% for function in @functions[library] || [] %>
40
40
 
41
41
  <% if function.comment %>
42
- // <%= function.comment %>
42
+ <%= format_comment(function.comment, '//') %>
43
43
  <% end %>
44
44
  extern <%= function.type %> <%= function.name %>(<%=
45
45
  function.parameters.each_value.map { |p| "#{p.type} #{p.name}" }.join(', ')
@@ -16,9 +16,9 @@ public interface <%= library&.interface_name || :FFI %> extends Library {
16
16
  <% end %>
17
17
  <% for enum in @enums[library] || [] %>
18
18
 
19
- <% if enum.comment %>
20
- // <%= enum.comment %>
21
- <% end %>
19
+ <% if enum.comment %>
20
+ <%= format_comment(enum.comment, ' //') %>
21
+ <% end %>
22
22
  public static class <%= enum.name %> {
23
23
  <% for name, value in enum.values || {} %>
24
24
  public static final int <%= name %> = <%= value %>;
@@ -28,7 +28,7 @@ public interface <%= library&.interface_name || :FFI %> extends Library {
28
28
  <% for struct in @structs[library] || [] %>
29
29
 
30
30
  <% if struct.comment %>
31
- // <%= struct.comment %>
31
+ <%= format_comment(struct.comment, ' //') %>
32
32
  <% end %>
33
33
  <% if struct.opaque? %>
34
34
  @FieldOrder({ "_opaque" })
@@ -46,7 +46,7 @@ public interface <%= library&.interface_name || :FFI %> extends Library {
46
46
  <% for function in @functions[library] || [] %>
47
47
 
48
48
  <% if function.comment %>
49
- // <%= function.comment %>
49
+ <%= format_comment(function.comment, ' //') %>
50
50
  <% end %>
51
51
  <%= param_type(function.type) %> <%= function.name %>(<%=
52
52
  function.parameters.each_value.map { |p| [param_type(p.type), p.name].join(' ') }.join(', ')
@@ -14,7 +14,7 @@
14
14
  <% for enum in @enums[library] || [] %>
15
15
 
16
16
  <% if enum.comment %>
17
- ;; <%= enum.comment %>
17
+ <%= format_comment(enum.comment, ';;') %>
18
18
  <% end %>
19
19
  (cffi:defcenum <%= enum.name %>
20
20
  <% for name, value in enum.values || {} %>
@@ -25,14 +25,14 @@
25
25
  <% for struct in @structs[library] || [] %>
26
26
 
27
27
  <% if struct.comment %>
28
- ;; <%= struct.comment %>
28
+ <%= format_comment(struct.comment, ';;') %>
29
29
  <% end %>
30
30
  <% if struct.opaque? %>
31
31
  (cffi:defctype <%= struct.name %> :pointer)
32
32
  <% else %>
33
33
  (cffi:defcstruct <%= struct.name %>
34
34
  <% for name, type in struct.fields || {} %>
35
- (<%= name %> <%= struct_type(type).map(&:inspect).join(' ') %>)
35
+ (<%= name %> <%= struct_type(type) %>)
36
36
  <% end %>
37
37
  )
38
38
  <% end %>
@@ -40,10 +40,10 @@
40
40
  <% for function in @functions[library] || [] %>
41
41
 
42
42
  <% if function.comment %>
43
- ;; <%= function.comment %>
43
+ <%= format_comment(function.comment, ';;') %>
44
44
  <% end %>
45
- (cffi:defcfun "<%= function.name %>" <%= param_type(function.type).inspect %> <%=
46
- function.parameters.each_value.map { |p| "(#{p.name} #{param_type(p.type).inspect})" }.join(' ')
45
+ (cffi:defcfun "<%= function.name %>" <%= param_type(function.type) %><%=
46
+ function.parameters.each_value.map { |p| " (#{p.name} #{param_type(p.type)})" }.join
47
47
  %>)
48
48
  <% end %>
49
49
  <% end %>
@@ -18,7 +18,7 @@ import ctypes, ctypes.util
18
18
  <% for enum in @enums[library] || [] %>
19
19
 
20
20
  <% if enum.comment %>
21
- # <%= enum.comment %>
21
+ <%= format_comment(enum.comment, '#') %>
22
22
  <% end %>
23
23
  <%= enum.name %> = ctypes.c_int
24
24
  <% for name, value in enum.values || {} %>
@@ -28,12 +28,12 @@ import ctypes, ctypes.util
28
28
  <% for struct in @structs[library] || [] %>
29
29
 
30
30
  <% if struct.comment %>
31
- # <%= struct.comment %>
31
+ <%= format_comment(struct.comment, '#') %>
32
32
  <% end %>
33
33
  <% if struct.opaque? %>
34
- <%= struct.name %> = ctypes.POINTER(ctypes.c_void)
34
+ <%= struct.name %> = ctypes.POINTER(ctypes.c_void_p)
35
35
  <% else %>
36
- class <%= struct.name %>(Structure):
36
+ class <%= struct.name %>(ctypes.Structure):
37
37
  <% if struct.fields.nil? || struct.fields.empty? %>
38
38
  _fields_ = []
39
39
  <% else %>
@@ -48,7 +48,7 @@ class <%= struct.name %>(Structure):
48
48
  <% for function in @functions[library] || [] %>
49
49
 
50
50
  <% if function.comment %>
51
- # <%= function.comment %>
51
+ <%= format_comment(function.comment, '#') %>
52
52
  <% end %>
53
53
  <%= function.name %> = <%= library&.name || :lib %>.<%= function.name %>
54
54
  <%= function.name %>.restype = <%= param_type(function.type) %>
@@ -13,7 +13,7 @@ module <%= options[:module] || library&.name&.capitalize || :FFI %>
13
13
  <% for enum in @enums[library] || [] %>
14
14
 
15
15
  <% if enum.comment %>
16
- # <%= enum.comment %>
16
+ <%= format_comment(enum.comment, ' #') %>
17
17
  <% end %>
18
18
  <%= enum.name %> = :int
19
19
  <% for name, value in enum.values || {} %>
@@ -23,14 +23,14 @@ module <%= options[:module] || library&.name&.capitalize || :FFI %>
23
23
  <% for struct in @structs[library] || [] %>
24
24
 
25
25
  <% if struct.comment %>
26
- # <%= struct.comment %>
26
+ <%= format_comment(struct.comment, ' #') %>
27
27
  <% end %>
28
28
  <% if struct.opaque? %>
29
- <%= struct.name %> = FFI::Pointer
29
+ <%= struct.name %> = :pointer
30
30
  <% else %>
31
31
  class <%= struct.name %> < FFI::Struct
32
32
  <% for (name, type), i in (struct.fields || {}).each_with_index %>
33
- <%= i.zero? ? 'layout' : ' '*6 %> :<%= name %>, <%= struct_type(type).inspect %><%= (i == (struct.fields || {}).size-1) ? '' : ',' %> # <%= type %>
33
+ <%= i.zero? ? 'layout' : ' '*6 %> :<%= name %>, <%= struct_type(type) %><%= (i == (struct.fields || {}).size-1) ? '' : ',' %> # <%= type %>
34
34
  <% end %>
35
35
  end
36
36
  <% end %>
@@ -38,11 +38,11 @@ module <%= options[:module] || library&.name&.capitalize || :FFI %>
38
38
  <% for function in @functions[library] || [] %>
39
39
 
40
40
  <% if function.comment %>
41
- # <%= function.comment %>
41
+ <%= format_comment(function.comment, ' #') %>
42
42
  <% end %>
43
43
  attach_function :<%= function.name %>, [<%=
44
- function.parameters.each_value.map { |p| param_type(p.type).inspect }.join(', ')
45
- %>], :<%= param_type(function.type) %>
44
+ function.parameters.each_value.map { |param| param_type(param.type) }.join(', ')
45
+ %>], <%= param_type(function.type) %>
46
46
  <% end %>
47
47
  end # <%= options[:module] || library&.name&.capitalize || :FFI %>
48
48
  <% end %>
@@ -88,7 +88,8 @@ module FFIDB
88
88
  end
89
89
 
90
90
  def export_typedef(typedef, disabled: nil)
91
- (@typedefs[@library] ||= []) << typedef
91
+ @typedefs[@library] ||= {}
92
+ @typedefs[@library][typedef.name] = typedef
92
93
  end
93
94
 
94
95
  def export_enum(enum, disabled: nil)
@@ -96,15 +97,15 @@ module FFIDB
96
97
  end
97
98
 
98
99
  def export_struct(struct, disabled: nil)
99
- (@structs[@library] ||= []) << struct
100
+ (@structs[@library] ||= []) << self.resolve_struct(struct)
100
101
  end
101
102
 
102
103
  def export_union(union, disabled: nil)
103
- (@unions[@library] ||= []) << union
104
+ (@unions[@library] ||= []) << self.resolve_union(union)
104
105
  end
105
106
 
106
107
  def export_function(function, disabled: nil)
107
- (@functions[@library] ||= []) << function
108
+ (@functions[@library] ||= []) << self.resolve_function(function)
108
109
  end
109
110
 
110
111
  def finish_library
@@ -125,13 +126,121 @@ module FFIDB
125
126
  @stream.print *args
126
127
  end
127
128
 
129
+ ##
130
+ # @param [String] comment
131
+ # @param [String] prefix
132
+ # @return [String]
133
+ def format_comment(comment, prefix)
134
+ prefix = prefix + ' '
135
+ comment.each_line.map(&:strip).map { |s| s.prepend(prefix) }.join("\n")
136
+ end
137
+
138
+ ##
139
+ # @param [Function] function
140
+ # @feturn [Function]
141
+ def resolve_function(function)
142
+ function.type = self.resolve_type(function.type)
143
+ function.parameters.transform_values! do |param|
144
+ param.type = self.resolve_type(param.type)
145
+ param
146
+ end
147
+ function
148
+ end
149
+
150
+ ##
151
+ # @param [Struct] struct
152
+ # @feturn [Struct]
153
+ def resolve_struct(struct)
154
+ struct.fields.each do |field_name, field_type|
155
+ struct.fields[field_name] = self.resolve_type(field_type)
156
+ end
157
+ struct
158
+ end
159
+
160
+ ##
161
+ # @param [Union] union
162
+ # @feturn [Union]
163
+ def resolve_union(union)
164
+ self.resolve_struct(union)
165
+ end
166
+
167
+ ##
168
+ # @param [Type] type
169
+ # @return [Type, Symbol]
170
+ def resolve_type(type)
171
+ case
172
+ when type.struct_pointer?
173
+ name = type.spec.gsub(/^const /, '').gsub(/^struct /, '').gsub(/\s*\*+$/, '')
174
+ name.to_sym
175
+ when type.struct? || type.union?
176
+ type
177
+ when typedef = lookup_typedef(type.name)
178
+ case typedef.type.tag
179
+ when :enum then type.name.to_sym
180
+ when :struct then (type.pointer? ? type.name : "#{type.name}.by_value").to_sym # FIXME
181
+ else typedef.type
182
+ end
183
+ else type
184
+ end
185
+ end
186
+
187
+ ##
188
+ # @param [Type] type
189
+ # @return [Symbolic]
190
+ def lookup_symbol(type)
191
+ self.lookup_typedef(type.name)
192
+ end
193
+
194
+ ##
195
+ # @param [Symbol] type_name
196
+ # @return [Typedef]
197
+ def lookup_typedef(type_name)
198
+ @typedefs && @typedefs[@library] && @typedefs[@library][type_name]
199
+ end
200
+
201
+ ##
202
+ # @param [Symbol, Type] c_type
203
+ # @return [#to_s]
204
+ def struct_type(c_type)
205
+ return c_type if c_type.is_a?(Symbol) # a resolved typedef
206
+ self.param_type(c_type)
207
+ end
208
+
209
+ ##
210
+ # @param [Symbol, Type] c_type
211
+ # @return [#to_s]
212
+ def param_type(c_type)
213
+ return c_type if c_type.is_a?(Symbol) # a resolved typedef
214
+ case
215
+ when type = typemap[c_type.to_s] then type
216
+ when c_type.enum? then typemap['int']
217
+ when c_type.pointer? then typemap['void *']
218
+ when c_type.array? then typemap['void *']
219
+ else
220
+ warn "#{$0}: unknown C type #{c_type}, mapping to enum (int)" if debug?
221
+ typemap['int'] # TODO: typedef or enum
222
+ end
223
+ end
224
+
225
+ def typemap
226
+ @typemap ||= self.load_typemap(self.class.const_get(:TYPE_MAP))
227
+ end
228
+
229
+ def load_typemap(typemap_name)
230
+ ::YAML.load(File.read(self.path_to_typemap(typemap_name))).freeze
231
+ end
232
+
233
+ def path_to_typemap(typemap_name)
234
+ File.expand_path("../../etc/mappings/#{typemap_name}", __dir__)
235
+ end
236
+
128
237
  def render_template(template_name)
129
238
  #ERB.new(self.load_template(template_name)).result(binding)
130
239
  Tilt.new(self.path_to_template(template_name)).render(self)
131
240
  end
132
241
 
133
242
  def load_template(template_name)
134
- File.read(self.path_to_template(template_name))
243
+ File.read(self.path_to_template(template_name)).freeze
135
244
  end
136
245
 
137
246
  def path_to_template(template_name)
@@ -10,25 +10,24 @@ module FFIDB::Exporters
10
10
  # @see https://flutter.dev/docs/development/platform-integration/c-interop
11
11
  # @see https://api.dart.dev/dev/dart-ffi/dart-ffi-library.html
12
12
  class Dart < FFIDB::Exporter
13
- TYPE_MAP_FFI = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/dart.yaml", __dir__)))
14
- .freeze
13
+ TYPE_MAP = 'dart.yaml'
15
14
 
16
15
  # @see https://dart.dev/guides/language/language-tour
17
16
  TYPE_MAP_DART = {
18
- :Void => :void,
19
- :Int8 => :int,
20
- :Int16 => :int,
21
- :Int32 => :int,
22
- :Int64 => :int,
23
- :Uint8 => :int,
24
- :Uint16 => :int,
25
- :Uint32 => :int,
26
- :Uint64 => :int,
27
- :Float => :double,
28
- :Double => :double,
29
- :IntPtr => :int,
30
- 'Pointer<Int8>' => 'Pointer<Int8>',
31
- nil => 'Pointer<Void>',
17
+ 'Void' => :void,
18
+ 'Int8' => :int,
19
+ 'Int16' => :int,
20
+ 'Int32' => :int,
21
+ 'Int64' => :int,
22
+ 'Uint8' => :int,
23
+ 'Uint16' => :int,
24
+ 'Uint32' => :int,
25
+ 'Uint64' => :int,
26
+ 'Float' => :double,
27
+ 'Double' => :double,
28
+ 'IntPtr' => :int,
29
+ 'Pointer<Int8>' => 'Pointer<Int8>',
30
+ 'Pointer<Void>' => 'Pointer<Void>',
32
31
  }
33
32
 
34
33
  def finish
@@ -39,22 +38,45 @@ module FFIDB::Exporters
39
38
 
40
39
  ##
41
40
  # @param [FFIDB::Type] c_type
42
- # @return [#to_s]
41
+ # @return [String]
42
+ def dart_struct_type(c_type)
43
+ case
44
+ when c_type.array? then self.dart_param_type(c_type) # TODO: https://github.com/dart-lang/sdk/issues/35763
45
+ else self.dart_param_type(c_type)
46
+ end
47
+ end
48
+
49
+ ##
50
+ # @param [FFIDB::Type] c_type
51
+ # @return [String]
52
+ def ffi_struct_type(c_type)
53
+ case
54
+ when c_type.array? then self.ffi_param_type(c_type) # TODO: https://github.com/dart-lang/sdk/issues/35763
55
+ else self.ffi_param_type(c_type)
56
+ end
57
+ end
58
+
59
+ ##
60
+ # @param [FFIDB::Type] c_type
61
+ # @return [String]
43
62
  def dart_param_type(c_type)
44
- TYPE_MAP_DART[self.ffi_param_type(c_type)] || TYPE_MAP_DART[nil]
63
+ case
64
+ when c_type.array?
65
+ "Pointer<#{self.dart_param_type(c_type.array_type)}>"
66
+ when type = TYPE_MAP_DART[self.ffi_param_type(c_type)] then type
67
+ else TYPE_MAP_DART[self.typemap['int']].to_s
68
+ end
45
69
  end
46
- alias_method :dart_struct_type, :dart_param_type
47
70
 
48
71
  ##
49
72
  # @param [FFIDB::Type] c_type
50
- # @return [#to_s]
73
+ # @return [String]
51
74
  def ffi_param_type(c_type)
52
75
  case
53
- #when c_type.array? then # TODO: https://github.com/dart-lang/sdk/issues/35763
54
- when c_type.enum? then :Int32
55
- else TYPE_MAP_FFI[c_type.to_s] || TYPE_MAP_FFI['void *']
76
+ when c_type.array?
77
+ "Pointer<#{self.ffi_param_type(c_type.array_type)}>"
78
+ else self.param_type(c_type)
56
79
  end
57
80
  end
58
- alias_method :ffi_struct_type, :ffi_param_type
59
81
  end # Dart
60
82
  end # FFIDB::Exporters
@@ -8,8 +8,7 @@ module FFIDB::Exporters
8
8
  #
9
9
  # @see https://github.com/java-native-access/jna/blob/master/www/GettingStarted.md
10
10
  class Java < FFIDB::Exporter
11
- TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/java.yaml", __dir__)))
12
- .freeze
11
+ TYPE_MAP = 'java.yaml'
13
12
 
14
13
  def begin_library(library)
15
14
  if library
@@ -22,18 +21,5 @@ module FFIDB::Exporters
22
21
  def finish
23
22
  puts self.render_template('java.erb')
24
23
  end
25
-
26
- protected
27
-
28
- ##
29
- # @param [FFIDB::Type] c_type
30
- # @return [#to_s]
31
- def param_type(c_type)
32
- case
33
- when c_type.enum? then :int
34
- else TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
35
- end
36
- end
37
- alias_method :struct_type, :param_type
38
24
  end # Java
39
25
  end # FFIDB::Exporters
@@ -8,9 +8,7 @@ module FFIDB::Exporters
8
8
  #
9
9
  # @see https://common-lisp.net/project/cffi/
10
10
  class Lisp < FFIDB::Exporter
11
- TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/lisp.yaml", __dir__)))
12
- .transform_values(&:to_sym)
13
- .freeze
11
+ TYPE_MAP = 'lisp.yaml'
14
12
 
15
13
  def finish
16
14
  puts self.render_template('lisp.erb')
@@ -20,22 +18,19 @@ module FFIDB::Exporters
20
18
 
21
19
  ##
22
20
  # @param [FFIDB::Type] c_type
23
- # @return [#inspect]
21
+ # @return [String]
24
22
  def struct_type(c_type)
25
23
  case
26
- when c_type.array? then [c_type.array_type.to_s.to_sym, :count, c_type.array_size]
27
- else [self.param_type(c_type)]
24
+ when c_type.array? then [c_type.array_type.to_s.to_sym, :count, c_type.array_size].map(&:inspect).join(' ')
25
+ else self.param_type(c_type)
28
26
  end
29
27
  end
30
28
 
31
29
  ##
32
30
  # @param [FFIDB::Type] c_type
33
- # @return [#inspect]
31
+ # @return [String]
34
32
  def param_type(c_type)
35
- case
36
- when c_type.enum? then :int
37
- else TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
38
- end
33
+ ':' << super(c_type)
39
34
  end
40
35
  end # Lisp
41
36
  end # FFIDB::Exporters
@@ -8,8 +8,7 @@ module FFIDB::Exporters
8
8
  #
9
9
  # @see https://docs.python.org/3/library/ctypes.html
10
10
  class Python < FFIDB::Exporter
11
- TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/python.yaml", __dir__)))
12
- .freeze
11
+ TYPE_MAP = 'python.yaml'
13
12
 
14
13
  def finish
15
14
  puts self.render_template('python.erb')
@@ -18,18 +17,27 @@ module FFIDB::Exporters
18
17
  protected
19
18
 
20
19
  ##
21
- # @param [FFIDB::Type] c_type
22
- # @return [#to_s]
23
- def param_type(c_type)
24
- case
25
- when c_type.enum? then 'ctypes.c_int'
26
- when c_type.array? then [self.param_type(c_type.array_type), '*', c_type.array_size].join(' ')
27
- else case py_type = TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
28
- when 'None' then py_type
29
- else "ctypes.#{py_type}"
20
+ # @param [Symbol, FFIDB::Type] c_type
21
+ # @return [String]
22
+ def struct_type(c_type)
23
+ case c_type
24
+ when Symbol then c_type.to_s # a typedef
25
+ else case
26
+ when c_type.array? then [self.param_type(c_type.array_type), '*', c_type.array_size].join(' ')
27
+ else self.param_type(c_type)
30
28
  end
31
29
  end
32
30
  end
33
- alias_method :struct_type, :param_type
31
+
32
+ ##
33
+ # @param [Symbol, FFIDB::Type] c_type
34
+ # @return [String]
35
+ def param_type(c_type)
36
+ case type = super(c_type)
37
+ when Symbol then type.to_s # a typedef
38
+ when 'None' then type
39
+ else "ctypes.#{type}"
40
+ end
41
+ end
34
42
  end # Python
35
43
  end # FFIDB::Exporters
@@ -8,9 +8,7 @@ module FFIDB::Exporters
8
8
  #
9
9
  # @see https://github.com/ffi/ffi/wiki
10
10
  class Ruby < FFIDB::Exporter
11
- TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/ruby.yaml", __dir__)))
12
- .transform_values(&:to_sym)
13
- .freeze
11
+ TYPE_MAP = 'ruby.yaml'
14
12
 
15
13
  def finish
16
14
  puts self.render_template('ruby.erb')
@@ -19,15 +17,26 @@ module FFIDB::Exporters
19
17
  protected
20
18
 
21
19
  ##
22
- # @param [FFIDB::Type] c_type
23
- # @return [#inspect]
20
+ # @param [Symbol, FFIDB::Type] c_type
21
+ # @return [String]
22
+ def struct_type(c_type)
23
+ case c_type
24
+ when Symbol then c_type.to_s # a typedef
25
+ else case
26
+ when c_type.array? then [self.param_type(c_type.array_type), c_type.array_size].inspect
27
+ else self.param_type(c_type)
28
+ end
29
+ end
30
+ end
31
+
32
+ ##
33
+ # @param [Symbol, FFIDB::Type] c_type
34
+ # @return [String]
24
35
  def param_type(c_type)
25
- case
26
- when c_type.enum? then :int
27
- when c_type.array? then [self.param_type(c_type.array_type), c_type.array_size]
28
- else TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
36
+ case type = super(c_type)
37
+ when Symbol then type.to_s # a typedef
38
+ else ':' << type.to_s
29
39
  end
30
40
  end
31
- alias_method :struct_type, :param_type
32
41
  end # Ruby
33
42
  end # FFIDB::Exporters
@@ -23,6 +23,23 @@ module FFIDB
23
23
  # @return [Integer]
24
24
  def <=>(other) self.spec <=> other.spec end
25
25
 
26
+ ##
27
+ # @return [Symbol]
28
+ def tag
29
+ case self.spec.gsub(/^const /, '')
30
+ when 'enum', /^enum\s+/ then :enum
31
+ when 'struct', /^struct\s+/ then :struct
32
+ when 'union', /^union\s+/ then :union
33
+ else nil
34
+ end
35
+ end
36
+
37
+ ##
38
+ # @return [Symbol]
39
+ def name
40
+ self.spec.gsub(/\s*\*+$/, '').to_sym # TODO
41
+ end
42
+
26
43
  ##
27
44
  # @return [Boolean]
28
45
  def const_qualified?
@@ -50,13 +67,13 @@ module FFIDB
50
67
  ##
51
68
  # @return [Boolean]
52
69
  def enum?
53
- !(self.pointer?) && self.spec.start_with?('enum ')
70
+ !(self.pointer?) && (self.spec == 'enum' || self.spec.start_with?('enum '))
54
71
  end
55
72
 
56
73
  ##
57
74
  # @return [Boolean]
58
75
  def struct?
59
- !(self.pointer?) && (self.spec.start_with?('struct ') || self.spec.start_with?('const struct '))
76
+ !(self.pointer?) && (self.spec == 'struct' || self.spec.start_with?('struct ') || self.spec.start_with?('const struct '))
60
77
  end
61
78
 
62
79
  ##
@@ -180,19 +197,6 @@ module FFIDB
180
197
  self.spec.include?('(*)')
181
198
  end
182
199
 
183
- ##
184
- # @return [Integer, Range, nil]
185
- def sizeof
186
- nil # TODO
187
- end
188
- alias_method :size, :sizeof
189
-
190
- ##
191
- # @return [Integer, Range, nil]
192
- def alignof
193
- nil # TODO
194
- end
195
-
196
200
  ##
197
201
  # @return [String]
198
202
  def to_s
@@ -210,5 +214,20 @@ module FFIDB
210
214
  def inspect
211
215
  "#{self.class}(#{self.spec.inspect})"
212
216
  end
217
+
218
+ protected
219
+
220
+ ##
221
+ # @return [Integer, Range, nil]
222
+ def sizeof
223
+ nil # TODO
224
+ end
225
+ alias_method :size, :sizeof
226
+
227
+ ##
228
+ # @return [Integer, Range, nil]
229
+ def alignof
230
+ nil # TODO
231
+ end
213
232
  end # Type
214
233
  end # FFIDB
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffidb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arto Bendiken
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-21 00:00:00.000000000 Z
11
+ date: 2020-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: dogma.rb
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: tilt
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -175,7 +189,7 @@ metadata:
175
189
  documentation_uri: https://www.rubydoc.info/github/ffidb/ffidb.rb/master
176
190
  homepage_uri: https://github.com/ffidb
177
191
  source_code_uri: https://github.com/ffidb/ffidb.rb
178
- post_install_message:
192
+ post_install_message:
179
193
  rdoc_options: []
180
194
  require_paths:
181
195
  - lib
@@ -191,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
205
  version: 3.1.2
192
206
  requirements: []
193
207
  rubygems_version: 3.1.2
194
- signing_key:
208
+ signing_key:
195
209
  specification_version: 4
196
210
  summary: Command-line interface (CLI) for the FFI DB registry.
197
211
  test_files: []