gir_ffi 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +11 -0
  3. data/README.md +8 -6
  4. data/TODO.md +3 -0
  5. data/lib/ffi-glib.rb +2 -1
  6. data/lib/ffi-gobject.rb +2 -1
  7. data/lib/ffi-gobject/object.rb +19 -9
  8. data/lib/ffi-gobject/value.rb +15 -3
  9. data/lib/gir_ffi-base.rb +9 -4
  10. data/lib/gir_ffi-base/glib.rb +8 -0
  11. data/lib/gir_ffi-base/glib/boolean.rb +1 -0
  12. data/lib/gir_ffi-base/glib/strv.rb +1 -0
  13. data/lib/gir_ffi-base/gobject.rb +5 -1
  14. data/lib/gir_ffi/boxed_base.rb +12 -0
  15. data/lib/gir_ffi/builder.rb +10 -1
  16. data/lib/gir_ffi/builders/argument_builder.rb +8 -4
  17. data/lib/gir_ffi/builders/base_return_value_builder.rb +38 -0
  18. data/lib/gir_ffi/builders/callback_return_value_builder.rb +2 -30
  19. data/lib/gir_ffi/builders/initializer_return_value_builder.rb +2 -6
  20. data/lib/gir_ffi/builders/module_builder.rb +2 -3
  21. data/lib/gir_ffi/builders/property_argument_builder.rb +23 -0
  22. data/lib/gir_ffi/builders/property_builder.rb +65 -46
  23. data/lib/gir_ffi/builders/property_return_value_builder.rb +14 -0
  24. data/lib/gir_ffi/builders/return_value_builder.rb +9 -33
  25. data/lib/gir_ffi/callback_base.rb +5 -0
  26. data/lib/gir_ffi/core.rb +3 -3
  27. data/lib/gir_ffi/in_pointer.rb +1 -1
  28. data/lib/gir_ffi/info_ext/i_signal_info.rb +2 -3
  29. data/lib/gir_ffi/info_ext/i_type_info.rb +22 -14
  30. data/lib/gir_ffi/interface_base.rb +12 -0
  31. data/lib/gir_ffi/user_defined_type_info.rb +8 -0
  32. data/lib/gir_ffi/version.rb +1 -1
  33. data/test/gir_ffi/builders/function_builder_test.rb +19 -0
  34. data/test/gir_ffi/builders/object_builder_test.rb +5 -11
  35. data/test/gir_ffi/builders/property_builder_test.rb +37 -5
  36. data/test/gir_ffi/builders/signal_closure_builder_test.rb +21 -0
  37. data/test/gir_ffi/builders/vfunc_builder_test.rb +20 -0
  38. data/test/gir_ffi/info_ext/i_type_info_test.rb +18 -0
  39. data/test/gir_ffi/user_defined_type_info_test.rb +25 -0
  40. data/test/gir_ffi_test_helper.rb +2 -6
  41. data/test/integration/generated_gimarshallingtests_test.rb +5 -5
  42. data/test/integration/generated_gio_test.rb +2 -3
  43. data/test/integration/generated_gst_test.rb +1 -0
  44. data/test/integration/generated_regress_test.rb +630 -189
  45. data/test/integration/generated_utility_test.rb +173 -0
  46. data/test/lib/Makefile.am +3 -5
  47. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45d1fd64a20d066116552af625c33d0173bd6c47
4
- data.tar.gz: 404f1c8c32d94fff866f0e3499a62f4b9727ebc8
3
+ metadata.gz: 16ecb2c35535aff890ce4f63d90d9522a697c042
4
+ data.tar.gz: 54025535f0adadd1b3a1bc940d78ec7acbbdf47b
5
5
  SHA512:
