gir_ffi 0.2.2 → 0.2.3

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.
Files changed (69) hide show
  1. data/History.txt +6 -0
  2. data/lib/ffi-glib.rb +1 -0
  3. data/lib/ffi-glib/array.rb +49 -10
  4. data/lib/ffi-glib/hash_table.rb +19 -5
  5. data/lib/ffi-glib/list.rb +4 -1
  6. data/lib/ffi-glib/list_methods.rb +8 -1
  7. data/lib/ffi-glib/s_list.rb +4 -1
  8. data/lib/ffi-glib/strv.rb +31 -0
  9. data/lib/ffi-gobject.rb +2 -35
  10. data/lib/ffi-gobject/base.rb +38 -0
  11. data/lib/ffi-gobject/object.rb +28 -30
  12. data/lib/ffi-gobject/value.rb +72 -56
  13. data/lib/ffi-gobject_introspection/i_struct_info.rb +11 -1
  14. data/lib/ffi-gobject_introspection/lib.rb +3 -1
  15. data/lib/gir_ffi/arg_helper.rb +2 -19
  16. data/lib/gir_ffi/builder/argument.rb +239 -305
  17. data/lib/gir_ffi/builder/argument/base.rb +12 -9
  18. data/lib/gir_ffi/builder/argument/in_base.rb +2 -6
  19. data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -5
  20. data/lib/gir_ffi/builder/argument/out_base.rb +0 -11
  21. data/lib/gir_ffi/builder/field.rb +55 -0
  22. data/lib/gir_ffi/builder/function.rb +7 -7
  23. data/lib/gir_ffi/builder/module.rb +5 -7
  24. data/lib/gir_ffi/builder/type/object.rb +0 -33
  25. data/lib/gir_ffi/builder/type/registered_type.rb +0 -16
  26. data/lib/gir_ffi/builder/type/struct_based.rb +3 -3
  27. data/lib/gir_ffi/builder/type/unintrospectable.rb +1 -1
  28. data/lib/gir_ffi/builder/type/with_layout.rb +26 -58
  29. data/lib/gir_ffi/builder/type/with_methods.rb +9 -11
  30. data/lib/gir_ffi/class_base.rb +24 -6
  31. data/lib/gir_ffi/ffi_ext/pointer.rb +15 -0
  32. data/lib/gir_ffi/in_pointer.rb +10 -5
  33. data/lib/gir_ffi/info_ext/i_field_info.rb +15 -0
  34. data/lib/gir_ffi/info_ext/i_type_info.rb +26 -0
  35. data/lib/gir_ffi/method_stubber.rb +18 -0
  36. data/lib/gir_ffi/type_map.rb +1 -0
  37. data/lib/gir_ffi/variable_name_generator.rb +2 -0
  38. data/lib/gir_ffi/version.rb +1 -1
  39. data/test/builder_test.rb +6 -5
  40. data/test/ffi-glib/array_test.rb +40 -5
  41. data/test/ffi-glib/hash_table_test.rb +27 -3
  42. data/test/ffi-glib/list_test.rb +23 -0
  43. data/test/ffi-glib/strv_test.rb +41 -0
  44. data/test/ffi-gobject/gobject_test.rb +26 -22
  45. data/test/ffi-gobject/value_test.rb +26 -1
  46. data/test/ffi-gobject_introspection/lib_test.rb +10 -0
  47. data/test/gir_ffi_test_helper.rb +1 -1
  48. data/test/integration/derived_classes_test.rb +31 -0
  49. data/test/integration/generated_gimarshallingtests_test.rb +29 -15
  50. data/test/integration/generated_gio_test.rb +5 -6
  51. data/test/integration/generated_regress_test.rb +11 -7
  52. data/test/integration/method_lookup_test.rb +32 -0
  53. data/test/interface_type_builder_test.rb +1 -1
  54. data/test/test_helper.rb +38 -0
  55. data/test/unit/argument_builder_test.rb +16 -4
  56. data/test/unit/class_base_test.rb +48 -0
  57. data/test/unit/function_builder_test.rb +144 -4
  58. data/test/unit/hash_table_element_type_provider_test.rb +16 -0
  59. data/test/unit/i_field_info_test.rb +39 -0
  60. data/test/unit/i_type_info_test.rb +23 -0
  61. data/test/unit/list_element_type_provider_test.rb +13 -0
  62. data/test/unit/module_builder_test.rb +1 -1
  63. data/test/unit/object_type_builder_test.rb +0 -17
  64. data/test/unit/struct_builder_test.rb +27 -39
  65. metadata +118 -60
  66. data/lib/gir_ffi/builder/argument/hash_table_base.rb +0 -20
  67. data/lib/gir_ffi/builder/argument/list_base.rb +0 -16
  68. data/test/class_base_test.rb +0 -10
  69. data/test/function_definition_builder_test.rb +0 -130
