gir_ffi 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|