6
- metadata.gz: 99533353d82d5700a0ecf734c4829157a51923b00b7bd40201dd760a8d6800865e6d00778182826565ac1ccf2bde68736d33cbb70116542ecf7d72e24a7d383e
7
- data.tar.gz: d9ddd4fe6a2017148a447d4ac8a9573905cd76cd73dabc7248f60fd75417f530751cf731286f5600e8c70baf89b97db73ff9847ef77505cf669f8231a63b8e75
6
+ metadata.gz: ae487826ba3c2f6e22ae78717b0f9523eb7d06e57a1892d52e50a950a925ae6cf18477bbf147c730b70e50b6c19373332f9b8409b0414a338e543ff3f7c7eea0
7
+ data.tar.gz: 16d9cf79dc31a6d5b591e4b835c1f3649414e9179a45e393c869bc8c5750b32573938b4817638b8d0355700a617951f828c3f11c435d1c7797aa0e63780dd9fc
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.5 / 2016-03-05
4
+
5
+ * Abort if modules were defined earlier, e.g., through the gems from the ruby-gnome family.
6
+ * Extend integration testing with GObjectIntrospection's test libraries.
7
+ * Find signals on user-defined types.
8
+ * Allow getting and setting of properties with a callback value.
9
+ * Handle pointer-like signal arguments such as GList.
10
+ * Handle static methods on interface modules.
11
+ * Free most self-allocated boxed types using GObject.boxed_free.
12
+ * Correctly assign length arguments for zero-terminated arguments
13
+
3
14
  ## 0.9.4 / 2016-02-22
4
15
 
5
16
  * Pass nil user data as null pointer, and store a missing callback as nil. This
data/README.md CHANGED
@@ -64,13 +64,15 @@ available under the name ending in plain `.so`. If GirFFI complains that it
64
64
  cannot find the library, try installing development packages for those
65
65
  libraries.
66
66
 
67
- GirFFI is developed on Debian sid, and tested through Travis CI on Ubuntu
68
- 12.04. Older versions of gobject-introspection than the ones used there
69
- are therefore not officially supported (although they may work).
67
+ GirFFI should work with gobject-introspection 1.32.0 and up.
70
68
 
71
- On Debian and Ubuntu, installing `libgirepository1.0-dev`,
72
- `gobject-introspection`, `gir1.2-gtop-2.0` and `gir1.2-gstreamer-1.0` should be
73
- enough to get `rake test` working.
69
+ On Debian and Ubuntu, installing `libgirepository1.0-1` and `gir1.2-glib-2.0`
70
+ should be enough to use GirFFI in your application.
71
+
72
+ To run the tests, you should additionally install `libgirepository1.0-dev`,
73
+ `gobject-introspection`, `gir1.2-gtop-2.0`, `gir1.2-pango-1.0`,
74
+ `gir1.2-secret-1` and `gir1.2-gstreamer-1.0`. This should be enough to get
75
+ `rake test` working.
74
76
 
75
77
  GirFFI has not been tested on Mac OS X or Microsoft Windows. YMMV.
76
78
 
data/TODO.md CHANGED
@@ -61,6 +61,9 @@ How about:
61
61
 
62
62
  This needs issue #63 to be resolved.
63
63
 
64
+ NOTE: When adding an interface module to a derived class, its prerequisites
65
+ should be checked.
66
+
64
67
  ## Persistent Ruby GObject identity
65
68
 
66
69
  GirFFI should make sure that if it gets a pointer to a GObject for which a Ruby
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  require 'gir_ffi/core'
3
3
 
4
- GirFFI.setup :GLib
4
+ # Bypass check for existing modules
5
+ GirFFI::Builders::ModuleBuilder.new('GLib').generate
5
6
 
6
7
  require 'ffi-glib/array'
7
8
  require 'ffi-glib/byte_array'
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  require 'gir_ffi/core'
3
3
 
4
- GirFFI.setup :GObject
4
+ # Bypass check for existing modules
5
+ GirFFI::Builders::ModuleBuilder.new('GObject').generate
5
6
 
6
7
  require 'ffi-gobject/base'
7
8
 
@@ -68,12 +68,7 @@ module GObject
68
68
  def get_property_extended(property_name)
69
69
  value = get_property(property_name)
70
70
  type_info = get_property_type property_name
71
- case type_info.tag
72
- when :ghash, :glist
73
- adjust_value_to_type value, type_info
74
- else
75
- value
76
- end
71
+ property_value_post_conversion value, type_info
77
72
  end
