gir_ffi 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/DESIGN.rdoc +54 -0
- data/History.txt +3 -0
- data/README.rdoc +59 -0
- data/Rakefile +21 -0
- data/TODO.rdoc +40 -0
- data/examples/01_empty_window.rb +15 -0
- data/examples/02_hello_world.rb +30 -0
- data/examples/03_upgraded_hello_world.rb +45 -0
- data/examples/demo_ffi_inherited_layout.rb +21 -0
- data/examples/demo_ffi_nested_struct.rb +17 -0
- data/examples/demo_ffi_safe_inherited_layout.rb +43 -0
- data/examples/hard_coded.rb +144 -0
- data/lib/gir_ffi.rb +47 -0
- data/lib/gir_ffi/allocation_helper.rb +12 -0
- data/lib/gir_ffi/arg_helper.rb +77 -0
- data/lib/gir_ffi/base.rb +23 -0
- data/lib/gir_ffi/builder.rb +159 -0
- data/lib/gir_ffi/builder_helper.rb +32 -0
- data/lib/gir_ffi/class_base.rb +11 -0
- data/lib/gir_ffi/class_builder.rb +116 -0
- data/lib/gir_ffi/constructor_definition_builder.rb +20 -0
- data/lib/gir_ffi/function_definition_builder.rb +148 -0
- data/lib/gir_ffi/g_error.rb +8 -0
- data/lib/gir_ffi/g_type.rb +14 -0
- data/lib/gir_ffi/i_arg_info.rb +16 -0
- data/lib/gir_ffi/i_base_info.rb +45 -0
- data/lib/gir_ffi/i_callable_info.rb +18 -0
- data/lib/gir_ffi/i_callback_info.rb +7 -0
- data/lib/gir_ffi/i_constant_info.rb +6 -0
- data/lib/gir_ffi/i_enum_info.rb +13 -0
- data/lib/gir_ffi/i_field_info.rb +10 -0
- data/lib/gir_ffi/i_flags_info.rb +5 -0
- data/lib/gir_ffi/i_function_info.rb +16 -0
- data/lib/gir_ffi/i_interface_info.rb +7 -0
- data/lib/gir_ffi/i_object_info.rb +50 -0
- data/lib/gir_ffi/i_property_info.rb +7 -0
- data/lib/gir_ffi/i_registered_type_info.rb +8 -0
- data/lib/gir_ffi/i_repository.rb +108 -0
- data/lib/gir_ffi/i_signal_info.rb +7 -0
- data/lib/gir_ffi/i_struct_info.rb +22 -0
- data/lib/gir_ffi/i_type_info.rb +25 -0
- data/lib/gir_ffi/i_union_info.rb +7 -0
- data/lib/gir_ffi/i_value_info.rb +8 -0
- data/lib/gir_ffi/i_vfunc_info.rb +7 -0
- data/lib/gir_ffi/lib.rb +174 -0
- data/lib/gir_ffi/lib_c.rb +11 -0
- data/lib/gir_ffi/method_missing_definition_builder.rb +62 -0
- data/lib/gir_ffi/module_builder.rb +66 -0
- data/lib/gir_ffi/overrides/gtk.rb +12 -0
- data/lib/gir_ffi/version.rb +4 -0
- data/tasks/bones.rake +87 -0
- data/tasks/notes.rake +134 -0
- data/tasks/post_load.rake +25 -0
- data/tasks/setup.rb +138 -0
- data/tasks/test.rake +22 -0
- data/test/arg_helper_test.rb +112 -0
- data/test/builder_test.rb +328 -0
- data/test/constructor_definition_builder_test.rb +19 -0
- data/test/function_definition_builder_test.rb +60 -0
- data/test/g_type_test.rb +22 -0
- data/test/girffi_test.rb +11 -0
- data/test/gtk_overrides_test.rb +22 -0
- data/test/i_repository_test.rb +54 -0
- data/test/test_helper.rb +39 -0
- metadata +174 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
module GirFFI
|
2
|
+
# Wraps a GIStructInfo struct.
|
3
|
+
# Represents a struct.
|
4
|
+
class IStructInfo < IRegisteredTypeInfo
|
5
|
+
def n_fields; Lib.g_struct_info_get_n_fields @gobj; end
|
6
|
+
def field(index); IFieldInfo.wrap(Lib.g_struct_info_get_field @gobj, index); end
|
7
|
+
|
8
|
+
##
|
9
|
+
build_array_method :fields
|
10
|
+
|
11
|
+
def n_methods; Lib.g_struct_info_get_n_methods @gobj; end
|
12
|
+
def method(index); IFunctionInfo.wrap(Lib.g_struct_info_get_method @gobj, index); end
|
13
|
+
|
14
|
+
##
|
15
|
+
build_array_method :methods
|
16
|
+
|
17
|
+
def find_method(name); IFunctionInfo.wrap(Lib.g_struct_info_find_method @gobj, name); end
|
18
|
+
def size; Lib.g_struct_info_get_size @gobj; end
|
19
|
+
def alignment; Lib.g_struct_info_get_alignment @gobj; end
|
20
|
+
def gtype_struct?; Lib.g_struct_info_is_gtype_struct @gobj; end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module GirFFI
|
2
|
+
# Wraps a GITypeInfo struct.
|
3
|
+
# Represents type information, direction, transfer etc.
|
4
|
+
class ITypeInfo < IBaseInfo
|
5
|
+
def pointer?; Lib.g_type_info_is_pointer @gobj; end
|
6
|
+
def tag; Lib.g_type_info_get_tag @gobj; end
|
7
|
+
def param_type(index); ITypeInfo.wrap(Lib.g_type_info_get_param_type @gobj, index); end
|
8
|
+
def interface
|
9
|
+
ptr = Lib.g_type_info_get_interface @gobj
|
10
|
+
IRepository.wrap_ibaseinfo_pointer ptr
|
11
|
+
end
|
12
|
+
def array_length; Lib.g_type_info_get_array_length @gobj; end
|
13
|
+
def array_fixed_size; Lib.g_type_info_get_array_fixed_size @gobj; end
|
14
|
+
def zero_terminated?; Lib.g_type_info_is_zero_terminated @gobj; end
|
15
|
+
def n_error_domains; Lib.g_type_info_get_n_error_domains @gobj; end
|
16
|
+
def error_domain(index); IErrorDomainInfo.wrap(Lib.g_type_info_get_error_domain @gobj, index); end
|
17
|
+
##
|
18
|
+
build_array_method :error_domains
|
19
|
+
|
20
|
+
def name
|
21
|
+
raise "Should not call this for gir 0.6.5 ..."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/lib/gir_ffi/lib.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
module Lib
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib "girepository-1.0"
|
7
|
+
|
8
|
+
# IRepository
|
9
|
+
enum :IRepositoryLoadFlags, [:LAZY, (1<<0)]
|
10
|
+
|
11
|
+
attach_function :g_irepository_get_default, [], :pointer
|
12
|
+
attach_function :g_irepository_require,
|
13
|
+
[:pointer, :string, :string, :IRepositoryLoadFlags, :pointer],
|
14
|
+
:pointer
|
15
|
+
attach_function :g_irepository_get_n_infos, [:pointer, :string], :int
|
16
|
+
attach_function :g_irepository_get_info,
|
17
|
+
[:pointer, :string, :int], :pointer
|
18
|
+
attach_function :g_irepository_find_by_name,
|
19
|
+
[:pointer, :string, :string], :pointer
|
20
|
+
attach_function :g_irepository_get_shared_library,
|
21
|
+
[:pointer, :string], :string
|
22
|
+
|
23
|
+
# IBaseInfo
|
24
|
+
enum :IInfoType, [
|
25
|
+
:invalid,
|
26
|
+
:function,
|
27
|
+
:callback,
|
28
|
+
:struct,
|
29
|
+
:boxed,
|
30
|
+
:enum,
|
31
|
+
:flags,
|
32
|
+
:object,
|
33
|
+
:interface,
|
34
|
+
:constant,
|
35
|
+
:error_domain,
|
36
|
+
:union,
|
37
|
+
:value,
|
38
|
+
:signal,
|
39
|
+
:vfunc,
|
40
|
+
:property,
|
41
|
+
:field,
|
42
|
+
:arg,
|
43
|
+
:type,
|
44
|
+
:unresolved
|
45
|
+
]
|
46
|
+
|
47
|
+
attach_function :g_base_info_get_type, [:pointer], :IInfoType
|
48
|
+
attach_function :g_base_info_get_name, [:pointer], :string
|
49
|
+
attach_function :g_base_info_get_namespace, [:pointer], :string
|
50
|
+
attach_function :g_base_info_is_deprecated, [:pointer], :bool
|
51
|
+
attach_function :g_base_info_equal, [:pointer, :pointer], :bool
|
52
|
+
|
53
|
+
# IFunctionInfo
|
54
|
+
attach_function :g_function_info_get_symbol, [:pointer], :string
|
55
|
+
# TODO: return type is bitfield
|
56
|
+
attach_function :g_function_info_get_flags, [:pointer], :int
|
57
|
+
|
58
|
+
# ICallableInfo
|
59
|
+
enum :ITransfer, [
|
60
|
+
:nothing,
|
61
|
+
:container,
|
62
|
+
:everything
|
63
|
+
]
|
64
|
+
|
65
|
+
attach_function :g_callable_info_get_return_type, [:pointer], :pointer
|
66
|
+
attach_function :g_callable_info_get_caller_owns, [:pointer], :ITransfer
|
67
|
+
attach_function :g_callable_info_may_return_null, [:pointer], :bool
|
68
|
+
attach_function :g_callable_info_get_n_args, [:pointer], :int
|
69
|
+
attach_function :g_callable_info_get_arg, [:pointer, :int], :pointer
|
70
|
+
|
71
|
+
# IArgInfo
|
72
|
+
enum :IDirection, [
|
73
|
+
:in,
|
74
|
+
:out,
|
75
|
+
:inout
|
76
|
+
]
|
77
|
+
|
78
|
+
enum :IScopeType, [
|
79
|
+
:invalid,
|
80
|
+
:call,
|
81
|
+
:async,
|
82
|
+
:notified
|
83
|
+
]
|
84
|
+
|
85
|
+
attach_function :g_arg_info_get_direction, [:pointer], :IDirection
|
86
|
+
attach_function :g_arg_info_is_return_value, [:pointer], :bool
|
87
|
+
attach_function :g_arg_info_is_optional, [:pointer], :bool
|
88
|
+
attach_function :g_arg_info_may_be_null, [:pointer], :bool
|
89
|
+
attach_function :g_arg_info_get_ownership_transfer, [:pointer], :ITransfer
|
90
|
+
attach_function :g_arg_info_get_scope, [:pointer], :IScopeType
|
91
|
+
attach_function :g_arg_info_get_closure, [:pointer], :int
|
92
|
+
attach_function :g_arg_info_get_destroy, [:pointer], :int
|
93
|
+
attach_function :g_arg_info_get_type, [:pointer], :pointer
|
94
|
+
|
95
|
+
# The values of ITypeTag were changed in an incompatible way between
|
96
|
+
# gobject-introspection version 0.9.0 and 0.9.1. Therefore, we need to
|
97
|
+
# retrieve the correct values before declaring the ITypeTag enum.
|
98
|
+
attach_function :tmp_type_tag_to_string, :g_type_tag_to_string, [:int], :string
|
99
|
+
arr = (0..31).map { |i| [tmp_type_tag_to_string(i).to_sym, i] }.flatten
|
100
|
+
enum :ITypeTag, arr
|
101
|
+
|
102
|
+
# Now, attach g_type_tag_to_string again under its own name with an
|
103
|
+
# improved signature.
|
104
|
+
attach_function :g_type_tag_to_string, [:ITypeTag], :string
|
105
|
+
|
106
|
+
#define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY)
|
107
|
+
|
108
|
+
attach_function :g_type_info_is_pointer, [:pointer], :bool
|
109
|
+
attach_function :g_type_info_get_tag, [:pointer], :ITypeTag
|
110
|
+
attach_function :g_type_info_get_param_type, [:pointer, :int], :pointer
|
111
|
+
attach_function :g_type_info_get_interface, [:pointer], :pointer
|
112
|
+
attach_function :g_type_info_get_array_length, [:pointer], :int
|
113
|
+
attach_function :g_type_info_get_array_fixed_size, [:pointer], :int
|
114
|
+
attach_function :g_type_info_is_zero_terminated, [:pointer], :bool
|
115
|
+
attach_function :g_type_info_get_n_error_domains, [:pointer], :int
|
116
|
+
attach_function :g_type_info_get_error_domain, [:pointer, :int], :pointer
|
117
|
+
|
118
|
+
# IStructInfo
|
119
|
+
attach_function :g_struct_info_get_n_fields, [:pointer], :int
|
120
|
+
attach_function :g_struct_info_get_field, [:pointer, :int], :pointer
|
121
|
+
attach_function :g_struct_info_get_n_methods, [:pointer], :int
|
122
|
+
attach_function :g_struct_info_get_method, [:pointer, :int], :pointer
|
123
|
+
attach_function :g_struct_info_find_method, [:pointer, :string], :pointer
|
124
|
+
attach_function :g_struct_info_get_size, [:pointer], :int
|
125
|
+
attach_function :g_struct_info_get_alignment, [:pointer], :int
|
126
|
+
attach_function :g_struct_info_is_gtype_struct, [:pointer], :bool
|
127
|
+
|
128
|
+
# IValueInfo
|
129
|
+
attach_function :g_value_info_get_value, [:pointer], :long
|
130
|
+
|
131
|
+
# IFieldInfo
|
132
|
+
enum :IFieldInfoFlags, [
|
133
|
+
:readable, (1 << 0),
|
134
|
+
:writable, (1 << 1)
|
135
|
+
]
|
136
|
+
attach_function :g_field_info_get_flags, [:pointer], :IFieldInfoFlags
|
137
|
+
attach_function :g_field_info_get_size, [:pointer], :int
|
138
|
+
attach_function :g_field_info_get_offset, [:pointer], :int
|
139
|
+
attach_function :g_field_info_get_type, [:pointer], :pointer
|
140
|
+
|
141
|
+
# IUnionInfo
|
142
|
+
# IStructInfo
|
143
|
+
# IRegisteredTypeInfo
|
144
|
+
|
145
|
+
# IEnumInfo
|
146
|
+
attach_function :g_enum_info_get_storage_type, [:pointer], :ITypeTag
|
147
|
+
attach_function :g_enum_info_get_n_values, [:pointer], :int
|
148
|
+
attach_function :g_enum_info_get_value, [:pointer, :int], :pointer
|
149
|
+
|
150
|
+
# IObjectInfo
|
151
|
+
attach_function :g_object_info_get_type_name, [:pointer], :string
|
152
|
+
attach_function :g_object_info_get_type_init, [:pointer], :string
|
153
|
+
attach_function :g_object_info_get_abstract, [:pointer], :bool
|
154
|
+
attach_function :g_object_info_get_parent, [:pointer], :pointer
|
155
|
+
attach_function :g_object_info_get_n_interfaces, [:pointer], :int
|
156
|
+
attach_function :g_object_info_get_interface, [:pointer, :int], :pointer
|
157
|
+
attach_function :g_object_info_get_n_fields, [:pointer], :int
|
158
|
+
attach_function :g_object_info_get_field, [:pointer, :int], :pointer
|
159
|
+
attach_function :g_object_info_get_n_properties, [:pointer], :int
|
160
|
+
attach_function :g_object_info_get_property, [:pointer, :int], :pointer
|
161
|
+
attach_function :g_object_info_get_n_methods, [:pointer], :int
|
162
|
+
attach_function :g_object_info_get_method, [:pointer, :int], :pointer
|
163
|
+
attach_function :g_object_info_find_method, [:pointer, :string], :pointer
|
164
|
+
attach_function :g_object_info_get_n_signals, [:pointer], :int
|
165
|
+
attach_function :g_object_info_get_signal, [:pointer, :int], :pointer
|
166
|
+
attach_function :g_object_info_get_n_vfuncs, [:pointer], :int
|
167
|
+
attach_function :g_object_info_get_vfunc, [:pointer, :int], :pointer
|
168
|
+
attach_function :g_object_info_find_vfunc, [:pointer, :string], :pointer
|
169
|
+
attach_function :g_object_info_get_n_constants, [:pointer], :int
|
170
|
+
attach_function :g_object_info_get_constant, [:pointer, :int], :pointer
|
171
|
+
attach_function :g_object_info_get_class_struct, [:pointer], :pointer
|
172
|
+
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module GirFFI
|
2
|
+
# Base class for builders of #method_missing definitions.
|
3
|
+
class MethodMissingDefinitionBuilder
|
4
|
+
def initialize lib, namespace
|
5
|
+
@lib = lib
|
6
|
+
@namespace = namespace
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate
|
10
|
+
args = arguments.map {|arg| "\"#{arg}\""}
|
11
|
+
|
12
|
+
return <<-CODE
|
13
|
+
def #{slf}method_missing method, *arguments, &block
|
14
|
+
result = GirFFI::Builder.#{fn} #{args.join ', '}, #{libs.join ', '}, self, method.to_s
|
15
|
+
return super unless result
|
16
|
+
if block.nil?
|
17
|
+
self.send method, *arguments
|
18
|
+
else
|
19
|
+
self.send method, *arguments, &block
|
20
|
+
end
|
21
|
+
end
|
22
|
+
CODE
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Builds a #method_missing for a module. This method_missing will be
|
27
|
+
# called for missing module methods; these modules are not meant for
|
28
|
+
# #include'ing.
|
29
|
+
class ModuleMethodMissingDefinitionBuilder < MethodMissingDefinitionBuilder
|
30
|
+
private
|
31
|
+
|
32
|
+
def slf; "self."; end
|
33
|
+
def fn; "setup_function"; end
|
34
|
+
def arguments; [@namespace]; end
|
35
|
+
def libs; [@lib]; end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Builds a #method_missing for missing instance methods.
|
39
|
+
class InstanceMethodMissingDefinitionBuilder < MethodMissingDefinitionBuilder
|
40
|
+
def initialize lib, modul, namespace, classname
|
41
|
+
super lib, namespace
|
42
|
+
@classname = classname
|
43
|
+
@module = modul
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def slf; ""; end
|
49
|
+
def fn; "setup_method"; end
|
50
|
+
def arguments; [@namespace, @classname]; end
|
51
|
+
def libs; [@lib, @module]; end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Builds a #method_missing for missing class methods.
|
55
|
+
class ClassMethodMissingDefinitionBuilder < InstanceMethodMissingDefinitionBuilder
|
56
|
+
private
|
57
|
+
|
58
|
+
def slf; "self."; end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'gir_ffi/builder_helper'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
# Builds a module based on information found in the introspection
|
5
|
+
# repository.
|
6
|
+
class ModuleBuilder
|
7
|
+
|
8
|
+
def initialize namespace, box
|
9
|
+
@namespace = namespace
|
10
|
+
@box = box
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate
|
14
|
+
build_module
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def build_module
|
20
|
+
IRepository.default.require @namespace, nil
|
21
|
+
setup_module
|
22
|
+
setup_lib_for_ffi
|
23
|
+
unless @module.respond_to? :method_missing
|
24
|
+
@module.class_eval module_method_missing_definition
|
25
|
+
@module.class_eval const_missing_definition
|
26
|
+
end
|
27
|
+
@module
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_module
|
31
|
+
if @box.nil?
|
32
|
+
boxm = ::Object
|
33
|
+
else
|
34
|
+
boxm = BuilderHelper.get_or_define_module ::Object, @box.to_s
|
35
|
+
end
|
36
|
+
@module = BuilderHelper.get_or_define_module boxm, @namespace.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def setup_lib_for_ffi
|
40
|
+
@lib = BuilderHelper.get_or_define_module @module, :Lib
|
41
|
+
|
42
|
+
unless (class << @lib; self.include? FFI::Library; end)
|
43
|
+
@lib.extend FFI::Library
|
44
|
+
libs = IRepository.default.shared_library(@namespace).split(/,/)
|
45
|
+
@lib.ffi_lib(*libs)
|
46
|
+
end
|
47
|
+
|
48
|
+
BuilderHelper.optionally_define_constant(@lib, :CALLBACKS) { [] }
|
49
|
+
end
|
50
|
+
|
51
|
+
def module_method_missing_definition
|
52
|
+
ModuleMethodMissingDefinitionBuilder.new(@lib, @namespace).generate
|
53
|
+
end
|
54
|
+
|
55
|
+
def const_missing_definition
|
56
|
+
box = @box.nil? ? "nil" : "\"#{@box}\""
|
57
|
+
return <<-CODE
|
58
|
+
def self.const_missing classname
|
59
|
+
info = IRepository.default.find_by_name "#{@namespace}", classname.to_s
|
60
|
+
return super if info.nil?
|
61
|
+
return GirFFI::Builder.build_class "#{@namespace}", classname.to_s, #{box}
|
62
|
+
end
|
63
|
+
CODE
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
GirFFI::Builder.setup_function "Gtk", Gtk::Lib, Gtk, "init"
|
2
|
+
module Gtk
|
3
|
+
class << self
|
4
|
+
alias _base_init init
|
5
|
+
def init
|
6
|
+
(my_len, my_args) = _base_init ARGV.length + 1, [$0, *ARGV]
|
7
|
+
my_args.shift
|
8
|
+
ARGV.replace my_args
|
9
|
+
end
|
10
|
+
private :_base_init
|
11
|
+
end
|
12
|
+
end
|
data/tasks/bones.rake
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# The following code is copied straight from Bones 2.5.1
|
2
|
+
#
|
3
|
+
require 'pp'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
module Bones
|
7
|
+
|
8
|
+
# Helper module that will pretty print OpenStruct objects. It is used mainly
|
9
|
+
# for debugging the Mr Bones project open struct.
|
10
|
+
#
|
11
|
+
module Debug
|
12
|
+
|
13
|
+
# :stopdoc:
|
14
|
+
KEY_LENGTH = 20
|
15
|
+
VAR_LENGTH = 78 - 6 - KEY_LENGTH
|
16
|
+
SEP = "\n" + ' '*(KEY_LENGTH+6)
|
17
|
+
FMT = " %-#{KEY_LENGTH}s => %s"
|
18
|
+
# :startdoc:
|
19
|
+
|
20
|
+
# Print all the keys for the given _ostruct_ to stdout. If a _prefix_ is
|
21
|
+
# given, then the open struct keys will be prefixed with this string.
|
22
|
+
#
|
23
|
+
def self.show( ostruct, prefix = '' )
|
24
|
+
sio = StringIO.new
|
25
|
+
|
26
|
+
h = ostruct.instance_variable_get(:@table)
|
27
|
+
h.keys.map {|k| k.to_s}.sort.each do |k|
|
28
|
+
sio.seek 0
|
29
|
+
sio.truncate 0
|
30
|
+
next if k =~ %r/^_/o
|
31
|
+
|
32
|
+
val = h[k.to_sym]
|
33
|
+
if val.instance_of?(OpenStruct)
|
34
|
+
self.show(val, prefix + k + '.')
|
35
|
+
else
|
36
|
+
PP.pp(val, sio, VAR_LENGTH)
|
37
|
+
sio.seek 0
|
38
|
+
val = sio.read
|
39
|
+
val = val.split("\n").join(SEP)
|
40
|
+
|
41
|
+
key = prefix + k
|
42
|
+
key[(KEY_LENGTH-3)..-1] = '...' if key.length > KEY_LENGTH
|
43
|
+
puts(FMT % [key, val])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Print a single attribute from the given _ostruct_ to stdout. The
|
49
|
+
# attributed is identified by the given _key_.
|
50
|
+
#
|
51
|
+
def self.show_attr( ostruct, key )
|
52
|
+
sio = StringIO.new
|
53
|
+
|
54
|
+
key = key.dup if key.frozen?
|
55
|
+
val = key.split('.').inject(ostruct) {|os,k| os.send(k)}
|
56
|
+
|
57
|
+
if val.instance_of?(OpenStruct)
|
58
|
+
self.show(val, key + '.')
|
59
|
+
else
|
60
|
+
PP.pp(val, sio, VAR_LENGTH)
|
61
|
+
sio.seek 0
|
62
|
+
val = sio.read
|
63
|
+
val = val.split("\n").join(SEP)
|
64
|
+
|
65
|
+
key[(KEY_LENGTH-3)..-1] = '...' if key.length > KEY_LENGTH
|
66
|
+
puts(FMT % [key, val])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end # module Debug
|
71
|
+
end # module Bones
|
72
|
+
|
73
|
+
namespace :bones do
|
74
|
+
|
75
|
+
desc 'Show the PROJ open struct'
|
76
|
+
task :debug do |t|
|
77
|
+
atr = if t.application.top_level_tasks.length == 2
|
78
|
+
t.application.top_level_tasks.pop
|
79
|
+
end
|
80
|
+
|
81
|
+
if atr then Bones::Debug.show_attr(PROJ, atr)
|
82
|
+
else Bones::Debug.show PROJ end
|
83
|
+
end
|
84
|
+
|
85
|
+
end # namespace :bones
|
86
|
+
|
87
|
+
# EOF
|