gir_ffi 0.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/README.md +1 -1
- data/TODO.rdoc +12 -4
- data/lib/ffi-glib.rb +0 -5
- data/lib/ffi-glib/list.rb +1 -1
- data/lib/ffi-glib/s_list.rb +1 -1
- data/lib/ffi-gobject.rb +2 -3
- data/lib/ffi-gobject/closure.rb +4 -3
- data/lib/ffi-gobject_introspection/i_base_info.rb +11 -14
- data/lib/ffi-gobject_introspection/i_constant_info.rb +1 -1
- data/lib/ffi-gobject_introspection/i_function_info.rb +0 -6
- data/lib/ffi-gobject_introspection/lib.rb +8 -2
- data/lib/gir_ffi.rb +5 -0
- data/lib/gir_ffi/arg_helper.rb +1 -1
- data/lib/gir_ffi/argument_builder.rb +161 -0
- data/lib/gir_ffi/base_argument_builder.rb +146 -0
- data/lib/gir_ffi/builder/field.rb +7 -5
- data/lib/gir_ffi/builder/module.rb +3 -14
- data/lib/gir_ffi/builder/property.rb +0 -2
- data/lib/gir_ffi/builder/type/callback.rb +0 -8
- data/lib/gir_ffi/builder/type/constant.rb +0 -4
- data/lib/gir_ffi/builder/type/enum.rb +0 -4
- data/lib/gir_ffi/builder/type/interface.rb +0 -4
- data/lib/gir_ffi/builder/type/object.rb +0 -1
- data/lib/gir_ffi/builder/type/struct_based.rb +0 -6
- data/lib/gir_ffi/builder/type/union.rb +0 -4
- data/lib/gir_ffi/builder/type/with_layout.rb +0 -1
- data/lib/gir_ffi/builder/type/with_methods.rb +1 -7
- data/lib/gir_ffi/callback.rb +9 -0
- data/lib/gir_ffi/callback_helper.rb +8 -1
- data/lib/gir_ffi/class_base.rb +6 -26
- data/lib/gir_ffi/error_argument_builder.rb +17 -0
- data/lib/gir_ffi/{builder/function.rb → function_builder.rb} +14 -11
- data/lib/gir_ffi/in_out_pointer.rb +29 -36
- data/lib/gir_ffi/in_pointer.rb +1 -1
- data/lib/gir_ffi/info_ext.rb +6 -0
- data/lib/gir_ffi/info_ext/i_field_info.rb +0 -2
- data/lib/gir_ffi/info_ext/i_type_info.rb +29 -10
- data/lib/gir_ffi/info_ext/safe_constant_name.rb +21 -0
- data/lib/gir_ffi/info_ext/safe_function_name.rb +13 -0
- data/lib/gir_ffi/interface_base.rb +1 -11
- data/lib/gir_ffi/module_base.rb +0 -10
- data/lib/gir_ffi/null_argument_builder.rb +9 -0
- data/lib/gir_ffi/return_value_builder.rb +75 -0
- data/lib/gir_ffi/setter_argument_info.rb +16 -0
- data/lib/gir_ffi/type_map.rb +10 -1
- data/lib/gir_ffi/version.rb +1 -1
- data/tasks/test.rake +61 -0
- data/test/base_test_helper.rb +0 -2
- data/test/ffi-gobject/value_test.rb +15 -0
- data/test/ffi-gobject_introspection/i_base_info_test.rb +31 -6
- data/test/ffi-gobject_introspection/i_function_info_test.rb +0 -17
- data/test/ffi-gobject_introspection/lib_test.rb +0 -55
- data/test/ffi-gobject_test.rb +2 -1
- data/test/gir_ffi/argument_builder_test.rb +414 -0
- data/test/gir_ffi/base_argument_builder_test.rb +13 -0
- data/test/gir_ffi/builder/module_test.rb +4 -40
- data/test/gir_ffi/builder/type/callback_test.rb +0 -27
- data/test/gir_ffi/builder/type/constant_test.rb +0 -12
- data/test/gir_ffi/builder/type/enum_test.rb +0 -20
- data/test/gir_ffi/builder/type/interface_test.rb +0 -11
- data/test/gir_ffi/builder/type/object_test.rb +2 -2
- data/test/gir_ffi/builder/type/struct_test.rb +0 -39
- data/test/gir_ffi/builder/type/unintrospectable_test.rb +1 -1
- data/test/gir_ffi/builder/type/union_test.rb +0 -11
- data/test/gir_ffi/builder_test.rb +3 -11
- data/test/gir_ffi/callback_helper_test.rb +7 -0
- data/test/gir_ffi/{builder/function_test.rb → function_builder_test.rb} +16 -28
- data/test/gir_ffi/in_out_pointer_test.rb +0 -20
- data/test/gir_ffi/info_ext/i_type_info_test.rb +112 -26
- data/test/gir_ffi/info_ext/safe_constant_name_test.rb +16 -0
- data/test/gir_ffi/info_ext/safe_function_name_test.rb +22 -0
- data/test/gir_ffi/return_value_builder_test.rb +355 -0
- data/test/integration/generated_gimarshallingtests_test.rb +608 -296
- data/test/integration/generated_regress_test.rb +879 -494
- metadata +35 -24
- data/lib/gir_ffi/builder/argument.rb +0 -569
- data/lib/gir_ffi/builder/argument/base.rb +0 -151
- data/lib/gir_ffi/builder/argument/in_base.rb +0 -14
- data/lib/gir_ffi/builder/argument/in_out_base.rb +0 -18
- data/lib/gir_ffi/builder/argument/out_base.rb +0 -15
- data/test/gir_ffi/builder/argument/base_test.rb +0 -55
- data/test/integration/pretty_print_test.rb +0 -33
data/lib/gir_ffi/in_pointer.rb
CHANGED
@@ -0,0 +1,6 @@
|
|
1
|
+
require 'gir_ffi/info_ext/safe_constant_name'
|
2
|
+
require 'gir_ffi/info_ext/safe_function_name'
|
3
|
+
require 'gir_ffi/info_ext/i_field_info'
|
4
|
+
require 'gir_ffi/info_ext/i_property_info'
|
5
|
+
require 'gir_ffi/info_ext/i_registered_type_info'
|
6
|
+
require 'gir_ffi/info_ext/i_type_info'
|
@@ -40,9 +40,10 @@ module GirFFI
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def type_specification
|
43
|
-
tag = self.
|
44
|
-
|
45
|
-
|
43
|
+
tag = self.flattened_tag
|
44
|
+
case tag
|
45
|
+
when :strv, :zero_terminated, :c
|
46
|
+
"[#{tag.inspect}, #{subtype_tag_or_class_name}]"
|
46
47
|
else
|
47
48
|
tag.inspect
|
48
49
|
end
|
@@ -65,20 +66,38 @@ module GirFFI
|
|
65
66
|
|
66
67
|
def flattened_array_type
|
67
68
|
if zero_terminated?
|
68
|
-
|
69
|
-
:strv
|
70
|
-
else
|
71
|
-
# TODO: Check that array_type == :c
|
72
|
-
# TODO: Perhaps distinguish :c from zero-terminated :c
|
73
|
-
:c
|
74
|
-
end
|
69
|
+
zero_terminated_array_type
|
75
70
|
else
|
76
71
|
array_type
|
77
72
|
end
|
78
73
|
end
|
79
74
|
|
75
|
+
def subtype_tag_or_class_name
|
76
|
+
type = self.param_type 0
|
77
|
+
tag = type.tag
|
78
|
+
base = if tag == :interface
|
79
|
+
type.interface_type_name
|
80
|
+
else
|
81
|
+
tag.inspect
|
82
|
+
end
|
83
|
+
if type.pointer? && tag != :utf8
|
84
|
+
"[:pointer, #{base}]"
|
85
|
+
else
|
86
|
+
base
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
80
90
|
private
|
81
91
|
|
92
|
+
def zero_terminated_array_type
|
93
|
+
if element_type == :utf8
|
94
|
+
:strv
|
95
|
+
else
|
96
|
+
# TODO: Check that array_type == :c
|
97
|
+
:zero_terminated
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
82
101
|
def subtype_tag index
|
83
102
|
st = param_type(index)
|
84
103
|
tag = st.tag
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GirFFI
|
2
|
+
module InfoExt
|
3
|
+
module SafeConstantName
|
4
|
+
def safe_name
|
5
|
+
name.gsub(/^./) do |char|
|
6
|
+
case char
|
7
|
+
when "_"
|
8
|
+
"Private___"
|
9
|
+
else
|
10
|
+
char.upcase
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
GObjectIntrospection::IRegisteredTypeInfo.send :include, GirFFI::InfoExt::SafeConstantName
|
19
|
+
GObjectIntrospection::ICallbackInfo.send :include, GirFFI::InfoExt::SafeConstantName
|
20
|
+
GObjectIntrospection::IConstantInfo.send :include, GirFFI::InfoExt::SafeConstantName
|
21
|
+
|
@@ -1,21 +1,11 @@
|
|
1
1
|
module GirFFI
|
2
2
|
module InterfaceBase
|
3
|
-
# @deprecated Compatibility function. Remove in version 0.5.0.
|
4
|
-
def _builder
|
5
|
-
gir_ffi_builder
|
6
|
-
end
|
7
|
-
|
8
3
|
def gir_ffi_builder
|
9
4
|
self.const_get :GIR_FFI_BUILDER
|
10
5
|
end
|
11
6
|
|
12
|
-
# @deprecated Compatibility function. Remove in version 0.5.0.
|
13
|
-
def _setup_instance_method name
|
14
|
-
setup_instance_method name
|
15
|
-
end
|
16
|
-
|
17
7
|
def setup_instance_method name
|
18
|
-
|
8
|
+
gir_ffi_builder.setup_instance_method name
|
19
9
|
end
|
20
10
|
|
21
11
|
def wrap ptr
|
data/lib/gir_ffi/module_base.rb
CHANGED
@@ -16,20 +16,10 @@ module GirFFI
|
|
16
16
|
gir_ffi_builder.build_namespaced_class classname.to_s
|
17
17
|
end
|
18
18
|
|
19
|
-
# @deprecated Compatibility function. Remove in version 0.5.0.
|
20
|
-
def _builder
|
21
|
-
gir_ffi_builder
|
22
|
-
end
|
23
|
-
|
24
19
|
def gir_ffi_builder
|
25
20
|
self.const_get :GIR_FFI_BUILDER
|
26
21
|
end
|
27
22
|
|
28
|
-
# @deprecated Compatibility function. Remove in version 0.5.0.
|
29
|
-
def _setup_method name
|
30
|
-
setup_method name
|
31
|
-
end
|
32
|
-
|
33
23
|
def setup_method name
|
34
24
|
gir_ffi_builder.setup_method name
|
35
25
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'gir_ffi/base_argument_builder'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
# Implements building post-processing statements for return values.
|
5
|
+
class ReturnValueBuilder < BaseArgumentBuilder
|
6
|
+
def initialize var_gen, type_info, is_constructor
|
7
|
+
super var_gen, nil, type_info, :return
|
8
|
+
@is_constructor = is_constructor
|
9
|
+
end
|
10
|
+
|
11
|
+
def post
|
12
|
+
if needs_wrapping?
|
13
|
+
if specialized_type_tag == :zero_terminated
|
14
|
+
# FIXME: This is almost certainly wrong.
|
15
|
+
[ "#{retname} = #{argument_class_name}.wrap(#{cvar})" ]
|
16
|
+
elsif [ :interface, :object ].include?(specialized_type_tag) && @is_constructor
|
17
|
+
[ "#{retname} = self.constructor_wrap(#{cvar})" ]
|
18
|
+
else
|
19
|
+
[ "#{retname} = #{argument_class_name}.wrap(#{return_value_conversion_arguments})" ]
|
20
|
+
end
|
21
|
+
elsif specialized_type_tag == :utf8
|
22
|
+
# TODO: Re-use methods in InOutPointer for this conversion
|
23
|
+
[ "#{retname} = GirFFI::ArgHelper.ptr_to_utf8(#{cvar})" ]
|
24
|
+
elsif specialized_type_tag == :c
|
25
|
+
size = array_size
|
26
|
+
[ "#{retname} = GirFFI::ArgHelper.ptr_to_typed_array #{subtype_tag_or_class_name}, #{cvar}, #{size}" ]
|
27
|
+
else
|
28
|
+
[]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def inarg
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
# TODO: Rename
|
37
|
+
def cvar
|
38
|
+
callarg unless is_void_return_value?
|
39
|
+
end
|
40
|
+
|
41
|
+
def retval
|
42
|
+
if has_conversion?
|
43
|
+
super
|
44
|
+
elsif is_void_return_value?
|
45
|
+
nil
|
46
|
+
else
|
47
|
+
callarg
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def retname
|
54
|
+
@retname ||= @var_gen.new_var
|
55
|
+
end
|
56
|
+
|
57
|
+
def has_conversion?
|
58
|
+
needs_wrapping? || [ :utf8, :c ].include?(specialized_type_tag)
|
59
|
+
end
|
60
|
+
|
61
|
+
def needs_wrapping?
|
62
|
+
[ :struct, :union, :interface, :object, :strv, :zero_terminated,
|
63
|
+
:byte_array, :ptr_array, :glist, :gslist, :ghash, :array
|
64
|
+
].include?(specialized_type_tag)
|
65
|
+
end
|
66
|
+
|
67
|
+
def is_void_return_value?
|
68
|
+
specialized_type_tag == :void && !type_info.pointer?
|
69
|
+
end
|
70
|
+
|
71
|
+
def return_value_conversion_arguments
|
72
|
+
conversion_arguments cvar
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module GirFFI
|
2
|
+
# Class to represent argument info for the argument of a setter method.
|
3
|
+
# Implements the necessary parts of IArgumentInfo's interface.
|
4
|
+
class SetterArgumentInfo
|
5
|
+
attr_reader :name, :argument_type
|
6
|
+
|
7
|
+
def initialize name, type
|
8
|
+
@name = name
|
9
|
+
@argument_type = type
|
10
|
+
end
|
11
|
+
|
12
|
+
def direction
|
13
|
+
:in
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/gir_ffi/type_map.rb
CHANGED
@@ -4,6 +4,15 @@ module GirFFI
|
|
4
4
|
gtype_type = "uint#{sz}".to_sym
|
5
5
|
|
6
6
|
TAG_TYPE_MAP = {
|
7
|
+
:enum => :int32,
|
8
|
+
:flags => :int32,
|
9
|
+
:ghash => :pointer,
|
10
|
+
:glist => :pointer,
|
11
|
+
:gslist => :pointer,
|
12
|
+
:strv => :pointer,
|
13
|
+
:c => :pointer,
|
14
|
+
:object => :pointer,
|
15
|
+
:struct => :pointer,
|
7
16
|
:GType => gtype_type,
|
8
17
|
:gboolean => :bool,
|
9
18
|
:gunichar => :uint32,
|
@@ -30,7 +39,7 @@ module GirFFI
|
|
30
39
|
case type
|
31
40
|
when :gboolean
|
32
41
|
:int32
|
33
|
-
when :utf8
|
42
|
+
when :utf8, :array
|
34
43
|
:pointer
|
35
44
|
else
|
36
45
|
map_basic_type(type)
|
data/lib/gir_ffi/version.rb
CHANGED
data/tasks/test.rake
CHANGED
@@ -1,5 +1,52 @@
|
|
1
1
|
require 'rake/testtask'
|
2
2
|
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'rexml/streamlistener'
|
5
|
+
|
6
|
+
# Listener class used to process GIR xml data, for creating test stubs.
|
7
|
+
class Listener
|
8
|
+
include REXML::StreamListener
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@inside_class = false
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :result
|
15
|
+
attr_accessor :namespace
|
16
|
+
|
17
|
+
def tag_start name, attrs
|
18
|
+
return if attrs['disguised'] == '1'
|
19
|
+
return if attrs['introspectable'] == '0'
|
20
|
+
return if attrs['glib:is-gtype-struct-for']
|
21
|
+
|
22
|
+
obj_name = attrs['name']
|
23
|
+
case name
|
24
|
+
when "constant"
|
25
|
+
result.puts " it \"has the constant #{obj_name}\" do"
|
26
|
+
when "record", "class", "enumeration", "bitfield", "interface", "union"
|
27
|
+
result.puts " describe \"#{namespace}::#{obj_name}\" do"
|
28
|
+
@inside_class = true
|
29
|
+
when "constructor"
|
30
|
+
result.puts " it \"creates an instance using ##{obj_name}\" do"
|
31
|
+
when "function", "method"
|
32
|
+
spaces = @inside_class ? " " : ""
|
33
|
+
result.puts " #{spaces}it \"has a working #{name} ##{obj_name}\" do"
|
34
|
+
when "member"
|
35
|
+
result.puts " it \"has the member :#{obj_name}\" do"
|
36
|
+
when "type", "return-value", "parameters", "parameter", "doc", "array"
|
37
|
+
else
|
38
|
+
puts "Skipping #{name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def tag_end name
|
43
|
+
case name
|
44
|
+
when "record", "class", "enumeration", "bitfield", "interface", "union"
|
45
|
+
@inside_class = false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
3
50
|
namespace :test do
|
4
51
|
def define_test_task name
|
5
52
|
Rake::TestTask.new(name) do |t|
|
@@ -54,6 +101,20 @@ namespace :test do
|
|
54
101
|
:main,
|
55
102
|
:overrides,
|
56
103
|
:integration]
|
104
|
+
|
105
|
+
task :stub => :lib do
|
106
|
+
file = File.new 'test/lib/Regress-1.0.gir'
|
107
|
+
listener = Listener.new
|
108
|
+
listener.result = File.open('tmp/regress_lines.rb', 'w')
|
109
|
+
listener.namespace = "Regress"
|
110
|
+
REXML::Document.parse_stream file, listener
|
111
|
+
|
112
|
+
file = File.new 'test/lib/GIMarshallingTests-1.0.gir'
|
113
|
+
listener = Listener.new
|
114
|
+
listener.result = File.open('tmp/gimarshallingtests_lines.rb', 'w')
|
115
|
+
listener.namespace = "GIMarshallingTests"
|
116
|
+
REXML::Document.parse_stream file, listener
|
117
|
+
end
|
57
118
|
end
|
58
119
|
|
59
120
|
file "test/lib/Makefile" => "test/lib/configure" do
|
data/test/base_test_helper.rb
CHANGED
@@ -3,6 +3,21 @@ require 'gir_ffi_test_helper'
|
|
3
3
|
require 'ffi-gobject'
|
4
4
|
|
5
5
|
describe GObject::Value do
|
6
|
+
describe "::Struct" do
|
7
|
+
describe "layout" do
|
8
|
+
let(:layout) { GObject::Value::Struct.layout }
|
9
|
+
|
10
|
+
it "consists of :g_type and :data" do
|
11
|
+
layout.members.must_equal [:g_type, :data]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has an array as its second element" do
|
15
|
+
types = layout.fields.map(&:type)
|
16
|
+
types[1].class.must_equal FFI::Type::Array
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
6
21
|
describe "::wrap_ruby_value" do
|
7
22
|
it "wraps a boolean false" do
|
8
23
|
gv = GObject::Value.wrap_ruby_value false
|
@@ -1,15 +1,40 @@
|
|
1
1
|
require 'introspection_test_helper'
|
2
2
|
|
3
3
|
describe GObjectIntrospection::IBaseInfo do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
let(:described_class) { GObjectIntrospection::IBaseInfo }
|
5
|
+
describe "#initialize" do
|
6
|
+
it "raises an error if nil is passed" do
|
7
|
+
proc { described_class.new nil }.must_raise ArgumentError
|
8
|
+
end
|
9
|
+
|
10
|
+
it "raises an error if a null pointer is passed" do
|
11
|
+
mock(ptr = Object.new).null? { true }
|
12
|
+
proc { described_class.new ptr }.must_raise ArgumentError
|
13
|
+
end
|
14
|
+
|
15
|
+
it "raises no error if a non-null pointer is passed" do
|
16
|
+
mock(ptr = Object.new).null? { false }
|
17
|
+
described_class.new ptr
|
18
|
+
pass
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "upon garbage collection" do
|
23
|
+
it "calls g_base_info_unref" do
|
24
|
+
skip "cannot be reliably tested on JRuby" if RUBY_PLATFORM == 'java'
|
25
|
+
mock(ptr = Object.new).null? { false }
|
26
|
+
mock(lib = Object.new).g_base_info_unref(ptr) { nil }
|
27
|
+
described_class.new ptr, lib
|
7
28
|
|
8
|
-
|
29
|
+
GC.start
|
9
30
|
|
10
|
-
|
31
|
+
# Yes, the next three lines are needed. https://gist.github.com/4277829
|
32
|
+
stub(ptr2 = Object.new).null? { false }
|
33
|
+
stub(lib).g_base_info_unref(ptr2) { nil }
|
34
|
+
described_class.new ptr2, lib
|
11
35
|
|
12
|
-
|
36
|
+
GC.start
|
37
|
+
GC.start
|
13
38
|
end
|
14
39
|
end
|
15
40
|
end
|