78
73
 
79
74
  def get_property_with_override(property_name)
@@ -84,8 +79,7 @@ module GObject
84
79
 
85
80
  def set_property_extended(property_name, value)
86
81
  type_info = get_property_type property_name
87
- adjusted_value = adjust_value_to_type(value, type_info)
88
-
82
+ adjusted_value = property_value_pre_conversion(value, type_info)
89
83
  set_property property_name, adjusted_value
90
84
  end
91
85
 
@@ -127,7 +121,21 @@ module GObject
127
121
  end
128
122
 
129
123
  # TODO: Move to ITypeInfo
130
- def adjust_value_to_type(val, type_info)
124
+ def property_value_post_conversion(val, type_info)
125
+ case type_info.flattened_tag
126
+ when :ghash
127
+ GLib::HashTable.from type_info.element_type, val
128
+ when :glist
129
+ GLib::List.from type_info.element_type, val
130
+ when :callback
131
+ GirFFI::Builder.build_class(type_info.interface).wrap val
132
+ else
133
+ val
134
+ end
135
+ end
136
+
137
+ # TODO: Move to ITypeInfo
138
+ def property_value_pre_conversion(val, type_info)
131
139
  case type_info.flattened_tag
132
140
  when :ghash
133
141
  GLib::HashTable.from type_info.element_type, val
@@ -135,6 +143,8 @@ module GObject
135
143
  GLib::List.from type_info.element_type, val
136
144
  when :strv
137
145
  GLib::Strv.from val
146
+ when :callback
147
+ GirFFI::Builder.build_class(type_info.interface).from val
138
148
  else
139
149
  val
140
150
  end
@@ -9,16 +9,22 @@ module GObject
9
9
  def init_with_finalizer(type)
10
10
  return self if [TYPE_NONE, TYPE_INVALID].include? type
11
11
  init_without_finalizer(type)
12
- ObjectSpace.define_finalizer self, self.class.make_finalizer(to_ptr)
13
12
  self
14
13
  end
15
14
 
16
15
  alias_method :init_without_finalizer, :init
17
16
  alias_method :init, :init_with_finalizer
18
17
 
19
- def self.make_finalizer(ptr)
18
+ def self.make_finalizer(struct, gtype)
20
19
  proc do
21
- GObject::Lib.g_value_unset ptr
20
+ ptr = struct.to_ptr
21
+ if ptr.autorelease?
22
+ ptr.autorelease = false
23
+ unless struct[:g_type] == TYPE_INVALID
24
+ GObject::Lib.g_value_unset ptr
25
+ end
26
+ GObject.boxed_free gtype, ptr
27
+ end
22
28
  end
23
29
  end
24
30
 
@@ -107,6 +113,12 @@ module GObject
107
113
  end
108
114
  end
109
115
 
116
+ def self.copy_value_to_pointer(value, pointer, offset = 0)
117
+ super(value, pointer, offset).tap do
118
+ value.to_ptr.autorelease = false if value
119
+ end
120
+ end
121
+
110
122
  private
111
123
 
112
124
  def set_ruby_value(val)
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
- # This section contains code that is needed by GObjectIntrospection, but
3
- # belongs in modules that can only be created fully once GObjectIntrospection
4
- # is fully loaded.
5
- require 'gir_ffi-base/glib/boolean'
2
+ #
3
+ # This section contains code that is needed by GObjectIntrospection and GirFFI,
4
+ # but belongs in modules that can only be created fully once GirFFI is fully
5
+ # loaded.
6
+
7
+ # GLib::Strv and GObject.type_init are needed by GObjectIntrospection
6
8
  require 'gir_ffi-base/glib/strv'
7
9
  require 'gir_ffi-base/gobject'
10
+
11
+ # GLib::Boolean is needed by GirFFI.
12
+ require 'gir_ffi-base/glib/boolean'
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ensure GLib is defined by GirFFI itself
4
+ raise 'The module GLib was already defined elsewhere' if Kernel.const_defined? :GLib
5
+
6
+ # Module representing GLib's GLib namespace.
7
+ module GLib
8
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'ffi'
3
+ require 'gir_ffi-base/glib'
3
4
 
