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.
Files changed (78) hide show
  1. data/History.txt +14 -0
  2. data/TODO.rdoc +10 -5
  3. data/lib/ffi-glib.rb +7 -73
  4. data/lib/ffi-glib/array.rb +29 -4
  5. data/lib/ffi-glib/byte_array.rb +15 -1
  6. data/lib/ffi-glib/hash_table.rb +31 -24
  7. data/lib/ffi-glib/list.rb +28 -0
  8. data/lib/ffi-glib/list_methods.rb +10 -2
  9. data/lib/ffi-glib/ptr_array.rb +39 -0
  10. data/lib/ffi-glib/s_list.rb +29 -0
  11. data/lib/ffi-gobject.rb +49 -22
  12. data/lib/ffi-gobject/closure.rb +4 -3
  13. data/lib/ffi-gobject/helper.rb +20 -43
  14. data/lib/ffi-gobject/initially_unowned.rb +2 -0
  15. data/lib/ffi-gobject/object.rb +54 -0
  16. data/lib/ffi-gobject/ruby_closure.rb +22 -16
  17. data/lib/ffi-gobject/value.rb +54 -19
  18. data/lib/ffi-gobject_introspection/i_constant_info.rb +17 -1
  19. data/lib/ffi-gobject_introspection/i_field_info.rb +8 -0
  20. data/lib/ffi-gobject_introspection/i_property_info.rb +3 -1
  21. data/lib/ffi-gobject_introspection/lib.rb +19 -2
  22. data/lib/gir_ffi/arg_helper.rb +7 -45
  23. data/lib/gir_ffi/builder.rb +1 -1
  24. data/lib/gir_ffi/builder/argument.rb +148 -107
  25. data/lib/gir_ffi/builder/argument/base.rb +5 -5
  26. data/lib/gir_ffi/builder/argument/in_base.rb +2 -2
  27. data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -3
  28. data/lib/gir_ffi/builder/argument/out_base.rb +2 -3
  29. data/lib/gir_ffi/builder/function.rb +11 -17
  30. data/lib/gir_ffi/builder/module.rb +26 -0
  31. data/lib/gir_ffi/builder/type.rb +5 -0
  32. data/lib/gir_ffi/builder/type/base.rb +2 -0
  33. data/lib/gir_ffi/builder/type/callback.rb +18 -3
  34. data/lib/gir_ffi/builder/type/constant.rb +4 -12
  35. data/lib/gir_ffi/builder/type/enum.rb +15 -6
  36. data/lib/gir_ffi/builder/type/interface.rb +4 -0
  37. data/lib/gir_ffi/builder/type/object.rb +11 -0
  38. data/lib/gir_ffi/builder/type/struct_based.rb +14 -4
  39. data/lib/gir_ffi/builder/type/union.rb +13 -7
  40. data/lib/gir_ffi/builder/type/with_layout.rb +59 -8
  41. data/lib/gir_ffi/class_base.rb +8 -1
  42. data/lib/gir_ffi/in_out_pointer.rb +17 -18
  43. data/lib/gir_ffi/in_pointer.rb +8 -1
  44. data/lib/gir_ffi/type_map.rb +12 -0
  45. data/lib/gir_ffi/variable_name_generator.rb +12 -0
  46. data/lib/gir_ffi/version.rb +1 -1
  47. data/test/ffi-glib/array_test.rb +54 -0
  48. data/test/ffi-glib/byte_array_test.rb +21 -0
  49. data/test/ffi-glib/glib_overrides_test.rb +1 -46
  50. data/test/ffi-glib/hash_table_test.rb +24 -0
  51. data/test/ffi-glib/list_test.rb +46 -0
  52. data/test/ffi-glib/ptr_array_test.rb +51 -0
  53. data/test/ffi-glib/s_list_test.rb +46 -0
  54. data/test/ffi-gobject/g_object_overrides_test.rb +8 -8
  55. data/test/ffi-gobject/gobject_test.rb +26 -0
  56. data/test/ffi-gobject/object_test.rb +12 -0
  57. data/test/ffi-gobject_introspection/i_constant_info_test.rb +5 -1
  58. data/test/ffi-gobject_introspection/lib_test.rb +56 -0
  59. data/test/integration/generated_gimarshallingtests_test.rb +118 -76
  60. data/test/integration/generated_regress_test.rb +220 -62
  61. data/test/integration/pretty_print_test.rb +11 -0
  62. data/test/type_builder_test.rb +0 -48
  63. data/test/unintrospectable_type_builder_test.rb +8 -2
  64. data/test/unit/builder_test.rb +1 -1
  65. data/test/unit/callback_builder_test.rb +19 -0
  66. data/test/unit/constant_builder_test.rb +11 -0
  67. data/test/unit/enum_builder_test.rb +25 -0
  68. data/test/unit/function_builder_test.rb +17 -0
  69. data/test/unit/in_out_pointer_test.rb +11 -0
  70. data/test/unit/in_pointer_test.rb +6 -2
  71. data/test/unit/interface_builder_test.rb +17 -0
  72. data/test/unit/module_builder_test.rb +95 -0
  73. data/test/unit/object_type_builder_test.rb +24 -0
  74. data/test/unit/struct_builder_test.rb +106 -0
  75. data/test/unit/union_builder_test.rb +17 -0
  76. data/test/unit/variable_name_generator_test.rb +16 -0
  77. metadata +102 -75
  78. 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 function_builder, arginfo=nil, libmodule=nil
