gir_ffi 0.0.5 → 0.0.6
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 +8 -0
- data/lib/gir_ffi/arg_helper.rb +55 -37
- data/lib/gir_ffi/argument_builder.rb +382 -0
- data/lib/gir_ffi/builder.rb +4 -4
- data/lib/gir_ffi/class_builder.rb +36 -33
- data/lib/gir_ffi/function_definition_builder.rb +50 -277
- data/lib/gir_ffi/g_object.rb +9 -8
- data/lib/gir_ffi/i_repository.rb +2 -2
- data/lib/gir_ffi/lib.rb +4 -2
- data/lib/gir_ffi/overrides/gobject.rb +43 -41
- data/lib/gir_ffi.rb +0 -34
- data/test/arg_helper_test.rb +19 -13
- data/test/builder_test.rb +0 -1
- data/test/class_base_test.rb +0 -1
- data/test/class_builder_test.rb +0 -1
- data/test/function_definition_builder_test.rb +2 -4
- data/test/{gobject_overrides_test.rb → g_object_overrides_test.rb} +0 -1
- data/test/g_object_test.rb +0 -1
- data/test/{everything_test.rb → generated_everything_test.rb} +13 -14
- data/test/generated_gio_test.rb +32 -0
- data/test/generated_gtk_test.rb +65 -0
- data/test/girffi_test.rb +0 -1
- data/test/gtk_overrides_test.rb +1 -1
- data/test/i_object_info_test.rb +0 -1
- data/test/i_repository_test.rb +0 -1
- data/test/module_builder_test.rb +0 -1
- data/test/test_helper.rb +11 -0
- metadata +13 -8
@@ -1,32 +1,9 @@
|
|
1
|
+
require 'gir_ffi/argument_builder'
|
2
|
+
|
1
3
|
module GirFFI
|
2
4
|
# Implements the creation of a Ruby function definition out of a GIR
|
3
5
|
# IFunctionInfo.
|
4
6
|
class FunctionDefinitionBuilder
|
5
|
-
ArgData = Struct.new(:arginfo, :inarg, :callarg, :retval, :pre, :post, :postpost,
|
6
|
-
:name, :retname)
|
7
|
-
class ArgData
|
8
|
-
def initialize arginfo=nil
|
9
|
-
super
|
10
|
-
self.arginfo = arginfo
|
11
|
-
self.inarg = nil
|
12
|
-
self.callarg = nil
|
13
|
-
self.retval = nil
|
14
|
-
self.retname = nil
|
15
|
-
self.name = nil
|
16
|
-
self.pre = []
|
17
|
-
self.post = []
|
18
|
-
self.postpost = []
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
KEYWORDS = [
|
23
|
-
"alias", "and", "begin", "break", "case", "class", "def", "do",
|
24
|
-
"else", "elsif", "end", "ensure", "false", "for", "if", "in",
|
25
|
-
"module", "next", "nil", "not", "or", "redo", "rescue", "retry",
|
26
|
-
"return", "self", "super", "then", "true", "undef", "unless",
|
27
|
-
"until", "when", "while", "yield"
|
28
|
-
]
|
29
|
-
|
30
7
|
def initialize info, libmodule
|
31
8
|
@info = info
|
32
9
|
@libmodule = libmodule
|
@@ -34,10 +11,19 @@ module GirFFI
|
|
34
11
|
|
35
12
|
def generate
|
36
13
|
setup_accumulators
|
37
|
-
@data = @info.args.map {|
|
38
|
-
@
|
39
|
-
|
40
|
-
|
14
|
+
@data = @info.args.map {|arg| ArgumentBuilder.build self, arg, @libmodule}
|
15
|
+
@rvdata = ReturnValueBuilder.new self, @info
|
16
|
+
|
17
|
+
alldata = @data.dup << @rvdata
|
18
|
+
|
19
|
+
alldata.each {|data|
|
20
|
+
data.prepare
|
21
|
+
idx = data.type.array_length
|
22
|
+
data.length_arg = @data[idx] if idx > -1
|
23
|
+
}
|
24
|
+
|
25
|
+
alldata.each {|data| data.process }
|
26
|
+
|
41
27
|
adjust_accumulators
|
42
28
|
return filled_out_template
|
43
29
|
end
|
@@ -45,266 +31,59 @@ module GirFFI
|
|
45
31
|
private
|
46
32
|
|
47
33
|
def setup_accumulators
|
48
|
-
@inargs = []
|
49
|
-
@callargs = []
|
50
|
-
@retvals = []
|
51
|
-
|
52
|
-
@pre = []
|
53
|
-
@post = []
|
54
|
-
|
55
|
-
@data = []
|
56
|
-
|
57
|
-
@capture = ""
|
58
|
-
|
59
34
|
@varno = 0
|
60
35
|
end
|
61
36
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
case arg.direction
|
68
|
-
when :inout
|
69
|
-
data.inarg = data.name
|
70
|
-
data.retname = data.retval = new_var
|
71
|
-
when :in
|
72
|
-
data.inarg = data.name
|
73
|
-
when :out
|
74
|
-
data.retname = data.retval = new_var
|
75
|
-
else
|
76
|
-
raise ArgumentError
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def process_arg data
|
81
|
-
arg = data.arginfo
|
82
|
-
case arg.direction
|
83
|
-
when :inout
|
84
|
-
process_inout_arg data
|
85
|
-
when :in
|
86
|
-
process_in_arg data
|
87
|
-
when :out
|
88
|
-
process_out_arg data
|
89
|
-
else
|
90
|
-
raise ArgumentError
|
91
|
-
end
|
37
|
+
def adjust_accumulators
|
38
|
+
klass = @info.throws? ? ErrorHandlerBuilder : NullArgumentBuilder
|
39
|
+
@errarg = klass.new(self)
|
40
|
+
@errarg.prepare
|
41
|
+
@errarg.process
|
92
42
|
end
|
93
43
|
|
94
|
-
def
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
case tag
|
102
|
-
when :interface
|
103
|
-
raise NotImplementedError
|
104
|
-
when :array
|
105
|
-
tag = arg.type.param_type(0).tag
|
106
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.#{tag}_array_to_inoutptr #{data.inarg}"
|
107
|
-
if arg.type.array_length > -1
|
108
|
-
idx = arg.type.array_length
|
109
|
-
lendata = @data[idx]
|
110
|
-
rv = lendata.retval
|
111
|
-
lendata.retval = nil
|
112
|
-
lname = lendata.inarg
|
113
|
-
lendata.inarg = nil
|
114
|
-
lendata.pre.unshift "#{lname} = #{data.inarg}.length"
|
115
|
-
data.post << "#{data.retval} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{data.callarg}, #{rv}"
|
116
|
-
if tag == :utf8
|
117
|
-
data.post << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{data.callarg}, #{rv}"
|
118
|
-
else
|
119
|
-
data.post << "GirFFI::ArgHelper.cleanup_ptr_ptr #{data.callarg}"
|
120
|
-
end
|
121
|
-
else
|
122
|
-
raise NotImplementedError
|
44
|
+
def filled_out_template
|
45
|
+
return <<-CODE
|
46
|
+
def #{@info.name} #{inargs.join(', ')}
|
47
|
+
#{pre.join("\n")}
|
48
|
+
#{capture}::#{@libmodule}.#{@info.symbol} #{callargs.join(', ')}
|
49
|
+
#{post.join("\n")}
|
123
50
|
end
|
124
|
-
|
125
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.#{tag}_to_inoutptr #{data.inarg}"
|
126
|
-
data.post << "#{data.retval} = GirFFI::ArgHelper.outptr_to_#{tag} #{data.callarg}"
|
127
|
-
data.post << "GirFFI::ArgHelper.cleanup_ptr #{data.callarg}"
|
128
|
-
end
|
129
|
-
|
130
|
-
data
|
51
|
+
CODE
|
131
52
|
end
|
132
53
|
|
133
|
-
def
|
134
|
-
|
135
|
-
type = arg.type
|
136
|
-
tag = type.tag
|
137
|
-
|
138
|
-
case tag
|
139
|
-
when :interface
|
140
|
-
iface = arg.type.interface
|
141
|
-
if arg.caller_allocates?
|
142
|
-
data.pre << "#{data.callarg} = #{iface.namespace}::#{iface.name}.allocate"
|
143
|
-
data.post << "#{data.retval} = #{data.callarg}"
|
144
|
-
else
|
145
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.pointer_outptr"
|
146
|
-
tmpvar = new_var
|
147
|
-
data.post << "#{tmpvar} = GirFFI::ArgHelper.outptr_to_pointer #{data.callarg}"
|
148
|
-
data.post << "#{data.retval} = #{iface.namespace}::#{iface.name}.wrap #{tmpvar}"
|
149
|
-
end
|
150
|
-
when :array
|
151
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.pointer_outptr"
|
152
|
-
|
153
|
-
tag = arg.type.param_type(0).tag
|
154
|
-
size = type.array_fixed_size
|
155
|
-
idx = type.array_length
|
156
|
-
|
157
|
-
if size <= 0
|
158
|
-
if idx > -1
|
159
|
-
size = @data[idx].retval
|
160
|
-
@data[idx].retval = nil
|
161
|
-
else
|
162
|
-
raise NotImplementedError
|
163
|
-
end
|
164
|
-
end
|
165
|
-
data.postpost << "#{data.retval} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{data.callarg}, #{size}"
|
166
|
-
if arg.ownership_transfer == :everything
|
167
|
-
if tag == :utf8
|
168
|
-
data.postpost << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{data.callarg}, #{rv}"
|
169
|
-
else
|
170
|
-
data.postpost << "GirFFI::ArgHelper.cleanup_ptr_ptr #{data.callarg}"
|
171
|
-
end
|
172
|
-
end
|
173
|
-
else
|
174
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.#{tag}_outptr"
|
175
|
-
data.post << "#{data.retname} = GirFFI::ArgHelper.outptr_to_#{tag} #{data.callarg}"
|
176
|
-
if arg.ownership_transfer == :everything
|
177
|
-
data.post << "GirFFI::ArgHelper.cleanup_ptr #{data.callarg}"
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
data
|
54
|
+
def inargs
|
55
|
+
@data.map(&:inarg).compact
|
182
56
|
end
|
183
57
|
|
184
|
-
def
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
case tag
|
191
|
-
when :interface
|
192
|
-
if type.interface.type == :callback
|
193
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.mapped_callback_args #{data.inarg}"
|
194
|
-
data.pre << "::#{@libmodule}::CALLBACKS << #{data.callarg}"
|
195
|
-
else
|
196
|
-
data.pre << "#{data.callarg} = #{data.inarg}"
|
197
|
-
end
|
198
|
-
when :void
|
199
|
-
raise NotImplementedError unless arg.type.pointer?
|
200
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.object_to_inptr #{data.inarg}"
|
201
|
-
when :array
|
202
|
-
if type.array_fixed_size > 0
|
203
|
-
data.pre << "GirFFI::ArgHelper.check_fixed_array_size #{type.array_fixed_size}, #{data.inarg}, \"#{data.inarg}\""
|
204
|
-
elsif type.array_length > -1
|
205
|
-
idx = type.array_length
|
206
|
-
lenvar = @data[idx].inarg
|
207
|
-
@data[idx].inarg = nil
|
208
|
-
@data[idx].pre.unshift "#{lenvar} = #{data.inarg}.nil? ? 0 : #{data.inarg}.length"
|
209
|
-
end
|
210
|
-
|
211
|
-
tag = arg.type.param_type(0).tag
|
212
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.#{tag}_array_to_inptr #{data.inarg}"
|
213
|
-
unless arg.ownership_transfer == :everything
|
214
|
-
if tag == :utf8
|
215
|
-
data.post << "GirFFI::ArgHelper.cleanup_ptr_ptr #{data.callarg}"
|
216
|
-
else
|
217
|
-
data.post << "GirFFI::ArgHelper.cleanup_ptr #{data.callarg}"
|
218
|
-
end
|
219
|
-
end
|
220
|
-
when :utf8
|
221
|
-
data.pre << "#{data.callarg} = GirFFI::ArgHelper.utf8_to_inptr #{data.name}"
|
222
|
-
# TODO:
|
223
|
-
#data.post << "GirFFI::ArgHelper.cleanup_ptr #{data.callarg}"
|
224
|
-
else
|
225
|
-
data.pre << "#{data.callarg} = #{data.name}"
|
226
|
-
end
|
227
|
-
|
228
|
-
data
|
58
|
+
def callargs
|
59
|
+
ca = @data.map(&:callarg)
|
60
|
+
ca << @errarg.callarg
|
61
|
+
ca.unshift "self" if @info.method?
|
62
|
+
ca.compact
|
229
63
|
end
|
230
64
|
|
231
|
-
def
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
cvar = new_var
|
237
|
-
@capture = "#{cvar} = "
|
238
|
-
|
239
|
-
case tag
|
240
|
-
when :interface
|
241
|
-
interface = type.interface
|
242
|
-
namespace = interface.namespace
|
243
|
-
name = interface.name
|
244
|
-
GirFFI::Builder.build_class namespace, name
|
245
|
-
retval = new_var
|
246
|
-
@rvdata.post << "#{retval} = ::#{namespace}::#{name}.wrap(#{cvar})"
|
247
|
-
if interface.type == :object
|
248
|
-
@rvdata.post << "GirFFI::ArgHelper.sink_if_floating(#{retval})"
|
249
|
-
end
|
250
|
-
@rvdata.retval = retval
|
251
|
-
when :array
|
252
|
-
tag = type.param_type(0).tag
|
253
|
-
size = type.array_fixed_size
|
254
|
-
idx = type.array_length
|
65
|
+
def pre
|
66
|
+
pr = @data.map(&:pre)
|
67
|
+
pr << @errarg.pre
|
68
|
+
pr.flatten
|
69
|
+
end
|
255
70
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
elsif idx > -1
|
260
|
-
lendata = @data[idx]
|
261
|
-
rv = lendata.retval
|
262
|
-
lendata.retval = nil
|
263
|
-
@rvdata.post << "#{retval} = GirFFI::ArgHelper.ptr_to_#{tag}_array #{cvar}, #{rv}"
|
264
|
-
end
|
265
|
-
@rvdata.retval = retval
|
71
|
+
def capture
|
72
|
+
if (cv = @rvdata.cvar)
|
73
|
+
"#{cv} = "
|
266
74
|
else
|
267
|
-
|
75
|
+
""
|
268
76
|
end
|
269
77
|
end
|
270
78
|
|
271
|
-
def
|
272
|
-
@
|
273
|
-
@
|
274
|
-
@inargs << data.inarg
|
275
|
-
@callargs << data.callarg
|
276
|
-
@retvals << data.retval
|
277
|
-
@pre += data.pre
|
278
|
-
@post += data.post
|
279
|
-
end
|
280
|
-
@data.each do |data|
|
281
|
-
@post += data.postpost
|
282
|
-
end
|
283
|
-
@post += @rvdata.post
|
79
|
+
def post
|
80
|
+
po = (@data.map(&:post) + @data.map(&:postpost) + @rvdata.post)
|
81
|
+
po.unshift @errarg.post
|
284
82
|
|
285
|
-
|
286
|
-
|
287
|
-
@pre << "#{errvar} = FFI::MemoryPointer.new(:pointer).write_pointer nil"
|
288
|
-
@post.unshift "GirFFI::ArgHelper.check_error(#{errvar})"
|
289
|
-
@callargs << errvar
|
290
|
-
end
|
291
|
-
|
292
|
-
@retvals = @retvals.compact
|
293
|
-
@post << "return #{@retvals.compact.join(', ')}" unless @retvals.empty?
|
83
|
+
retvals = ([@rvdata.retval] + @data.map(&:retval)).compact
|
84
|
+
po << "return #{retvals.join(', ')}" unless retvals.empty?
|
294
85
|
|
295
|
-
|
296
|
-
@callargs.unshift "self"
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
def filled_out_template
|
301
|
-
return <<-CODE
|
302
|
-
def #{@info.name} #{@inargs.compact.join(', ')}
|
303
|
-
#{@pre.join("\n")}
|
304
|
-
#{@capture}::#{@libmodule}.#{@info.symbol} #{@callargs.compact.join(', ')}
|
305
|
-
#{@post.join("\n")}
|
306
|
-
end
|
307
|
-
CODE
|
86
|
+
po.flatten
|
308
87
|
end
|
309
88
|
|
310
89
|
def new_var
|
@@ -312,12 +91,6 @@ module GirFFI
|
|
312
91
|
"_v#{@varno}"
|
313
92
|
end
|
314
93
|
|
315
|
-
|
316
|
-
if KEYWORDS.include? name
|
317
|
-
"#{name}_"
|
318
|
-
else
|
319
|
-
name
|
320
|
-
end
|
321
|
-
end
|
94
|
+
public :new_var
|
322
95
|
end
|
323
96
|
end
|
data/lib/gir_ffi/g_object.rb
CHANGED
@@ -1,25 +1,26 @@
|
|
1
1
|
require 'ffi'
|
2
2
|
|
3
3
|
module GirFFI
|
4
|
+
# TODO: Rename to avoid constant lookup issues (and confusion).
|
4
5
|
module GObject
|
5
6
|
def self.type_init
|
6
7
|
Lib::g_type_init
|
7
8
|
end
|
8
9
|
|
9
|
-
def self.object_ref
|
10
|
-
Lib::g_object_ref
|
10
|
+
def self.object_ref obj
|
11
|
+
Lib::g_object_ref obj.to_ptr
|
11
12
|
end
|
12
13
|
|
13
|
-
def self.object_ref_sink
|
14
|
-
Lib::g_object_ref_sink
|
14
|
+
def self.object_ref_sink obj
|
15
|
+
Lib::g_object_ref_sink obj.to_ptr
|
15
16
|
end
|
16
17
|
|
17
|
-
def self.object_unref
|
18
|
-
Lib::g_object_unref
|
18
|
+
def self.object_unref obj
|
19
|
+
Lib::g_object_unref obj.to_ptr
|
19
20
|
end
|
20
21
|
|
21
|
-
def self.object_is_floating
|
22
|
-
Lib::g_object_is_floating
|
22
|
+
def self.object_is_floating obj
|
23
|
+
Lib::g_object_is_floating obj.to_ptr
|
23
24
|
end
|
24
25
|
|
25
26
|
module Lib
|
data/lib/gir_ffi/i_repository.rb
CHANGED
data/lib/gir_ffi/lib.rb
CHANGED
@@ -99,8 +99,10 @@ module GirFFI
|
|
99
99
|
# gobject-introspection version 0.9.0 and 0.9.1. Therefore, we need to
|
100
100
|
# retrieve the correct values before declaring the ITypeTag enum.
|
101
101
|
attach_function :tmp_type_tag_to_string, :g_type_tag_to_string, [:int], :string
|
102
|
-
|
103
|
-
|
102
|
+
type_tag_map = (0..31).map { |id|
|
103
|
+
[tmp_type_tag_to_string(id).to_sym, id]
|
104
|
+
}.flatten
|
105
|
+
enum :ITypeTag, type_tag_map
|
104
106
|
|
105
107
|
# Now, attach g_type_tag_to_string again under its own name with an
|
106
108
|
# improved signature.
|
@@ -24,6 +24,8 @@ module GirFFI
|
|
24
24
|
when true, false
|
25
25
|
gvalue.init ::GObject.type_from_name("gboolean")
|
26
26
|
gvalue.set_boolean val
|
27
|
+
else
|
28
|
+
nil
|
27
29
|
end
|
28
30
|
gvalue
|
29
31
|
end
|
@@ -41,31 +43,14 @@ module GirFFI
|
|
41
43
|
|
42
44
|
def signal_emit object, signal, *args
|
43
45
|
type = type_from_instance object
|
44
|
-
|
45
46
|
id = signal_lookup signal, type
|
46
47
|
|
47
|
-
val = ::GObject::Value.new
|
48
|
-
val.init type
|
49
|
-
val.set_instance object
|
50
|
-
|
51
|
-
q = ::GObject::SignalQuery.new
|
52
|
-
signal_query id, q
|
53
|
-
|
54
|
-
use_ret = (q[:return_type] != ::GObject.type_from_name("void"))
|
55
|
-
if use_ret
|
56
|
-
rval = ::GObject::Value.new
|
57
|
-
rval.init q[:return_type]
|
58
|
-
end
|
59
|
-
|
60
48
|
arr = Helper.signal_arguments_to_gvalue_array signal, object, *args
|
49
|
+
rval = Helper.gvalue_for_signal_return_value signal, object
|
61
50
|
|
62
51
|
signal_emitv arr[:values], id, 0, rval
|
63
52
|
|
64
|
-
|
65
|
-
rval
|
66
|
-
else
|
67
|
-
nil
|
68
|
-
end
|
53
|
+
rval
|
69
54
|
end
|
70
55
|
|
71
56
|
def signal_connect object, signal, data=nil, &block
|
@@ -79,7 +64,7 @@ module GirFFI
|
|
79
64
|
|
80
65
|
rettype = GirFFI::Builder.itypeinfo_to_ffitype sig.return_type
|
81
66
|
|
82
|
-
argtypes = [:pointer] + sig.args.map {|
|
67
|
+
argtypes = [:pointer] + sig.args.map {|arg| :pointer} + [:pointer]
|
83
68
|
|
84
69
|
callback = FFI::Function.new rettype, argtypes,
|
85
70
|
&(Helper.signal_callback_args(sig, object.class, &block))
|
@@ -107,32 +92,49 @@ module GirFFI
|
|
107
92
|
arr.append val
|
108
93
|
val.unset
|
109
94
|
|
110
|
-
sig.args.zip(rest).each do |
|
111
|
-
info, arg
|
112
|
-
|
113
|
-
interface = info.type.interface
|
114
|
-
|
115
|
-
val = ::GObject::Value.new
|
116
|
-
val.init info.type.interface.g_type
|
117
|
-
case interface.type
|
118
|
-
when :struct
|
119
|
-
val.set_boxed arg
|
120
|
-
when :object
|
121
|
-
val.set_instance arg
|
122
|
-
else
|
123
|
-
raise NotImplementedError, interface.type
|
124
|
-
end
|
125
|
-
|
126
|
-
arr.append val
|
127
|
-
|
128
|
-
val.unset
|
95
|
+
sig.args.zip(rest).each do |info, arg|
|
96
|
+
arr.append signal_argument_to_gvalue info, arg
|
97
|
+
end
|
129
98
|
|
99
|
+
arr
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.signal_argument_to_gvalue info, arg
|
103
|
+
if info.type.tag == :interface
|
104
|
+
interface = info.type.interface
|
105
|
+
|
106
|
+
val = ::GObject::Value.new
|
107
|
+
val.init info.type.interface.g_type
|
108
|
+
case interface.type
|
109
|
+
when :struct
|
110
|
+
val.set_boxed arg
|
111
|
+
when :object
|
112
|
+
val.set_instance arg
|
130
113
|
else
|
131
|
-
raise NotImplementedError
|
114
|
+
raise NotImplementedError, interface.type
|
132
115
|
end
|
116
|
+
|
117
|
+
return val
|
118
|
+
else
|
119
|
+
raise NotImplementedError
|
133
120
|
end
|
121
|
+
end
|
134
122
|
|
135
|
-
|
123
|
+
def self.gvalue_for_signal_return_value signal, object
|
124
|
+
type = ::GObject.type_from_instance object
|
125
|
+
|
126
|
+
# TODO: Use same signal info as signal_arguments_to_gvalue_array
|
127
|
+
id = ::GObject.signal_lookup signal, type
|
128
|
+
|
129
|
+
query = ::GObject::SignalQuery.new
|
130
|
+
::GObject.signal_query id, query
|
131
|
+
|
132
|
+
use_ret = (query[:return_type] != ::GObject.type_from_name("void"))
|
133
|
+
if use_ret
|
134
|
+
rval = ::GObject::Value.new
|
135
|
+
rval.init query[:return_type]
|
136
|
+
end
|
137
|
+
rval
|
136
138
|
end
|
137
139
|
|
138
140
|
def self.cast_back_signal_arguments signalinfo, klass, *args
|
data/lib/gir_ffi.rb
CHANGED
@@ -1,36 +1,3 @@
|
|
1
|
-
|
2
|
-
module GirFFI
|
3
|
-
|
4
|
-
# :stopdoc:
|
5
|
-
VERSION = '0.0.1'
|
6
|
-
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
|
-
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
8
|
-
# :startdoc:
|
9
|
-
|
10
|
-
# Returns the version string for the library.
|
11
|
-
#
|
12
|
-
def self.version
|
13
|
-
VERSION
|
14
|
-
end
|
15
|
-
|
16
|
-
# Returns the library path for the module. If any arguments are given,
|
17
|
-
# they will be joined to the end of the libray path using
|
18
|
-
# <tt>File.join</tt>.
|
19
|
-
#
|
20
|
-
def self.libpath( *args )
|
21
|
-
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Returns the lpath for the module. If any arguments are given,
|
25
|
-
# they will be joined to the end of the path using
|
26
|
-
# <tt>File.join</tt>.
|
27
|
-
#
|
28
|
-
def self.path( *args )
|
29
|
-
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
1
|
require 'gir_ffi/i_repository'
|
35
2
|
require 'gir_ffi/builder'
|
36
3
|
|
@@ -40,4 +7,3 @@ module GirFFI
|
|
40
7
|
GirFFI::Builder.build_module module_name
|
41
8
|
end
|
42
9
|
end
|
43
|
-
# EOF
|
data/test/arg_helper_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.expand_path('test_helper.rb', File.dirname(__FILE__))
|
2
|
-
require 'gir_ffi/arg_helper'
|
3
2
|
|
4
3
|
class ArgHelperTest < Test::Unit::TestCase
|
5
4
|
context "The int_to_inoutptr method's return value" do
|
@@ -7,8 +6,8 @@ class ArgHelperTest < Test::Unit::TestCase
|
|
7
6
|
@result = GirFFI::ArgHelper.int_to_inoutptr 24
|
8
7
|
end
|
9
8
|
|
10
|
-
should "be
|
11
|
-
|
9
|
+
should "be an FFI::Pointer" do
|
10
|
+
assert_instance_of FFI::Pointer, @result
|
12
11
|
end
|
13
12
|
|
14
13
|
should "hold a pointer to the correct input value" do
|
@@ -22,8 +21,8 @@ class ArgHelperTest < Test::Unit::TestCase
|
|
22
21
|
@result = GirFFI::ArgHelper.utf8_array_to_inoutptr ["foo", "bar", "baz"]
|
23
22
|
end
|
24
23
|
|
25
|
-
should "return
|
26
|
-
|
24
|
+
should "return an FFI::Pointer" do
|
25
|
+
assert_instance_of FFI::Pointer, @result
|
27
26
|
end
|
28
27
|
|
29
28
|
should "return a pointer to an array of pointers to strings" do
|
@@ -81,15 +80,16 @@ class ArgHelperTest < Test::Unit::TestCase
|
|
81
80
|
@ptr.write_pointer p
|
82
81
|
end
|
83
82
|
|
84
|
-
should "
|
83
|
+
should "render the null pointer as nil" do
|
85
84
|
assert_equal ["one", "two", nil],
|
86
85
|
GirFFI::ArgHelper.outptr_to_utf8_array(@ptr, 3)
|
87
86
|
end
|
88
87
|
end
|
89
88
|
|
90
|
-
context "when called with
|
89
|
+
context "when called with a pointer to null" do
|
91
90
|
should "return nil" do
|
92
|
-
|
91
|
+
ptr = GirFFI::ArgHelper.pointer_pointer.write_pointer nil
|
92
|
+
assert_nil GirFFI::ArgHelper.outptr_to_utf8_array(ptr, 0)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -119,12 +119,18 @@ class ArgHelperTest < Test::Unit::TestCase
|
|
119
119
|
end
|
120
120
|
|
121
121
|
context "The object_pointer_to_object method" do
|
122
|
-
|
122
|
+
setup do
|
123
123
|
GirFFI.setup :Everything
|
124
|
-
o = Everything::TestSubObj.new
|
125
|
-
o2 = GirFFI::ArgHelper.object_pointer_to_object o.to_ptr
|
126
|
-
|
127
|
-
|
124
|
+
@o = Everything::TestSubObj.new
|
125
|
+
@o2 = GirFFI::ArgHelper.object_pointer_to_object @o.to_ptr
|
126
|
+
end
|
127
|
+
|
128
|
+
should "return an object of the correct class" do
|
129
|
+
assert_instance_of Everything::TestSubObj, @o2
|
130
|
+
end
|
131
|
+
|
132
|
+
should "return an object pointing to the original struct" do
|
133
|
+
assert_equal @o.to_ptr, @o2.to_ptr
|
128
134
|
end
|
129
135
|
end
|
130
136
|
end
|
data/test/builder_test.rb
CHANGED
data/test/class_base_test.rb
CHANGED