4
5
  module GLib
5
6
  # Implementation of gboolean
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'ffi'
3
+ require 'gir_ffi-base/glib'
3
4
 
4
5
  module GLib
5
6
  # Represents a null-terminated array of strings. GLib uses this
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'gir_ffi-base/gobject/lib'
2
+
3
+ # Ensure GLib is defined by GirFFI itself
4
+ raise 'The module GObject was already defined elsewhere' if Kernel.const_defined? :GObject
3
5
 
4
6
  # The part of the GObject namespace that is needed by GObjectIntrospection.
5
7
  module GObject
@@ -7,3 +9,5 @@ module GObject
7
9
  Lib.g_type_init
8
10
  end
9
11
  end
12
+
13
+ require 'gir_ffi-base/gobject/lib'
@@ -35,6 +35,18 @@ module GirFFI
35
35
 
36
36
  def initialize
37
37
  @struct = self.class::Struct.new
38
+ gtype = self.class.gtype
39
+ if GObject.type_fundamental(gtype) == GObject::TYPE_BOXED
40
+ ObjectSpace.define_finalizer self, self.class.make_finalizer(@struct, gtype)
41
+ end
42
+ end
43
+
44
+ def self.make_finalizer(struct, gtype)
45
+ proc do
46
+ ptr = struct.to_ptr
47
+ ptr.autorelease = false
48
+ GObject.boxed_free gtype, struct.to_ptr
49
+ end
38
50
  end
39
51
  end
40
52
  end
@@ -29,7 +29,16 @@ module GirFFI
29
29
  end
30
30
 
31
31
  def self.build_module(namespace, version = nil)
32
- Builders::ModuleBuilder.new(namespace, version).generate
32
+ module_name = namespace.gsub(/^./, &:upcase)
33
+ if Kernel.const_defined? module_name
34
+ modul = Kernel.const_get module_name
35
+ unless modul.const_defined? :GIR_FFI_BUILDER
36
+ raise "The module #{module_name} was already defined elsewhere"
37
+ end
38
+ end
39
+ Builders::ModuleBuilder.new(module_name,
40
+ namespace: namespace,
41
+ version: version).generate
33
42
  end
34
43
 
35
44
  # TODO: Move elsewhere, perhaps to FunctionBuilder.
@@ -120,17 +120,21 @@ module GirFFI
120
120
  "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{name}, \"#{name}\""
121
121
  end
122
122
 
123
- def skipped?
123
+ def skipped_in?
124
+ @arginfo.skip?
125
+ end
126
+
127
+ def skipped_out?
124
128
  @arginfo.skip? ||
125
129
  @array_arg && @array_arg.specialized_type_tag == :strv
126
130
  end
127
131
 
128
132
  def has_output_value?
129
- (direction == :inout || direction == :out) && !skipped?
133
+ (direction == :inout || direction == :out) && !skipped_out?
130
134
  end
131
135
 
132
136
  def has_input_value?
133
- has_ingoing_component? && !skipped?
137
+ has_ingoing_component? && !skipped_in?
134
138
  end
135
139
 
136
140
  def has_ingoing_component?
@@ -163,7 +167,7 @@ module GirFFI
163
167
  DESTROY_NOTIFIER = 'GLib::DestroyNotify.default'.freeze
164
168
 
165
169
  def ingoing_convertor
166
- if skipped?
170
+ if skipped_in?
167
171
  NullConvertor.new('0')
168
172
  elsif destroy_notifier?
169
173
  NullConvertor.new(DESTROY_NOTIFIER)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ require 'gir_ffi/builders/base_argument_builder'
