gir_ffi 0.0.8 → 0.0.9
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 +11 -0
- data/TODO.rdoc +5 -0
- data/examples/01_empty_window.rb +0 -1
- data/examples/02_hello_world.rb +0 -1
- data/examples/03_upgraded_hello_world.rb +0 -1
- data/examples/04_webkit.rb +0 -1
- data/lib/gir_ffi/arg_helper.rb +231 -94
- data/lib/gir_ffi/builder/argument.rb +372 -46
- data/lib/gir_ffi/builder/module.rb +25 -10
- data/lib/gir_ffi/builder/type/constant.rb +39 -0
- data/lib/gir_ffi/builder/type/enum.rb +15 -5
- data/lib/gir_ffi/builder/type/registered_type.rb +25 -6
- data/lib/gir_ffi/builder/type/struct.rb +1 -9
- data/lib/gir_ffi/builder/type/union.rb +5 -0
- data/lib/gir_ffi/builder/type.rb +13 -14
- data/lib/gir_ffi/builder.rb +7 -4
- data/lib/gir_ffi/builder_helper.rb +4 -3
- data/lib/gir_ffi/i_base_info.rb +4 -0
- data/lib/gir_ffi/i_constant_info.rb +9 -0
- data/lib/gir_ffi/i_registered_type_info.rb +0 -1
- data/lib/gir_ffi/i_repository.rb +8 -2
- data/lib/gir_ffi/i_type_info.rb +7 -0
- data/lib/gir_ffi/lib.rb +41 -3
- data/lib/gir_ffi/overrides/glib.rb +188 -4
- data/lib/gir_ffi/overrides/gobject.rb +16 -5
- data/tasks/test.rake +1 -1
- data/test/arg_helper_test.rb +5 -5
- data/test/builder_test.rb +64 -41
- data/test/class_base_test.rb +1 -1
- data/test/function_definition_builder_test.rb +24 -2
- data/test/g_object_overrides_test.rb +1 -3
- data/test/g_object_test.rb +1 -1
- data/test/generated_gimarshallingtests_test.rb +1677 -0
- data/test/generated_gio_test.rb +1 -1
- data/test/generated_gtk_test.rb +31 -2
- data/test/generated_regress_test.rb +278 -54
- data/test/girffi_test.rb +20 -5
- data/test/glib_overrides_test.rb +81 -0
- data/test/gtk_overrides_test.rb +2 -3
- data/test/i_object_info_test.rb +1 -1
- data/test/i_repository_test.rb +3 -4
- data/test/lib/Makefile.am +18 -2
- data/test/module_builder_test.rb +1 -1
- data/test/test_helper.rb +88 -5
- data/test/type_builder_test.rb +7 -10
- metadata +16 -13
@@ -46,23 +46,19 @@ module GirFFI::Builder
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def type_tag
|
49
|
-
type_info.tag
|
49
|
+
tag = type_info.tag
|
50
|
+
tag == :GType ? :gtype : tag
|
50
51
|
end
|
51
52
|
|
52
|
-
def subtype_tag
|
53
|
-
st = type_info.param_type(
|
53
|
+
def subtype_tag index=0
|
54
|
+
st = type_info.param_type(index)
|
54
55
|
t = st.tag
|
55
56
|
case t
|
56
57
|
when :GType
|
57
58
|
return :gtype
|
58
59
|
when :interface
|
59
|
-
|
60
|
-
|
61
|
-
if iface.name == 'Value' and iface.namespace == 'GObject'
|
62
|
-
return :gvalue
|
63
|
-
else
|
64
|
-
raise NotImplementedError
|
65
|
-
end
|
60
|
+
return :interface_pointer if st.pointer?
|
61
|
+
return :interface
|
66
62
|
else
|
67
63
|
return t
|
68
64
|
end
|
@@ -70,7 +66,12 @@ module GirFFI::Builder
|
|
70
66
|
|
71
67
|
def argument_class_name
|
72
68
|
iface = type_info.interface
|
73
|
-
"::#{iface.
|
69
|
+
"::#{iface.safe_namespace}::#{iface.name}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def subtype_class_name index=0
|
73
|
+
iface = type_info.param_type(index).interface
|
74
|
+
"::#{iface.safe_namespace}::#{iface.name}"
|
74
75
|
end
|
75
76
|
|
76
77
|
def array_size
|
@@ -130,9 +131,15 @@ module GirFFI::Builder
|
|
130
131
|
when :void
|
131
132
|
VoidInArgument
|
132
133
|
when :array
|
133
|
-
|
134
|
+
if type.array_type == :c
|
135
|
+
CArrayInArgument
|
136
|
+
else
|
137
|
+
RegularInArgument
|
138
|
+
end
|
134
139
|
when :glist, :gslist
|
135
140
|
ListInArgument
|
141
|
+
when :ghash
|
142
|
+
HashTableInArgument
|
136
143
|
when :utf8
|
137
144
|
Utf8InArgument
|
138
145
|
else
|
@@ -161,7 +168,7 @@ module GirFFI::Builder
|
|
161
168
|
end
|
162
169
|
|
163
170
|
# Implements argument processing for array arguments with direction :in.
|
164
|
-
class
|
171
|
+
class CArrayInArgument < InArgument
|
165
172
|
def post
|
166
173
|
unless @arginfo.ownership_transfer == :everything
|
167
174
|
if subtype_tag == :utf8
|
@@ -183,13 +190,21 @@ module GirFFI::Builder
|
|
183
190
|
end
|
184
191
|
end
|
185
192
|
|
186
|
-
# Implements argument processing for gslist arguments with
|
193
|
+
# Implements argument processing for glist and gslist arguments with
|
194
|
+
# direction :in.
|
187
195
|
class ListInArgument < InArgument
|
188
196
|
def pre
|
189
197
|
[ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name}" ]
|
190
198
|
end
|
191
199
|
end
|
192
200
|
|
201
|
+
# Implements argument processing for ghash arguments with direction :in.
|
202
|
+
class HashTableInArgument < InArgument
|
203
|
+
def pre
|
204
|
+
[ "#{@callarg} = GirFFI::ArgHelper.hash_to_ghash #{subtype_tag(0).inspect}, #{subtype_tag(1).inspect}, #{@name}" ]
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
193
208
|
# Implements argument processing for UTF8 string arguments with direction
|
194
209
|
# :in.
|
195
210
|
class Utf8InArgument < InArgument
|
@@ -228,13 +243,32 @@ module GirFFI::Builder
|
|
228
243
|
end
|
229
244
|
|
230
245
|
def self.build function_builder, arginfo, libmodule
|
246
|
+
type = arginfo.argument_type
|
231
247
|
klass = case arginfo.argument_type.tag
|
232
248
|
when :interface
|
233
|
-
|
249
|
+
case type.interface.info_type
|
250
|
+
when :enum, :flags
|
251
|
+
EnumOutArgument
|
252
|
+
else
|
253
|
+
InterfaceOutArgument
|
254
|
+
end
|
234
255
|
when :array
|
235
|
-
|
256
|
+
if type.zero_terminated?
|
257
|
+
StrvOutArgument
|
258
|
+
else
|
259
|
+
case type.array_type
|
260
|
+
when :c
|
261
|
+
CArrayOutArgument
|
262
|
+
when :array
|
263
|
+
ArrayOutArgument
|
264
|
+
end
|
265
|
+
end
|
266
|
+
when :glist
|
267
|
+
ListOutArgument
|
236
268
|
when :gslist
|
237
|
-
|
269
|
+
SListOutArgument
|
270
|
+
when :ghash
|
271
|
+
HashTableOutArgument
|
238
272
|
else
|
239
273
|
RegularOutArgument
|
240
274
|
end
|
@@ -242,6 +276,22 @@ module GirFFI::Builder
|
|
242
276
|
end
|
243
277
|
end
|
244
278
|
|
279
|
+
# Implements argument processing for arguments with direction
|
280
|
+
# :out that are enums
|
281
|
+
class EnumOutArgument < OutArgument
|
282
|
+
def post
|
283
|
+
pst = [ "#{@retname} = #{argument_class_name}[GirFFI::ArgHelper.outptr_to_gint32 #{@callarg}]" ]
|
284
|
+
if @arginfo.ownership_transfer == :everything
|
285
|
+
pst << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
286
|
+
end
|
287
|
+
pst
|
288
|
+
end
|
289
|
+
|
290
|
+
def pre
|
291
|
+
[ "#{@callarg} = GirFFI::ArgHelper.gint32_outptr" ]
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
245
295
|
# Implements argument processing for interface arguments with direction
|
246
296
|
# :out (structs, objects, etc.).
|
247
297
|
class InterfaceOutArgument < OutArgument
|
@@ -264,7 +314,7 @@ module GirFFI::Builder
|
|
264
314
|
|
265
315
|
# Implements argument processing for array arguments with direction
|
266
316
|
# :out.
|
267
|
-
class
|
317
|
+
class CArrayOutArgument < OutArgument
|
268
318
|
def pre
|
269
319
|
[ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
|
270
320
|
end
|
@@ -273,11 +323,20 @@ module GirFFI::Builder
|
|
273
323
|
size = array_size
|
274
324
|
tag = subtype_tag
|
275
325
|
|
276
|
-
pp = [
|
326
|
+
pp = []
|
327
|
+
|
328
|
+
if tag == :interface or tag == :interface_pointer
|
329
|
+
pp << "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{subtype_class_name}, #{@callarg}, #{size}"
|
330
|
+
else
|
331
|
+
pp << "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{size}"
|
332
|
+
end
|
277
333
|
|
278
334
|
if @arginfo.ownership_transfer == :everything
|
279
|
-
|
335
|
+
case tag
|
336
|
+
when :utf8
|
280
337
|
pp << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{size}"
|
338
|
+
when :interface
|
339
|
+
pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
281
340
|
else
|
282
341
|
pp << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
|
283
342
|
end
|
@@ -287,17 +346,82 @@ module GirFFI::Builder
|
|
287
346
|
end
|
288
347
|
end
|
289
348
|
|
349
|
+
# Implements argument processing for strv arguments with direction
|
350
|
+
# :out.
|
351
|
+
class StrvOutArgument < OutArgument
|
352
|
+
def pre
|
353
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
|
354
|
+
end
|
355
|
+
|
356
|
+
def postpost
|
357
|
+
[ "#{@retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{@callarg}" ]
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
# Implements argument processing for GArray arguments with direction
|
362
|
+
# :out.
|
363
|
+
class ArrayOutArgument < OutArgument
|
364
|
+
def pre
|
365
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
|
366
|
+
end
|
367
|
+
|
368
|
+
def post
|
369
|
+
tag = subtype_tag
|
370
|
+
etype = GirFFI::Builder::TAG_TYPE_MAP[tag] || tag
|
371
|
+
|
372
|
+
pp = []
|
373
|
+
|
374
|
+
pp << "#{@retname} = GLib::Array.wrap(GirFFI::ArgHelper.outptr_to_pointer #{@callarg})"
|
375
|
+
pp << "#{@retname}.element_type = #{etype.inspect}"
|
376
|
+
|
377
|
+
if @arginfo.ownership_transfer == :everything
|
378
|
+
pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
379
|
+
end
|
380
|
+
|
381
|
+
pp
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
# Implements argument processing for glist arguments with direction
|
386
|
+
# :out.
|
387
|
+
class ListOutArgument < OutArgument
|
388
|
+
def pre
|
389
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
|
390
|
+
end
|
391
|
+
|
392
|
+
def post
|
393
|
+
elm_t = subtype_tag.inspect
|
394
|
+
[ "#{@retname} = GLib::List.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
290
398
|
# Implements argument processing for gslist arguments with direction
|
291
399
|
# :out.
|
292
|
-
class
|
400
|
+
class SListOutArgument < OutArgument
|
401
|
+
def pre
|
402
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
|
403
|
+
end
|
404
|
+
|
405
|
+
def post
|
406
|
+
elm_t = subtype_tag.inspect
|
407
|
+
[ "#{@retname} = GLib::SList.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
# Implements argument processing for ghash arguments with direction
|
412
|
+
# :out.
|
413
|
+
class HashTableOutArgument < OutArgument
|
293
414
|
def pre
|
294
415
|
[ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
|
295
416
|
end
|
296
417
|
|
297
418
|
def postpost
|
298
|
-
|
419
|
+
key_t = subtype_tag(0).inspect
|
420
|
+
val_t = subtype_tag(1).inspect
|
421
|
+
[ "#{@retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
|
299
422
|
end
|
300
423
|
end
|
424
|
+
|
301
425
|
# Implements argument processing for arguments with direction
|
302
426
|
# :out that are neither arrays nor 'interfaces'.
|
303
427
|
class RegularOutArgument < OutArgument
|
@@ -324,13 +448,32 @@ module GirFFI::Builder
|
|
324
448
|
end
|
325
449
|
|
326
450
|
def self.build function_builder, arginfo, libmodule
|
327
|
-
|
328
|
-
|
329
|
-
klass = case arginfo.argument_type.tag
|
451
|
+
type = arginfo.argument_type
|
452
|
+
klass = case type.tag
|
330
453
|
when :interface
|
331
|
-
|
454
|
+
case type.interface.info_type
|
455
|
+
when :enum, :flags
|
456
|
+
EnumInOutArgument
|
457
|
+
else
|
458
|
+
InterfaceInOutArgument
|
459
|
+
end
|
332
460
|
when :array
|
333
|
-
|
461
|
+
if type.zero_terminated?
|
462
|
+
StrvInOutArgument
|
463
|
+
else
|
464
|
+
case type.array_type
|
465
|
+
when :c
|
466
|
+
CArrayInOutArgument
|
467
|
+
when :array
|
468
|
+
ArrayInOutArgument
|
469
|
+
end
|
470
|
+
end
|
471
|
+
when :glist
|
472
|
+
ListInOutArgument
|
473
|
+
when :gslist
|
474
|
+
SListInOutArgument
|
475
|
+
when :ghash
|
476
|
+
HashTableInOutArgument
|
334
477
|
else
|
335
478
|
RegularInOutArgument
|
336
479
|
end
|
@@ -339,34 +482,147 @@ module GirFFI::Builder
|
|
339
482
|
end
|
340
483
|
end
|
341
484
|
|
342
|
-
# Implements argument processing for
|
485
|
+
# Implements argument processing for arguments with direction
|
486
|
+
# :inout that are enums.
|
487
|
+
class EnumInOutArgument < InOutArgument
|
488
|
+
def pre
|
489
|
+
pr = []
|
490
|
+
pr << "#{@callarg} = GirFFI::ArgHelper.gint32_to_inoutptr #{argument_class_name}[#{@name}]"
|
491
|
+
pr
|
492
|
+
end
|
493
|
+
|
494
|
+
def post
|
495
|
+
[ "#{@retname} = #{argument_class_name}[GirFFI::ArgHelper.outptr_to_gint32 #{@callarg}]",
|
496
|
+
"GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
# Implements argument processing for interface arguments with direction
|
501
|
+
# :inout (structs, objects, etc.).
|
502
|
+
class InterfaceInOutArgument < InOutArgument
|
503
|
+
def pre
|
504
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr #{@name}.to_ptr" ]
|
505
|
+
end
|
506
|
+
|
507
|
+
def post
|
508
|
+
[ "#{@retname} = #{argument_class_name}.wrap(GirFFI::ArgHelper.outptr_to_pointer #{@callarg})",
|
509
|
+
"GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
# Implements argument processing for strv arguments with direction
|
343
514
|
# :inout.
|
344
|
-
class
|
515
|
+
class StrvInOutArgument < InOutArgument
|
345
516
|
def pre
|
346
517
|
[ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_inoutptr #{@name}" ]
|
347
518
|
end
|
348
519
|
|
349
520
|
def post
|
521
|
+
[ "#{@retname} = GirFFI::ArgHelper.outptr_strv_to_utf8_array #{@callarg}" ]
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
# Implements argument processing for array arguments with direction
|
526
|
+
# :inout.
|
527
|
+
class CArrayInOutArgument < InOutArgument
|
528
|
+
def pre
|
529
|
+
[ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_inoutptr #{@name}" ]
|
530
|
+
end
|
531
|
+
|
532
|
+
def postpost
|
350
533
|
tag = subtype_tag
|
351
|
-
size =
|
534
|
+
size = array_size
|
352
535
|
pst = [ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{size}" ]
|
353
|
-
if
|
354
|
-
pst << "GirFFI::ArgHelper.
|
536
|
+
if @arginfo.ownership_transfer == :nothing
|
537
|
+
pst << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
355
538
|
else
|
356
|
-
|
539
|
+
if tag == :utf8
|
540
|
+
pst << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{size}"
|
541
|
+
else
|
542
|
+
pst << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
|
543
|
+
end
|
357
544
|
end
|
358
545
|
pst
|
359
546
|
end
|
360
547
|
end
|
361
548
|
|
362
|
-
# Implements argument processing for arguments with direction
|
363
|
-
# :
|
364
|
-
class
|
549
|
+
# Implements argument processing for GArray arguments with direction
|
550
|
+
# :out.
|
551
|
+
class ArrayInOutArgument < InOutArgument
|
552
|
+
def pre
|
553
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr #{@name}" ]
|
554
|
+
end
|
555
|
+
|
365
556
|
def post
|
366
|
-
|
367
|
-
|
557
|
+
tag = subtype_tag
|
558
|
+
etype = GirFFI::Builder::TAG_TYPE_MAP[tag] || tag
|
559
|
+
|
560
|
+
pp = []
|
561
|
+
|
562
|
+
pp << "#{@retname} = GLib::Array.wrap(GirFFI::ArgHelper.outptr_to_pointer #{@callarg})"
|
563
|
+
pp << "#{@retname}.element_type = #{etype.inspect}"
|
564
|
+
pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
565
|
+
|
566
|
+
pp
|
368
567
|
end
|
568
|
+
end
|
369
569
|
|
570
|
+
# Implements argument processing for glist arguments with direction
|
571
|
+
# :inout.
|
572
|
+
class ListInOutArgument < InOutArgument
|
573
|
+
def pre
|
574
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr(GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name})" ]
|
575
|
+
end
|
576
|
+
|
577
|
+
def post
|
578
|
+
elm_t = subtype_tag.inspect
|
579
|
+
pp = []
|
580
|
+
pp << "#{@retname} = GLib::List.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
|
581
|
+
pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
582
|
+
pp
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
# Implements argument processing for gslist arguments with direction
|
587
|
+
# :inout.
|
588
|
+
# FIXME: Merge code with ListInOutArgument somehow.
|
589
|
+
class SListInOutArgument < InOutArgument
|
590
|
+
def pre
|
591
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr(GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name})" ]
|
592
|
+
end
|
593
|
+
|
594
|
+
def post
|
595
|
+
elm_t = subtype_tag.inspect
|
596
|
+
pp = []
|
597
|
+
pp << "#{@retname} = GLib::SList.wrap #{elm_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
|
598
|
+
pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
599
|
+
pp
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
# Implements argument processing for ghash arguments with direction
|
604
|
+
# :inout.
|
605
|
+
class HashTableInOutArgument < InOutArgument
|
606
|
+
def pre
|
607
|
+
key_t = subtype_tag(0).inspect
|
608
|
+
val_t = subtype_tag(1).inspect
|
609
|
+
[ "#{@callarg} = GirFFI::ArgHelper.pointer_to_inoutptr(GirFFI::ArgHelper.hash_to_ghash(#{key_t}, #{val_t}, #{@name}))" ]
|
610
|
+
end
|
611
|
+
|
612
|
+
def postpost
|
613
|
+
pp = []
|
614
|
+
|
615
|
+
key_t = subtype_tag(0).inspect
|
616
|
+
val_t = subtype_tag(1).inspect
|
617
|
+
pp << "#{@retname} = GLib::HashTable.wrap #{key_t}, #{val_t}, GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
|
618
|
+
pp << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
|
619
|
+
pp
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
# Implements argument processing for arguments with direction
|
624
|
+
# :inout that are neither arrays nor 'interfaces'.
|
625
|
+
class RegularInOutArgument < InOutArgument
|
370
626
|
def pre
|
371
627
|
pr = []
|
372
628
|
if @array_arg
|
@@ -375,6 +631,11 @@ module GirFFI::Builder
|
|
375
631
|
pr << "#{@callarg} = GirFFI::ArgHelper.#{type_tag}_to_inoutptr #{@name}"
|
376
632
|
pr
|
377
633
|
end
|
634
|
+
|
635
|
+
def post
|
636
|
+
[ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{type_tag} #{@callarg}",
|
637
|
+
"GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
|
638
|
+
end
|
378
639
|
end
|
379
640
|
|
380
641
|
# Implements argument processing for return values.
|
@@ -397,7 +658,7 @@ module GirFFI::Builder
|
|
397
658
|
VoidReturnValue
|
398
659
|
when :interface
|
399
660
|
case type.interface.info_type
|
400
|
-
when :interface, :struct
|
661
|
+
when :interface, :struct, :union
|
401
662
|
InterfaceReturnValue
|
402
663
|
when :object
|
403
664
|
if arginfo.constructor?
|
@@ -409,9 +670,24 @@ module GirFFI::Builder
|
|
409
670
|
RegularReturnValue
|
410
671
|
end
|
411
672
|
when :array
|
412
|
-
|
413
|
-
|
673
|
+
if type.zero_terminated?
|
674
|
+
StrvReturnValue
|
675
|
+
else
|
676
|
+
case type.array_type
|
677
|
+
when :c
|
678
|
+
CArrayReturnValue
|
679
|
+
when :array
|
680
|
+
ArrayReturnValue
|
681
|
+
when :byte_array
|
682
|
+
ByteArrayReturnValue
|
683
|
+
end
|
684
|
+
end
|
685
|
+
when :glist
|
414
686
|
ListReturnValue
|
687
|
+
when :gslist
|
688
|
+
SListReturnValue
|
689
|
+
when :ghash
|
690
|
+
HashTableReturnValue
|
415
691
|
else
|
416
692
|
RegularReturnValue
|
417
693
|
end
|
@@ -452,12 +728,12 @@ module GirFFI::Builder
|
|
452
728
|
end
|
453
729
|
|
454
730
|
def post
|
455
|
-
[ "#{@retname} =
|
731
|
+
[ "#{@retname} = self.constructor_wrap(#{@cvar})" ]
|
456
732
|
end
|
457
733
|
end
|
458
734
|
|
459
735
|
# Implements argument processing for array return values.
|
460
|
-
class
|
736
|
+
class CArrayReturnValue < ReturnValue
|
461
737
|
def post
|
462
738
|
size = array_size
|
463
739
|
|
@@ -465,17 +741,67 @@ module GirFFI::Builder
|
|
465
741
|
end
|
466
742
|
end
|
467
743
|
|
468
|
-
# Implements argument processing for
|
744
|
+
# Implements argument processing for NULL-terminated string array return values.
|
745
|
+
class StrvReturnValue < ReturnValue
|
746
|
+
def post
|
747
|
+
[ "#{@retname} = GirFFI::ArgHelper.strv_to_utf8_array #{@cvar}" ]
|
748
|
+
end
|
749
|
+
end
|
750
|
+
|
751
|
+
# Implements argument processing for GList return values.
|
469
752
|
class ListReturnValue < ReturnValue
|
470
753
|
def post
|
471
|
-
|
754
|
+
elm_t = subtype_tag.inspect
|
755
|
+
[ "#{@retname} = GLib::List.wrap(#{elm_t}, #{@cvar})" ]
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
|
+
# Implements argument processing for GSList return values.
|
760
|
+
class SListReturnValue < ReturnValue
|
761
|
+
def post
|
762
|
+
elm_t = subtype_tag.inspect
|
763
|
+
[ "#{@retname} = GLib::SList.wrap(#{elm_t}, #{@cvar})" ]
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
# Implements argument processing for GHashTable return values.
|
768
|
+
class HashTableReturnValue < ReturnValue
|
769
|
+
def post
|
770
|
+
key_t = subtype_tag(0).inspect
|
771
|
+
val_t = subtype_tag(1).inspect
|
772
|
+
[ "#{@retname} = GLib::HashTable.wrap(#{key_t}, #{val_t}, #{@cvar})" ]
|
773
|
+
end
|
774
|
+
end
|
775
|
+
|
776
|
+
# Implements argument processing for GHashTable return values.
|
777
|
+
class ByteArrayReturnValue < ReturnValue
|
778
|
+
def post
|
779
|
+
[ "#{@retname} = GLib::ByteArray.wrap(#{@cvar})" ]
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
# Implements argument processing for GHashTable return values.
|
784
|
+
class ArrayReturnValue < ReturnValue
|
785
|
+
def post
|
786
|
+
tag = subtype_tag
|
787
|
+
etype = GirFFI::Builder::TAG_TYPE_MAP[tag] || tag
|
788
|
+
[ "#{@retname} = GLib::Array.wrap(#{@cvar})",
|
789
|
+
"#{@retname}.element_type = #{etype.inspect}" ]
|
472
790
|
end
|
473
791
|
end
|
474
792
|
|
475
793
|
# Implements argument processing for other return values.
|
476
794
|
class RegularReturnValue < ReturnValue
|
477
795
|
def retval
|
478
|
-
|
796
|
+
if RUBY_VERSION < "1.9"
|
797
|
+
@cvar
|
798
|
+
else
|
799
|
+
if type_tag == :utf8
|
800
|
+
"#{@cvar}.force_encoding('utf-8')"
|
801
|
+
else
|
802
|
+
@cvar
|
803
|
+
end
|
804
|
+
end
|
479
805
|
end
|
480
806
|
end
|
481
807
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'gir_ffi/builder_helper'
|
2
2
|
require 'gir_ffi/module_base'
|
3
|
+
require 'gir_ffi/builder/function'
|
3
4
|
|
4
5
|
module GirFFI
|
5
6
|
# Builds a module based on information found in the introspection
|
@@ -38,9 +39,15 @@ module GirFFI
|
|
38
39
|
Builder.build_class info
|
39
40
|
end
|
40
41
|
|
41
|
-
private
|
42
|
-
|
43
42
|
def build_module
|
43
|
+
unless defined? @module
|
44
|
+
build_dependencies
|
45
|
+
build_module_non_recursive
|
46
|
+
end
|
47
|
+
@module
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_module_non_recursive
|
44
51
|
unless defined? @module
|
45
52
|
instantiate_module
|
46
53
|
setup_lib_for_ffi
|
@@ -49,6 +56,16 @@ module GirFFI
|
|
49
56
|
@module
|
50
57
|
end
|
51
58
|
|
59
|
+
private
|
60
|
+
|
61
|
+
def build_dependencies
|
62
|
+
deps = gir.dependencies @namespace
|
63
|
+
deps.each {|dep|
|
64
|
+
name, version = dep.split '-'
|
65
|
+
Builder.build_module_non_recursive name, version
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
52
69
|
def instantiate_module
|
53
70
|
@module = get_or_define_module ::Object, @safe_namespace
|
54
71
|
end
|
@@ -72,9 +89,11 @@ module GirFFI
|
|
72
89
|
|
73
90
|
unless (class << @lib; self.include? FFI::Library; end)
|
74
91
|
@lib.extend FFI::Library
|
75
|
-
libs = gir.shared_library(@namespace).split(/,/)
|
76
92
|
@lib.ffi_lib_flags :global, :lazy
|
77
|
-
|
93
|
+
libspec = gir.shared_library(@namespace)
|
94
|
+
unless libspec.nil?
|
95
|
+
@lib.ffi_lib(*libspec.split(/,/))
|
96
|
+
end
|
78
97
|
end
|
79
98
|
|
80
99
|
optionally_define_constant(@lib, :CALLBACKS) { [] }
|
@@ -82,12 +101,8 @@ module GirFFI
|
|
82
101
|
|
83
102
|
def function_introspection_data function
|
84
103
|
info = gir.find_by_name @namespace, function.to_s
|
85
|
-
|
86
|
-
|
87
|
-
info
|
88
|
-
else
|
89
|
-
nil
|
90
|
-
end
|
104
|
+
return nil if info.nil?
|
105
|
+
info.info_type == :function ? info : nil
|
91
106
|
end
|
92
107
|
|
93
108
|
def function_definition info, libmodule
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'gir_ffi/builder/type/base'
|
2
|
+
module GirFFI
|
3
|
+
module Builder
|
4
|
+
module Type
|
5
|
+
|
6
|
+
# Implements the creation of a constant. Though semantically not a
|
7
|
+
# type, its build method is like that of the types, in that it is
|
8
|
+
# triggered by a missing constant in the parent namespace. The
|
9
|
+
# constant will be attached to the appropriate namespace module.
|
10
|
+
class Constant < Base
|
11
|
+
TYPE_TAG_TO_UNION_MEMBER = {
|
12
|
+
:gint32 => :v_int32,
|
13
|
+
:gdouble => :v_double,
|
14
|
+
:utf8 => :v_string
|
15
|
+
}
|
16
|
+
|
17
|
+
def build_class
|
18
|
+
unless defined? @klass
|
19
|
+
instantiate_class
|
20
|
+
end
|
21
|
+
@klass
|
22
|
+
end
|
23
|
+
|
24
|
+
def instantiate_class
|
25
|
+
@klass = optionally_define_constant namespace_module, @classname do
|
26
|
+
tag = info.constant_type.tag
|
27
|
+
val = info.value[TYPE_TAG_TO_UNION_MEMBER[tag]]
|
28
|
+
if RUBY_VERSION >= "1.9" and tag == :utf8
|
29
|
+
val.force_encoding("utf-8")
|
30
|
+
else
|
31
|
+
val
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|