gir_ffi 0.1.0 → 0.2.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.
- data/History.txt +14 -0
- data/TODO.rdoc +10 -5
- data/lib/ffi-glib.rb +7 -73
- data/lib/ffi-glib/array.rb +29 -4
- data/lib/ffi-glib/byte_array.rb +15 -1
- data/lib/ffi-glib/hash_table.rb +31 -24
- data/lib/ffi-glib/list.rb +28 -0
- data/lib/ffi-glib/list_methods.rb +10 -2
- data/lib/ffi-glib/ptr_array.rb +39 -0
- data/lib/ffi-glib/s_list.rb +29 -0
- data/lib/ffi-gobject.rb +49 -22
- data/lib/ffi-gobject/closure.rb +4 -3
- data/lib/ffi-gobject/helper.rb +20 -43
- data/lib/ffi-gobject/initially_unowned.rb +2 -0
- data/lib/ffi-gobject/object.rb +54 -0
- data/lib/ffi-gobject/ruby_closure.rb +22 -16
- data/lib/ffi-gobject/value.rb +54 -19
- data/lib/ffi-gobject_introspection/i_constant_info.rb +17 -1
- data/lib/ffi-gobject_introspection/i_field_info.rb +8 -0
- data/lib/ffi-gobject_introspection/i_property_info.rb +3 -1
- data/lib/ffi-gobject_introspection/lib.rb +19 -2
- data/lib/gir_ffi/arg_helper.rb +7 -45
- data/lib/gir_ffi/builder.rb +1 -1
- data/lib/gir_ffi/builder/argument.rb +148 -107
- data/lib/gir_ffi/builder/argument/base.rb +5 -5
- data/lib/gir_ffi/builder/argument/in_base.rb +2 -2
- data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -3
- data/lib/gir_ffi/builder/argument/out_base.rb +2 -3
- data/lib/gir_ffi/builder/function.rb +11 -17
- data/lib/gir_ffi/builder/module.rb +26 -0
- data/lib/gir_ffi/builder/type.rb +5 -0
- data/lib/gir_ffi/builder/type/base.rb +2 -0
- data/lib/gir_ffi/builder/type/callback.rb +18 -3
- data/lib/gir_ffi/builder/type/constant.rb +4 -12
- data/lib/gir_ffi/builder/type/enum.rb +15 -6
- data/lib/gir_ffi/builder/type/interface.rb +4 -0
- data/lib/gir_ffi/builder/type/object.rb +11 -0
- data/lib/gir_ffi/builder/type/struct_based.rb +14 -4
- data/lib/gir_ffi/builder/type/union.rb +13 -7
- data/lib/gir_ffi/builder/type/with_layout.rb +59 -8
- data/lib/gir_ffi/class_base.rb +8 -1
- data/lib/gir_ffi/in_out_pointer.rb +17 -18
- data/lib/gir_ffi/in_pointer.rb +8 -1
- data/lib/gir_ffi/type_map.rb +12 -0
- data/lib/gir_ffi/variable_name_generator.rb +12 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/test/ffi-glib/array_test.rb +54 -0
- data/test/ffi-glib/byte_array_test.rb +21 -0
- data/test/ffi-glib/glib_overrides_test.rb +1 -46
- data/test/ffi-glib/hash_table_test.rb +24 -0
- data/test/ffi-glib/list_test.rb +46 -0
- data/test/ffi-glib/ptr_array_test.rb +51 -0
- data/test/ffi-glib/s_list_test.rb +46 -0
- data/test/ffi-gobject/g_object_overrides_test.rb +8 -8
- data/test/ffi-gobject/gobject_test.rb +26 -0
- data/test/ffi-gobject/object_test.rb +12 -0
- data/test/ffi-gobject_introspection/i_constant_info_test.rb +5 -1
- data/test/ffi-gobject_introspection/lib_test.rb +56 -0
- data/test/integration/generated_gimarshallingtests_test.rb +118 -76
- data/test/integration/generated_regress_test.rb +220 -62
- data/test/integration/pretty_print_test.rb +11 -0
- data/test/type_builder_test.rb +0 -48
- data/test/unintrospectable_type_builder_test.rb +8 -2
- data/test/unit/builder_test.rb +1 -1
- data/test/unit/callback_builder_test.rb +19 -0
- data/test/unit/constant_builder_test.rb +11 -0
- data/test/unit/enum_builder_test.rb +25 -0
- data/test/unit/function_builder_test.rb +17 -0
- data/test/unit/in_out_pointer_test.rb +11 -0
- data/test/unit/in_pointer_test.rb +6 -2
- data/test/unit/interface_builder_test.rb +17 -0
- data/test/unit/module_builder_test.rb +95 -0
- data/test/unit/object_type_builder_test.rb +24 -0
- data/test/unit/struct_builder_test.rb +106 -0
- data/test/unit/union_builder_test.rb +17 -0
- data/test/unit/variable_name_generator_test.rb +16 -0
- metadata +102 -75
- data/test/module_builder_test.rb +0 -53
@@ -17,13 +17,13 @@ module GirFFI
|
|
17
17
|
|
18
18
|
attr_accessor :length_arg, :array_arg
|
19
19
|
|
20
|
-
def initialize
|
21
|
-
@
|
20
|
+
def initialize var_gen, name, typeinfo, libmodule
|
21
|
+
@typeinfo = typeinfo
|
22
22
|
@inarg = nil
|
23
23
|
@callarg = nil
|
24
24
|
@retname = nil
|
25
|
-
@name =
|
26
|
-
@
|
25
|
+
@name = safe(name)
|
26
|
+
@var_gen = var_gen
|
27
27
|
@libmodule = libmodule
|
28
28
|
@length_arg = nil
|
29
29
|
@array_arg = nil
|
@@ -32,7 +32,7 @@ module GirFFI
|
|
32
32
|
def prepare; end
|
33
33
|
|
34
34
|
def type_info
|
35
|
-
@
|
35
|
+
@typeinfo
|
36
36
|
end
|
37
37
|
|
38
38
|
def type_tag
|
@@ -4,13 +4,13 @@ module GirFFI
|
|
4
4
|
# Abstract base class implementing argument processing for arguments
|
5
5
|
# with direction :in.
|
6
6
|
class InBase < Base
|
7
|
+
# FIXME: Make class work without 'prepare' stage.
|
7
8
|
def prepare
|
8
|
-
@name = safe(@arginfo.name)
|
9
9
|
@inarg = @name
|
10
10
|
end
|
11
11
|
|
12
12
|
def callarg
|
13
|
-
@callarg ||= @
|
13
|
+
@callarg ||= @var_gen.new_var
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -5,16 +5,15 @@ module GirFFI
|
|
5
5
|
# with direction :inout.
|
6
6
|
class InOutBase < Base
|
7
7
|
def prepare
|
8
|
-
@name = safe(@arginfo.name)
|
9
8
|
@inarg = @name
|
10
9
|
end
|
11
10
|
|
12
11
|
def callarg
|
13
|
-
@callarg ||= @
|
12
|
+
@callarg ||= @var_gen.new_var
|
14
13
|
end
|
15
14
|
|
16
15
|
def retname
|
17
|
-
@retname ||= @
|
16
|
+
@retname ||= @var_gen.new_var
|
18
17
|
end
|
19
18
|
end
|
20
19
|
end
|
@@ -5,15 +5,14 @@ module GirFFI
|
|
5
5
|
# with direction :out.
|
6
6
|
class OutBase < Base
|
7
7
|
def prepare
|
8
|
-
@name = safe(@arginfo.name)
|
9
8
|
end
|
10
9
|
|
11
10
|
def callarg
|
12
|
-
@callarg ||= @
|
11
|
+
@callarg ||= @var_gen.new_var
|
13
12
|
end
|
14
13
|
|
15
14
|
def retname
|
16
|
-
@retname ||= @
|
15
|
+
@retname ||= @var_gen.new_var
|
17
16
|
end
|
18
17
|
|
19
18
|
def pre
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'gir_ffi/builder/argument'
|
2
|
+
require 'gir_ffi/variable_name_generator'
|
2
3
|
|
3
4
|
module GirFFI::Builder
|
4
5
|
# Implements the creation of a Ruby function definition out of a GIR
|
@@ -10,9 +11,9 @@ module GirFFI::Builder
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def generate
|
13
|
-
|
14
|
-
@data = @info.args.map {|arg| Argument.build
|
15
|
-
@rvdata = ReturnValue.build
|
14
|
+
vargen = GirFFI::VariableNameGenerator.new
|
15
|
+
@data = @info.args.map {|arg| Argument.build vargen, arg, @libmodule}
|
16
|
+
@rvdata = ReturnValue.build vargen, @info
|
16
17
|
|
17
18
|
alldata = @data.dup << @rvdata
|
18
19
|
|
@@ -25,19 +26,19 @@ module GirFFI::Builder
|
|
25
26
|
end
|
26
27
|
}
|
27
28
|
|
28
|
-
|
29
|
+
setup_error_argument vargen
|
29
30
|
return filled_out_template
|
30
31
|
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
def setup_accumulators
|
35
|
-
@varno = 0
|
33
|
+
def pretty_print
|
34
|
+
generate
|
36
35
|
end
|
37
36
|
|
38
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
def setup_error_argument vargen
|
39
40
|
klass = @info.throws? ? ErrorArgument : NullArgument
|
40
|
-
@errarg = klass.new
|
41
|
+
@errarg = klass.new vargen, nil, nil, nil
|
41
42
|
@errarg.prepare
|
42
43
|
end
|
43
44
|
|
@@ -87,12 +88,5 @@ module GirFFI::Builder
|
|
87
88
|
|
88
89
|
po.flatten
|
89
90
|
end
|
90
|
-
|
91
|
-
def new_var
|
92
|
-
@varno += 1
|
93
|
-
"_v#{@varno}"
|
94
|
-
end
|
95
|
-
|
96
|
-
public :new_var
|
97
91
|
end
|
98
92
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'gir_ffi/builder_helper'
|
2
2
|
require 'gir_ffi/module_base'
|
3
3
|
require 'gir_ffi/builder/function'
|
4
|
+
require 'indentation'
|
4
5
|
|
5
6
|
module GirFFI
|
6
7
|
# Builds a module based on information found in the introspection
|
@@ -37,6 +38,10 @@ module GirFFI
|
|
37
38
|
|
38
39
|
def build_namespaced_class classname
|
39
40
|
info = gir.find_by_name @namespace, classname.to_s
|
41
|
+
if info.nil?
|
42
|
+
raise NameError.new(
|
43
|
+
"Class #{classname} not found in namespace #{@namespace}")
|
44
|
+
end
|
40
45
|
Builder.build_class info
|
41
46
|
end
|
42
47
|
|
@@ -57,6 +62,15 @@ module GirFFI
|
|
57
62
|
@module
|
58
63
|
end
|
59
64
|
|
65
|
+
def pretty_print
|
66
|
+
s = "module #{@safe_namespace}\n"
|
67
|
+
gir.infos(@namespace).each do |info|
|
68
|
+
s << sub_builder(info).pretty_print.indent
|
69
|
+
s << "\n"
|
70
|
+
end
|
71
|
+
s << "end"
|
72
|
+
end
|
73
|
+
|
60
74
|
private
|
61
75
|
|
62
76
|
def build_dependencies
|
@@ -95,6 +109,18 @@ module GirFFI
|
|
95
109
|
optionally_define_constant(@lib, :CALLBACKS) { [] }
|
96
110
|
end
|
97
111
|
|
112
|
+
def sub_builder info
|
113
|
+
if info.info_type == :function
|
114
|
+
Builder::Function.new(info, libmodule)
|
115
|
+
else
|
116
|
+
Builder::Type.builder_for info
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def libmodule
|
121
|
+
@module.const_get(:Lib)
|
122
|
+
end
|
123
|
+
|
98
124
|
def function_introspection_data function
|
99
125
|
info = gir.find_by_name @namespace, function.to_s
|
100
126
|
return nil if info.nil?
|
data/lib/gir_ffi/builder/type.rb
CHANGED
@@ -9,11 +9,26 @@ module GirFFI
|
|
9
9
|
class Callback < Base
|
10
10
|
def instantiate_class
|
11
11
|
@klass = optionally_define_constant namespace_module, @classname do
|
12
|
-
|
13
|
-
ret = Builder.ffi_function_return_type info
|
14
|
-
lib.callback @classname.to_sym, args, ret
|
12
|
+
lib.callback callback_sym, argument_types, return_type
|
15
13
|
end
|
16
14
|
end
|
15
|
+
|
16
|
+
def pretty_print
|
17
|
+
return "#{@classname} = Lib.callback #{callback_sym.inspect}, " +
|
18
|
+
"#{argument_types.inspect}, #{return_type.inspect}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def callback_sym
|
22
|
+
@classname.to_sym
|
23
|
+
end
|
24
|
+
|
25
|
+
def argument_types
|
26
|
+
Builder.ffi_function_argument_types info
|
27
|
+
end
|
28
|
+
|
29
|
+
def return_type
|
30
|
+
Builder.ffi_function_return_type info
|
31
|
+
end
|
17
32
|
end
|
18
33
|
end
|
19
34
|
end
|
@@ -8,23 +8,15 @@ module GirFFI
|
|
8
8
|
# triggered by a missing constant in the parent namespace. The
|
9
9
|
# constant will be attached to the appropriate namespace module.
|
10
10
|
class Constant < Base
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
:utf8 => :v_string
|
15
|
-
}
|
11
|
+
def pretty_print
|
12
|
+
"#{@classname} = #{info.value.inspect}"
|
13
|
+
end
|
16
14
|
|
17
15
|
private
|
18
16
|
|
19
17
|
def instantiate_class
|
20
18
|
@klass = optionally_define_constant namespace_module, @classname do
|
21
|
-
|
22
|
-
val = info.value[TYPE_TAG_TO_UNION_MEMBER[tag]]
|
23
|
-
if RUBY_VERSION >= "1.9" and tag == :utf8
|
24
|
-
val.force_encoding("utf-8")
|
25
|
-
else
|
26
|
-
val
|
27
|
-
end
|
19
|
+
info.value
|
28
20
|
end
|
29
21
|
end
|
30
22
|
end
|
@@ -7,8 +7,16 @@ module GirFFI
|
|
7
7
|
# attached to the appropriate namespace module, and will be defined
|
8
8
|
# as an enum for FFI.
|
9
9
|
class Enum < RegisteredType
|
10
|
+
def pretty_print
|
11
|
+
"#{@classname} = Lib.enum #{enum_sym.inspect}, #{value_spec.inspect}"
|
12
|
+
end
|
13
|
+
|
10
14
|
private
|
11
15
|
|
16
|
+
def enum_sym
|
17
|
+
@classname.to_sym
|
18
|
+
end
|
19
|
+
|
12
20
|
def value_spec
|
13
21
|
return info.values.map {|vinfo|
|
14
22
|
val = GirFFI::ArgHelper.cast_uint32_to_int32(vinfo.value)
|
@@ -17,13 +25,14 @@ module GirFFI
|
|
17
25
|
end
|
18
26
|
|
19
27
|
def instantiate_class
|
20
|
-
|
21
|
-
|
22
|
-
else
|
23
|
-
@klass = namespace_module.const_set @classname,
|
24
|
-
lib.enum(@classname.to_sym, value_spec)
|
25
|
-
setup_gtype_getter
|
28
|
+
@klass = optionally_define_constant namespace_module, @classname do
|
29
|
+
lib.enum(enum_sym, value_spec)
|
26
30
|
end
|
31
|
+
setup_gtype_getter unless already_set_up
|
32
|
+
end
|
33
|
+
|
34
|
+
def already_set_up
|
35
|
+
@klass.respond_to? :get_gtype
|
27
36
|
end
|
28
37
|
end
|
29
38
|
end
|
@@ -34,6 +34,17 @@ module GirFFI
|
|
34
34
|
if parent
|
35
35
|
return superclass._find_signal signal_name
|
36
36
|
end
|
37
|
+
raise "Signal #{signal_name} not found"
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_property property_name
|
41
|
+
info.properties.each do |prop|
|
42
|
+
return prop if prop.name == property_name
|
43
|
+
end
|
44
|
+
if parent
|
45
|
+
return superclass._find_property property_name
|
46
|
+
end
|
47
|
+
raise "Property #{property_name} not found"
|
37
48
|
end
|
38
49
|
|
39
50
|
private
|
@@ -12,12 +12,22 @@ module GirFFI
|
|
12
12
|
include WithMethods
|
13
13
|
include WithLayout
|
14
14
|
|
15
|
+
def pretty_print
|
16
|
+
"class #{@classname}\nend"
|
17
|
+
end
|
18
|
+
|
15
19
|
private
|
16
20
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
def setup_class
|
22
|
+
setup_layout
|
23
|
+
setup_constants
|
24
|
+
stub_methods
|
25
|
+
setup_gtype_getter
|
26
|
+
setup_field_accessors
|
27
|
+
end
|
28
|
+
|
29
|
+
def layout_superclass
|
30
|
+
FFI::Struct
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
@@ -12,18 +12,24 @@ module GirFFI
|
|
12
12
|
include WithMethods
|
13
13
|
include WithLayout
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
def instantiate_class
|
18
|
-
@klass = get_or_define_class namespace_module, @classname, superclass
|
19
|
-
@structklass = get_or_define_class @klass, :Struct, FFI::Union
|
20
|
-
setup_class unless already_set_up
|
15
|
+
def pretty_print
|
16
|
+
"class #{@classname}\nend"
|
21
17
|
end
|
22
18
|
|
19
|
+
private
|
20
|
+
|
23
21
|
def setup_class
|
24
|
-
|
22
|
+
setup_layout
|
23
|
+
setup_constants
|
24
|
+
stub_methods
|
25
|
+
setup_gtype_getter
|
26
|
+
setup_field_accessors
|
25
27
|
provide_constructor
|
26
28
|
end
|
29
|
+
|
30
|
+
def layout_superclass
|
31
|
+
FFI::Union
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'gir_ffi/builder/argument'
|
2
|
+
require 'gir_ffi/variable_name_generator'
|
3
|
+
|
1
4
|
module GirFFI
|
2
5
|
module Builder
|
3
6
|
module Type
|
@@ -7,14 +10,6 @@ module GirFFI
|
|
7
10
|
module WithLayout
|
8
11
|
private
|
9
12
|
|
10
|
-
# TODO: Move to client classes.
|
11
|
-
def setup_class
|
12
|
-
setup_layout
|
13
|
-
setup_constants
|
14
|
-
stub_methods
|
15
|
-
setup_gtype_getter
|
16
|
-
end
|
17
|
-
|
18
13
|
def setup_layout
|
19
14
|
spec = layout_specification
|
20
15
|
@structklass.class_eval { layout(*spec) }
|
@@ -38,6 +33,62 @@ module GirFFI
|
|
38
33
|
finfo.offset ]
|
39
34
|
end
|
40
35
|
end
|
36
|
+
|
37
|
+
def setup_field_accessors
|
38
|
+
info.fields.each do |finfo|
|
39
|
+
unless info.find_method finfo.name
|
40
|
+
@klass.class_eval getter_def(finfo)
|
41
|
+
end
|
42
|
+
@klass.class_eval setter_def(finfo) if finfo.writable?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# TODO: Extract to new FieldBuilder class.
|
47
|
+
def getter_builder finfo
|
48
|
+
type = finfo.field_type
|
49
|
+
klass = Builder::ReturnValue.builder_for_field_getter type
|
50
|
+
vargen = VariableNameGenerator.new
|
51
|
+
klass.new vargen, finfo.name, type, nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def getter_def finfo
|
55
|
+
builder = getter_builder finfo
|
56
|
+
name = finfo.name
|
57
|
+
|
58
|
+
return <<-CODE
|
59
|
+
def #{name}
|
60
|
+
#{builder.cvar} = @struct[#{name.to_sym.inspect}]
|
61
|
+
#{builder.post.join("\n")}
|
62
|
+
#{builder.retval}
|
63
|
+
end
|
64
|
+
CODE
|
65
|
+
end
|
66
|
+
|
67
|
+
def setter_builder finfo
|
68
|
+
type = finfo.field_type
|
69
|
+
klass = Builder::InArgument.builder_for type
|
70
|
+
vargen = VariableNameGenerator.new
|
71
|
+
klass.new vargen, "value", type, lib
|
72
|
+
end
|
73
|
+
|
74
|
+
def setter_def finfo
|
75
|
+
builder = setter_builder finfo
|
76
|
+
builder.prepare
|
77
|
+
name = finfo.name
|
78
|
+
|
79
|
+
return <<-CODE
|
80
|
+
def #{name}= #{builder.inarg}
|
81
|
+
#{builder.pre.join("\n")}
|
82
|
+
@struct[#{name.to_sym.inspect}] = #{builder.callarg}
|
83
|
+
end
|
84
|
+
CODE
|
85
|
+
end
|
86
|
+
|
87
|
+
def instantiate_class
|
88
|
+
@klass = get_or_define_class namespace_module, @classname, superclass
|
89
|
+
@structklass = get_or_define_class @klass, :Struct, layout_superclass
|
90
|
+
setup_class unless already_set_up
|
91
|
+
end
|
41
92
|
end
|
42
93
|
end
|
43
94
|
end
|