3
+
4
+ module GirFFI
5
+ module Builders
6
+ # Implements building post-processing statements for return values of
7
+ # callbacks.
8
+ class BaseReturnValueBuilder < BaseArgumentBuilder
9
+ def relevant?
10
+ !void_return_value? && !arginfo.skip?
11
+ end
12
+
13
+ def capture_variable_name
14
+ @capture_variable_name ||= new_variable if relevant?
15
+ end
16
+
17
+ def post_converted_name
18
+ @post_converted_name ||= if has_post_conversion?
19
+ new_variable
20
+ else
21
+ capture_variable_name
22
+ end
23
+ end
24
+
25
+ def return_value_name
26
+ post_converted_name if has_return_value_name?
27
+ end
28
+
29
+ def void_return_value?
30
+ specialized_type_tag == :void && !type_info.pointer?
31
+ end
32
+
33
+ def has_return_value_name?
34
+ relevant? && !array_arg
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,32 +1,12 @@
1
1
  # frozen_string_literal: true
2
- require 'gir_ffi/builders/return_value_builder'
2
+ require 'gir_ffi/builders/base_return_value_builder'
3
3
  require 'gir_ffi/builders/ruby_to_c_convertor'
4
4
 
5
5
  module GirFFI
6
6
  module Builders
7
7
  # Implements building post-processing statements for return values of
8
8
  # callbacks.
9
- class CallbackReturnValueBuilder < BaseArgumentBuilder
10
- def relevant?
11
- !void_return_value? && !arginfo.skip?
12
- end
13
-
14
- def capture_variable_name
15
- @capture_variable_name ||= new_variable if relevant?
16
- end
17
-
18
- def post_converted_name
19
- @post_converted_name ||= if has_post_conversion?
20
- new_variable
21
- else
22
- capture_variable_name
23
- end
24
- end
25
-
26
- def return_value_name
27
- post_converted_name if has_return_value_name?
28
- end
29
-
9
+ class CallbackReturnValueBuilder < BaseReturnValueBuilder
30
10
  def post_conversion
31
11
  if has_post_conversion?
32
12
  if type_info.flattened_tag == :object
@@ -60,14 +40,6 @@ module GirFFI
60
40
  capture_variable_name
61
41
  end
62
42
  end
63
-
64
- def void_return_value?
65
- specialized_type_tag == :void && !type_info.pointer?
66
- end
67
-
68
- def has_return_value_name?
69
- relevant? && !array_arg
70
- end
71
43
  end
72
44
  end
73
45
  end
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
- require 'gir_ffi/builders/base_argument_builder'
2
+ require 'gir_ffi/builders/base_return_value_builder'
3
3
 
4
4
  module GirFFI
5
5
  module Builders
6
6
  # Implements post-conversion for initializer functions
7
- class InitializerReturnValueBuilder < BaseArgumentBuilder
8
- def capture_variable_name
9
- @capture_variable_name ||= new_variable
10
- end
11
-
7
+ class InitializerReturnValueBuilder < BaseReturnValueBuilder
12
8
  def post_conversion
13
9
  ["store_pointer(#{capture_variable_name})"]
14
10
  end
@@ -12,11 +12,10 @@ module GirFFI
12
12
  class ModuleBuilder
13
13
  include BuilderHelper
14
14
 
15
- def initialize(namespace, version = nil)
15
+ def initialize(module_name, namespace: module_name, version: nil)
16
16
  @namespace = namespace
17
17
  @version = version
18
- # FIXME: Pass safe namespace as an argument
19
- @safe_namespace = @namespace.gsub(/^./, &:upcase)
18
+ @safe_namespace = module_name
20
19
  end
21
20
 
22
21
  def generate
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ require 'gir_ffi/builders/base_argument_builder'
3
+
4
+ module GirFFI
5
+ module Builders
6
+ # Convertor for arguments for property setters.
7
+ class PropertyArgumentBuilder < BaseArgumentBuilder
8
+ def pre_conversion
9
+ pr = []
10
+ pr << "#{call_argument_name} = #{ingoing_convertor.conversion}"
11
+ pr
12
+ end
13
+
14
+ def ingoing_convertor
15
+ if type_info.needs_ruby_to_c_conversion_for_properties?
16
+ RubyToCConvertor.new(type_info, name)
17
+ else
18
+ NullConvertor.new(name)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end