21
- @arginfo = arginfo
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 = nil
26
- @function_builder = function_builder
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
- @arginfo.argument_type
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 ||= @function_builder.new_var
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 ||= @function_builder.new_var
12
+ @callarg ||= @var_gen.new_var
14
13
  end
15
14
 
16
15
  def retname
17
- @retname ||= @function_builder.new_var
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 ||= @function_builder.new_var
11
+ @callarg ||= @var_gen.new_var
13
12
  end
14
13
 
15
14
  def retname
16
- @retname ||= @function_builder.new_var
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
- setup_accumulators
14
- @data = @info.args.map {|arg| Argument.build self, arg, @libmodule}
15
- @rvdata = ReturnValue.build self, @info
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
- adjust_accumulators
29
+ setup_error_argument vargen
29
30
  return filled_out_template
30
31
  end
31
32
 
32
- private
33
-
34
- def setup_accumulators
35
- @varno = 0
33
+ def pretty_print
34
+ generate
36
35
  end
37
36
 
38
- def adjust_accumulators
37
+ private
38
+
39
+ def setup_error_argument vargen
39
40
  klass = @info.throws? ? ErrorArgument : NullArgument
40
- @errarg = klass.new(self)
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?
@@ -27,6 +27,11 @@ module GirFFI
27
27
  def self.build info
28
28
  TYPE_MAP[info.info_type].new(info).build_class
29
29
  end
30
+
31
+ # TODO: Pull up to include :function and :module
32
+ def self.builder_for info
33
+ TYPE_MAP[info.info_type].new(info)
34
+ end
30
35
  end
31
36
  end
32
37
  end
@@ -1,6 +1,8 @@
1
1
  module GirFFI
2
2
  module Builder
3
3
  module Type
4
+
5
+ # Base class for type builders.
4
6
  class Base
5
7
  include BuilderHelper
6
8
 
@@ -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
- args = Builder.ffi_function_argument_types info
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
- TYPE_TAG_TO_UNION_MEMBER = {
12
- :gint32 => :v_int32,
13
- :gdouble => :v_double,
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
- tag = info.constant_type.tag
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
- if const_defined_for namespace_module, @classname
21
- @klass = namespace_module.const_get @classname
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
@@ -10,6 +10,10 @@ module GirFFI
10
10
  class Interface < RegisteredType
11
11
  include WithMethods
12
12
 
13
+ def pretty_print
14
+ "module #{@classname}\n extend InterfaceBase\nend"
15
+ end
16
+
13
17
  private
14
18
 
15
19
  # FIXME: The word 'class' is not really correct.
@@ -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 instantiate_class
18
- @klass = get_or_define_class namespace_module, @classname, superclass
19
- @structklass = get_or_define_class @klass, :Struct, FFI::Struct
20
- setup_class unless already_set_up
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
- private
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
- super
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