@@ -13,24 +13,20 @@ module GirFFI
13
13
  "until", "when", "while", "yield"
14
14
  ]
15
15
 
16
- attr_reader :callarg, :name, :retname
16
+ attr_reader :name, :retname
17
17
 
18
18
  attr_accessor :length_arg, :array_arg
19
19
 
20
- def initialize var_gen, name, typeinfo, libmodule
20
+ def initialize var_gen, name, typeinfo
21
21
  @typeinfo = typeinfo
22
22
  @inarg = nil
23
- @callarg = nil
24
23
  @retname = nil
25
24
  @name = safe(name)
26
25
  @var_gen = var_gen
27
- @libmodule = libmodule
28
26
  @length_arg = nil
29
27
  @array_arg = nil
30
28
  end
31
29
 
32
- def prepare; end
33
-
34
30
  def type_info
35
31
  @typeinfo
36
32
  end
@@ -42,15 +38,18 @@ module GirFFI
42
38
 
43
39
  def subtype_tag index=0
44
40
  st = type_info.param_type(index)
45
- t = st.tag
46
- case t
41
+ tag = st.tag
42
+ case tag
47
43
  when :GType
48
44
  return :gtype
49
45
  when :interface
50
46
  return :interface_pointer if st.pointer?
51
47
  return :interface
48
+ when :void
49
+ return :gpointer if st.pointer?
50
+ return :void
52
51
  else
53
- return t
52
+ return tag
54
53
  end
55
54
  end
56
55
 
@@ -100,6 +99,10 @@ module GirFFI
100
99
  @array_arg.nil? ? @retname : nil
101
100
  end
102
101
 
102
+ def callarg
103
+ @callarg ||= @var_gen.new_var
104
+ end
105
+
103
106
  def pre
104
107
  []
105
108
  end
@@ -4,14 +4,10 @@ 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.
8
- def prepare
7
+ def initialize var_gen, name, typeinfo
8
+ super var_gen, name, typeinfo
9
9
  @inarg = @name
10
10
  end
11
-
12
- def callarg
13
- @callarg ||= @var_gen.new_var
14
- end
15
11
  end
16
12
  end
17
13
  end
@@ -4,14 +4,11 @@ module GirFFI
4
4
  # Abstract base class implementing argument processing for arguments
5
5
  # with direction :inout.
6
6
  class InOutBase < Base
7
- def prepare
7
+ def initialize var_gen, name, typeinfo
8
+ super var_gen, name, typeinfo
8
9
  @inarg = @name
9
10
  end
10
11
 
11
- def callarg
12
- @callarg ||= @var_gen.new_var
13
- end
14
-
15
12
  def retname
16
13
  @retname ||= @var_gen.new_var
17
14
  end
@@ -4,20 +4,9 @@ module GirFFI
4
4
  # Abstract base class implementing argument processing for arguments
5
5
  # with direction :out.
6
6
  class OutBase < Base
7
- def prepare
8
- end
9
-
10
- def callarg
11
- @callarg ||= @var_gen.new_var
12
- end
13
-
14
7
  def retname
15
8
  @retname ||= @var_gen.new_var
16
9
  end
17
-
18
- def pre
19
- [ "#{callarg} = GirFFI::InOutPointer.for #{base_type.inspect}" ]
20
- end
21
10
  end
22
11
  end
23
12
  end
