gir_ffi 0.0.6 → 0.0.7
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/History.txt +12 -0
- data/TODO.rdoc +10 -0
- data/examples/04_webkit.rb +16 -0
- data/lib/gir_ffi/arg_helper.rb +130 -38
- data/lib/gir_ffi/builder/argument.rb +552 -0
- data/lib/gir_ffi/{class_builder.rb → builder/class.rb} +89 -67
- data/lib/gir_ffi/{function_definition_builder.rb → builder/function.rb} +10 -10
- data/lib/gir_ffi/{module_builder.rb → builder/module.rb} +17 -16
- data/lib/gir_ffi/builder.rb +33 -28
- data/lib/gir_ffi/class_base.rb +7 -2
- data/lib/gir_ffi/i_base_info.rb +8 -0
- data/lib/gir_ffi/i_repository.rb +6 -0
- data/lib/gir_ffi/i_struct_info.rb +5 -1
- data/lib/gir_ffi/lib.rb +2 -0
- data/lib/gir_ffi/overrides/glib.rb +30 -0
- data/lib/gir_ffi/overrides/gobject.rb +143 -26
- data/tasks/test.rake +14 -0
- data/test/arg_helper_test.rb +19 -3
- data/test/builder_test.rb +85 -73
- data/test/class_builder_test.rb +15 -11
- data/test/function_definition_builder_test.rb +32 -49
- data/test/g_object_overrides_test.rb +103 -48
- data/test/{generated_everything_test.rb → generated_regress_test.rb} +229 -167
- data/test/i_object_info_test.rb +2 -2
- data/test/i_repository_test.rb +2 -2
- data/test/lib/Makefile.am +30 -0
- data/test/lib/autogen.sh +87 -0
- data/test/lib/configure.ac +30 -0
- data/test/lib/m4/jhflags.m4 +21 -0
- data/test/module_builder_test.rb +10 -10
- data/test/test_helper.rb +14 -10
- metadata +22 -12
- data/lib/gir_ffi/argument_builder.rb +0 -382
@@ -1,382 +0,0 @@
|
|
1
|
-
module GirFFI
|
2
|
-
# Abstract parent class of the argument building classes. These classes
|
3
|
-
# are used by FunctionDefinitionBuilder to create the code that processes
|
4
|
-
# each argument before and after the actual function call.
|
5
|
-
class ArgumentBuilder
|
6
|
-
KEYWORDS = [
|
7
|
-
"alias", "and", "begin", "break", "case", "class", "def", "do",
|
8
|
-
"else", "elsif", "end", "ensure", "false", "for", "if", "in",
|
9
|
-
"module", "next", "nil", "not", "or", "redo", "rescue", "retry",
|
10
|
-
"return", "self", "super", "then", "true", "undef", "unless",
|
11
|
-
"until", "when", "while", "yield"
|
12
|
-
]
|
13
|
-
|
14
|
-
attr_reader :arginfo, :callarg, :pre, :post, :postpost
|
15
|
-
|
16
|
-
attr_accessor :length_arg, :inarg, :retval
|
17
|
-
|
18
|
-
def initialize function_builder, arginfo=nil, libmodule=nil
|
19
|
-
@arginfo = arginfo
|
20
|
-
@inarg = nil
|
21
|
-
@callarg = nil
|
22
|
-
@retval = nil
|
23
|
-
@retname = nil
|
24
|
-
@name = nil
|
25
|
-
@pre = []
|
26
|
-
@post = []
|
27
|
-
@postpost = []
|
28
|
-
@function_builder = function_builder
|
29
|
-
@libmodule = libmodule
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.build function_builder, arginfo, libmodule
|
33
|
-
klass = case arginfo.direction
|
34
|
-
when :inout
|
35
|
-
InOutArgumentBuilder
|
36
|
-
when :in
|
37
|
-
InArgumentBuilder
|
38
|
-
when :out
|
39
|
-
OutArgumentBuilder
|
40
|
-
else
|
41
|
-
raise ArgumentError
|
42
|
-
end
|
43
|
-
klass.new function_builder, arginfo, libmodule
|
44
|
-
end
|
45
|
-
|
46
|
-
def type
|
47
|
-
@arginfo.type
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def safe name
|
53
|
-
if KEYWORDS.include? name
|
54
|
-
"#{name}_"
|
55
|
-
else
|
56
|
-
name
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Implements argument processing for arguments with direction :in
|
62
|
-
class InArgumentBuilder < ArgumentBuilder
|
63
|
-
def prepare
|
64
|
-
@name = safe(@arginfo.name)
|
65
|
-
@callarg = @function_builder.new_var
|
66
|
-
@inarg = @name
|
67
|
-
end
|
68
|
-
|
69
|
-
def process
|
70
|
-
case @arginfo.type.tag
|
71
|
-
when :interface
|
72
|
-
process_interface_in_arg
|
73
|
-
when :void
|
74
|
-
process_void_in_arg
|
75
|
-
when :array
|
76
|
-
process_array_in_arg
|
77
|
-
when :utf8
|
78
|
-
process_utf8_in_arg
|
79
|
-
else
|
80
|
-
process_other_in_arg
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
|
87
|
-
def process_interface_in_arg
|
88
|
-
arg = @arginfo
|
89
|
-
type = arg.type
|
90
|
-
|
91
|
-
iface = type.interface
|
92
|
-
if iface.type == :callback
|
93
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.wrap_in_callback_args_mapper \"#{iface.namespace}\", \"#{iface.name}\", #{@inarg}"
|
94
|
-
@pre << "::#{@libmodule}::CALLBACKS << #{@callarg}"
|
95
|
-
else
|
96
|
-
@pre << "#{@callarg} = #{@inarg}"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def process_void_in_arg
|
101
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.object_to_inptr #{@inarg}"
|
102
|
-
end
|
103
|
-
|
104
|
-
def process_utf8_in_arg
|
105
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.utf8_to_inptr #{@name}"
|
106
|
-
# TODO:
|
107
|
-
#@post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
108
|
-
end
|
109
|
-
|
110
|
-
def process_array_in_arg
|
111
|
-
arg = @arginfo
|
112
|
-
type = arg.type
|
113
|
-
|
114
|
-
if type.array_fixed_size > 0
|
115
|
-
@pre << "GirFFI::ArgHelper.check_fixed_array_size #{type.array_fixed_size}, #{@inarg}, \"#{@inarg}\""
|
116
|
-
elsif type.array_length > -1
|
117
|
-
idx = type.array_length
|
118
|
-
lenvar = @length_arg.inarg
|
119
|
-
@length_arg.inarg = nil
|
120
|
-
@length_arg.pre.unshift "#{lenvar} = #{@inarg}.nil? ? 0 : #{@inarg}.length"
|
121
|
-
end
|
122
|
-
|
123
|
-
tag = arg.type.param_type(0).tag.to_s.downcase
|
124
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_array_to_inptr #{@inarg}"
|
125
|
-
unless arg.ownership_transfer == :everything
|
126
|
-
if tag == :utf8
|
127
|
-
@post << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
|
128
|
-
else
|
129
|
-
@post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def process_other_in_arg
|
135
|
-
@pre << "#{@callarg} = #{@name}"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# Implements argument processing for arguments with direction :out
|
140
|
-
class OutArgumentBuilder < ArgumentBuilder
|
141
|
-
def prepare
|
142
|
-
@name = safe(@arginfo.name)
|
143
|
-
@callarg = @function_builder.new_var
|
144
|
-
@retname = @retval = @function_builder.new_var
|
145
|
-
end
|
146
|
-
|
147
|
-
def process
|
148
|
-
case @arginfo.type.tag
|
149
|
-
when :interface
|
150
|
-
process_interface_out_arg
|
151
|
-
when :array
|
152
|
-
process_array_out_arg
|
153
|
-
else
|
154
|
-
process_other_out_arg
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
private
|
159
|
-
|
160
|
-
def process_interface_out_arg
|
161
|
-
iface = @arginfo.type.interface
|
162
|
-
klass = "#{iface.namespace}::#{iface.name}"
|
163
|
-
|
164
|
-
if @arginfo.caller_allocates?
|
165
|
-
@pre << "#{@callarg} = #{klass}.allocate"
|
166
|
-
@post << "#{@retval} = #{@callarg}"
|
167
|
-
else
|
168
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.pointer_outptr"
|
169
|
-
@post << "#{@retval} = #{klass}.wrap GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def process_array_out_arg
|
174
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.pointer_outptr"
|
175
|
-
|
176
|
-
arg = @arginfo
|
177
|
-
type = arg.type
|
178
|
-
tag = type.param_type(0).tag
|
179
|
-
size = type.array_fixed_size
|
180
|
-
idx = type.array_length
|
181
|
-
|
182
|
-
if size <= 0
|
183
|
-
if idx > -1
|
184
|
-
size = @length_arg.retval
|
185
|
-
@length_arg.retval = nil
|
186
|
-
else
|
187
|
-
raise NotImplementedError
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
@postpost << "#{@retval} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{size}"
|
192
|
-
|
193
|
-
if arg.ownership_transfer == :everything
|
194
|
-
if tag == :utf8
|
195
|
-
@postpost << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{rv}"
|
196
|
-
else
|
197
|
-
@postpost << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
def process_other_out_arg
|
203
|
-
tag = @arginfo.type.tag
|
204
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_outptr"
|
205
|
-
@post << "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag} #{@callarg}"
|
206
|
-
if @arginfo.ownership_transfer == :everything
|
207
|
-
@post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
end
|
212
|
-
|
213
|
-
# Implements argument processing for arguments with direction :inout
|
214
|
-
class InOutArgumentBuilder < ArgumentBuilder
|
215
|
-
def prepare
|
216
|
-
@name = safe(@arginfo.name)
|
217
|
-
@callarg = @function_builder.new_var
|
218
|
-
@inarg = @name
|
219
|
-
@retname = @retval = @function_builder.new_var
|
220
|
-
end
|
221
|
-
|
222
|
-
def process
|
223
|
-
raise NotImplementedError unless @arginfo.ownership_transfer == :everything
|
224
|
-
|
225
|
-
case @arginfo.type.tag
|
226
|
-
when :interface
|
227
|
-
process_interface_inout_arg
|
228
|
-
when :array
|
229
|
-
process_array_inout_arg
|
230
|
-
else
|
231
|
-
process_other_inout_arg
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
private
|
236
|
-
|
237
|
-
def process_interface_inout_arg
|
238
|
-
raise NotImplementedError
|
239
|
-
end
|
240
|
-
|
241
|
-
def process_array_inout_arg
|
242
|
-
arg = @arginfo
|
243
|
-
tag = arg.type.param_type(0).tag
|
244
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_array_to_inoutptr #{@inarg}"
|
245
|
-
if arg.type.array_length > -1
|
246
|
-
idx = arg.type.array_length
|
247
|
-
rv = @length_arg.retval
|
248
|
-
@length_arg.retval = nil
|
249
|
-
lname = @length_arg.inarg
|
250
|
-
@length_arg.inarg = nil
|
251
|
-
@length_arg.pre.unshift "#{lname} = #{@inarg}.length"
|
252
|
-
@post << "#{@retval} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{rv}"
|
253
|
-
if tag == :utf8
|
254
|
-
@post << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{rv}"
|
255
|
-
else
|
256
|
-
@post << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
|
257
|
-
end
|
258
|
-
else
|
259
|
-
raise NotImplementedError
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
def process_other_inout_arg
|
264
|
-
tag = @arginfo.type.tag
|
265
|
-
@pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_to_inoutptr #{@inarg}"
|
266
|
-
@post << "#{@retval} = GirFFI::ArgHelper.outptr_to_#{tag} #{@callarg}"
|
267
|
-
@post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
# Implements argument processing for return values.
|
272
|
-
class ReturnValueBuilder < ArgumentBuilder
|
273
|
-
attr_reader :cvar
|
274
|
-
|
275
|
-
def prepare
|
276
|
-
return if tag == :void
|
277
|
-
@cvar = @function_builder.new_var
|
278
|
-
@retval = @function_builder.new_var
|
279
|
-
end
|
280
|
-
|
281
|
-
def process
|
282
|
-
return if tag == :void
|
283
|
-
|
284
|
-
type = @arginfo.return_type
|
285
|
-
|
286
|
-
case tag
|
287
|
-
when :interface
|
288
|
-
process_interface_return_value type, @cvar
|
289
|
-
when :array
|
290
|
-
process_array_return_value type, @cvar
|
291
|
-
else
|
292
|
-
process_other_return_value
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
def type
|
297
|
-
@arginfo.return_type
|
298
|
-
end
|
299
|
-
|
300
|
-
private
|
301
|
-
|
302
|
-
def process_interface_return_value type, cvar
|
303
|
-
interface = type.interface
|
304
|
-
namespace = interface.namespace
|
305
|
-
name = interface.name
|
306
|
-
|
307
|
-
case interface.type
|
308
|
-
when :interface
|
309
|
-
GirFFI::Builder.build_class namespace, name
|
310
|
-
@post << "#{@retval} = ::#{namespace}::#{name}.wrap(#{cvar})"
|
311
|
-
when :object
|
312
|
-
if @arginfo.constructor?
|
313
|
-
GirFFI::Builder.build_class namespace, name
|
314
|
-
@post << "#{@retval} = ::#{namespace}::#{name}.wrap(#{cvar})"
|
315
|
-
if is_subclass_of_initially_unowned interface
|
316
|
-
@post << "GirFFI::GObject.object_ref_sink(#{@retval})"
|
317
|
-
end
|
318
|
-
else
|
319
|
-
@post << "#{@retval} = GirFFI::ArgHelper.object_pointer_to_object(#{cvar})"
|
320
|
-
end
|
321
|
-
when :struct
|
322
|
-
GirFFI::Builder.build_class namespace, name
|
323
|
-
@post << "#{@retval} = ::#{namespace}::#{name}.wrap(#{cvar})"
|
324
|
-
else
|
325
|
-
@post << "#{@retval} = #{cvar}"
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
|
-
def process_array_return_value type, cvar
|
330
|
-
tag = type.param_type(0).tag
|
331
|
-
size = type.array_fixed_size
|
332
|
-
idx = type.array_length
|
333
|
-
|
334
|
-
if size > 0
|
335
|
-
@post << "#{@retval} = GirFFI::ArgHelper.ptr_to_#{tag}_array #{cvar}, #{size}"
|
336
|
-
elsif idx > -1
|
337
|
-
lendata = @length_arg #@data[idx]
|
338
|
-
rv = lendata.retval
|
339
|
-
lendata.retval = nil
|
340
|
-
@post << "#{@retval} = GirFFI::ArgHelper.ptr_to_#{tag}_array #{cvar}, #{rv}"
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
def process_other_return_value
|
345
|
-
@retval = @cvar
|
346
|
-
end
|
347
|
-
|
348
|
-
def tag
|
349
|
-
type.tag
|
350
|
-
end
|
351
|
-
|
352
|
-
def is_subclass_of_initially_unowned interface
|
353
|
-
if interface.namespace == "GObject" and interface.name == "InitiallyUnowned"
|
354
|
-
true
|
355
|
-
elsif interface.parent
|
356
|
-
is_subclass_of_initially_unowned interface.parent
|
357
|
-
else
|
358
|
-
false
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
# Implements argument processing for error handling arguments. These
|
364
|
-
# arguments are not part of the introspected signature, but their
|
365
|
-
# presence is indicated by the 'throws' attribute of the function.
|
366
|
-
class ErrorHandlerBuilder < ArgumentBuilder
|
367
|
-
def prepare
|
368
|
-
@callarg = @function_builder.new_var
|
369
|
-
end
|
370
|
-
|
371
|
-
def process
|
372
|
-
@pre << "#{@callarg} = FFI::MemoryPointer.new(:pointer).write_pointer nil"
|
373
|
-
@post << "GirFFI::ArgHelper.check_error(#{@callarg})"
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
# Argument builder that does nothing. Implements Null Object pattern.
|
378
|
-
class NullArgumentBuilder < ArgumentBuilder
|
379
|
-
def prepare; end
|
380
|
-
def process; end
|
381
|
-
end
|
382
|
-
end
|