@@ -0,0 +1,55 @@
1
+ require 'gir_ffi/builder/argument'
2
+ require 'gir_ffi/variable_name_generator'
3
+
4
+ module GirFFI
5
+ module Builder
6
+ # Creates field getter and setter code for a given IFieldInfo.
7
+ class Field
8
+ def initialize field_info, lib_module
9
+ @info = field_info
10
+ @libmodule = lib_module
11
+ end
12
+
13
+ def getter_def
14
+ builder = return_value_builder
15
+
16
+ return <<-CODE
17
+ def #{@info.name}
18
+ #{builder.cvar} = @struct[#{field_symbol.inspect}]
19
+ #{builder.post.join("\n")}
20
+ #{builder.retval}
21
+ end
22
+ CODE
23
+ end
24
+
25
+ def setter_def
26
+ builder = setter_builder
27
+ name = @info.name
28
+
29
+ return <<-CODE
30
+ def #{name}= #{builder.inarg}
31
+ #{builder.pre.join("\n")}
32
+ @struct[#{name.to_sym.inspect}] = #{builder.callarg}
33
+ end
34
+ CODE
35
+ end
36
+
37
+ private
38
+
39
+ def field_symbol
40
+ @info.name.to_sym
41
+ end
42
+
43
+ def return_value_builder
44
+ @rv_builder ||= ReturnValueFactory.builder_for_field_getter(
45
+ VariableNameGenerator.new, @info.name, @info.field_type)
46
+ end
47
+
48
+ def setter_builder
49
+ type = @info.field_type
50
+ vargen = VariableNameGenerator.new
51
+ Builder::InArgument.builder_for vargen, "value", type, @libmodule
52
+ end
53
+ end
54
+ end
55
+ end
@@ -13,12 +13,11 @@ module GirFFI::Builder
13
13
  def generate
14
14
  vargen = GirFFI::VariableNameGenerator.new
15
15
  @data = @info.args.map {|arg| Argument.build vargen, arg, @libmodule}
16
- @rvdata = ReturnValue.build vargen, @info
16
+ @rvdata = ReturnValueFactory.build vargen, @info
17
17
 
18
18
  alldata = @data.dup << @rvdata
19
19
 
20
20
  alldata.each {|data|
21
- data.prepare
22
21
  idx = data.type_info.array_length
23
22
  if idx > -1
24
23
  data.length_arg = @data[idx]
@@ -38,16 +37,17 @@ module GirFFI::Builder
38
37
 
39
38
  def setup_error_argument vargen
40
39
  klass = @info.throws? ? ErrorArgument : NullArgument
41
- @errarg = klass.new vargen, nil, nil, nil
42
- @errarg.prepare
40
+ @errarg = klass.new vargen, nil, nil
43
41
  end
44
42
 
45
43
  def filled_out_template
46
44
  lines = pre
47
- lines << "#{capture}::#{@libmodule}.#{@info.symbol} #{callargs.join(', ')}"
45
+ lines << "#{capture}#{@libmodule}.#{@info.symbol} #{callargs.join(', ')}"
48
46
  lines << post
49
47
 
50
- code = "def #{@info.safe_name} #{inargs.join(', ')}\n"
48
+ meta = @info.method? ? '' : "self."
49
+
50
+ code = "def #{meta}#{@info.safe_name} #{inargs.join(', ')}\n"
51
51
  code << lines.join("\n").indent
52
52
  code << "\nend\n"
53
53
  end
@@ -81,7 +81,7 @@ module GirFFI::Builder
81
81
  po = (@data.map(&:post) + @data.map(&:postpost) + @rvdata.post)
82
82
  po.unshift @errarg.post
83
83
 
84
- po += @data.map {|d| d.cleanup}
84
+ po += @data.map {|item| item.cleanup}
85
85
 
86
86
  retvals = ([@rvdata.retval] + @data.map(&:retval)).compact
87
87
  po << "return #{retvals.join(', ')}" unless retvals.empty?
@@ -29,9 +29,7 @@ module GirFFI
29
29
  lib = modul.const_get(:Lib)
30
30
 
31
31
  Builder.attach_ffi_function lib, go
32
-
33
- meta = (class << modul; self; end)
34
- meta.class_eval function_definition(go, lib)
32
+ modul.class_eval function_definition(go, lib)
35
33
 
36
34
  true
37
35
  end
@@ -63,12 +61,12 @@ module GirFFI
63
61
  end
64
62
 
65
63
  def pretty_print
66
- s = "module #{@safe_namespace}\n"
64
+ buf = "module #{@safe_namespace}\n"
67
65
  gir.infos(@namespace).each do |info|
68
- s << sub_builder(info).pretty_print.indent
69
- s << "\n"
66
+ buf << sub_builder(info).pretty_print.indent
67
+ buf << "\n"
70
68
  end
71
- s << "end"
69
+ buf << "end"
72
70
  end
73
71
 
74
72
  private
@@ -5,26 +5,6 @@ module GirFFI
5
5
 
6
6
  # Implements the creation of a class representing a GObject Object.
7
7
  class Object < StructBased
8
- def setup_method method
9
- if super
10
- return true
11
- else
12
- if parent
13
- return superclass._setup_method method
14
- else
15
- return false
16
- end
17
- end
18
- end
19
-
20
- def setup_instance_method method
21
- if super
22
- return true
23
- else
24
- setup_instance_method_in_ancestor method
25
- end
26
- end
27
-
28
8
  def find_signal signal_name
29
9
  signal_definers.each do |inf|
30
10
  inf.signals.each do |sig|
@@ -49,19 +29,6 @@ module GirFFI
49
29
 
50
30
  private
51
31
 
52
- def setup_instance_method_in_ancestor method
53
- interfaces.each do |iface|
54
- if iface._setup_instance_method method
55
- return true
56
- end
57
- end
58
- if parent
59
- return superclass._setup_instance_method method
60
- else
61
- return false
62
- end
63
- end
64
-
65
32
  def setup_class
66
33
  super
67
34
  setup_vfunc_invokers
@@ -11,22 +11,6 @@ module GirFFI
11
11
  class RegisteredType < Base
12
12
  private
13
13
 
14
- # FIXME: Move this into a class with the other type knowledge.
15
- def itypeinfo_to_ffitype_for_struct typeinfo
16
- ffitype = Builder.itypeinfo_to_ffitype typeinfo
17
- if ffitype.kind_of?(Class) and const_defined_for ffitype, :Struct
18
- ffitype = ffitype.const_get :Struct
19
- end
20
- if ffitype == :bool
21
- ffitype = :int
22
- end
23
- if ffitype == :array
24
- subtype = itypeinfo_to_ffitype_for_struct typeinfo.param_type(0)
25
- ffitype = [subtype, typeinfo.array_fixed_size]
26
- end
27
- ffitype
28
- end
29
-
30
14
  def setup_constants
31
15
  @klass.const_set :GIR_INFO, info
32
16
  @klass.const_set :GIR_FFI_BUILDER, self
@@ -13,9 +13,9 @@ module GirFFI
13
13
  include WithLayout
14
14
 
15
15
  def pretty_print
16
- s = "class #{@classname}\n"
17
- s << pretty_print_methods
18
- s << "end"
16
+ buf = "class #{@classname}\n"
17
+ buf << pretty_print_methods
18
+ buf << "end"
19
19
  end
20
20
 
21
21
  private
@@ -27,7 +27,7 @@ module GirFFI
27
27
  end
28
28
 
29
29
  def setup_instance_method method
30
- setup_instance_method_in_ancestor method
30
+ false
31
31
  end
32
32
 
33
33
  private
@@ -1,5 +1,5 @@
1
- require 'gir_ffi/builder/argument'
2
- require 'gir_ffi/variable_name_generator'
1
+ require 'gir_ffi/builder/field'
2
+ require 'gir_ffi/info_ext/i_field_info'
3
3
 
4
4
  module GirFFI
5
5
  module Builder
@@ -7,6 +7,8 @@ module GirFFI
7
7
 
8
8
  # Implements the creation of classes representing types with layout,
9
9
  # i.e., :union, :struct, :object.
10
+ # Note: This module depends on the additional inclusion of
11
+ # WithMethods.
10
12
  module WithLayout
11
13
  private
12
14
 
@@ -15,73 +17,39 @@ module GirFFI
15
17
  @structklass.class_eval { layout(*spec) }
16
18
  end
17
19
 
18
- def layout_specification
19
- fields = info.fields
20
-
21
- if fields.empty?
22
- if parent
23
- return [:parent, superclass.const_get(:Struct), 0]
24
- else
25
- return [:dummy, :char, 0]
26
- end
27
- end
28
-
29
- fields.inject([]) do |spec, finfo|
30
- spec +
31
- [ finfo.name.to_sym,
32
- itypeinfo_to_ffitype_for_struct(finfo.field_type),
33
- finfo.offset ]
20
+ def dummy_layout_specification
21
+ if parent
22
+ [:parent, superclass.const_get(:Struct), 0]
23
+ else
24
+ [:dummy, :char, 0]
34
25
  end
35
26
  end
36
27
 
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
28
+ def base_layout_specification
29
+ info.fields.map { |finfo| finfo.layout_specification }.flatten(1)
44
30
  end
45
31
 
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}
32
+ def layout_specification
33
+ spec = base_layout_specification
34
+ if spec.empty?
35
+ dummy_layout_specification
36
+ else
37
+ spec
63
38
  end
64
- CODE
65
39
  end
66
40
 
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
41
+ def setup_accessors_for_field_info finfo
42
+ builder = Builder::Field.new(finfo, lib)
43
+ unless has_instance_method finfo.name
44
+ @klass.class_eval builder.getter_def
45
+ end
46
+ @klass.class_eval builder.setter_def if finfo.writable?
72
47
  end
73
48
 
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}
49
+ def setup_field_accessors
50
+ info.fields.each do |finfo|
51
+ setup_accessors_for_field_info finfo
83
52
  end
84
- CODE
85
53
  end
86
54
 
87
55
  def instantiate_class