rbind 0.0.1

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 (48) hide show
  1. data/lib/rbind.rb +5 -0
  2. data/lib/rbind/.default_parser.rb.swp +0 -0
  3. data/lib/rbind/.generator_c.rb.swp +0 -0
  4. data/lib/rbind/core.rb +13 -0
  5. data/lib/rbind/core/.rbase.rb.swp +0 -0
  6. data/lib/rbind/core/.rclass.rb.swp +0 -0
  7. data/lib/rbind/core/.rdata_type.rb.swp +0 -0
  8. data/lib/rbind/core/.roperation.rb.swp +0 -0
  9. data/lib/rbind/core/rattribute.rb +45 -0
  10. data/lib/rbind/core/rbase.rb +172 -0
  11. data/lib/rbind/core/rclass.rb +149 -0
  12. data/lib/rbind/core/rconst.rb +35 -0
  13. data/lib/rbind/core/rdata_type.rb +93 -0
  14. data/lib/rbind/core/renum.rb +5 -0
  15. data/lib/rbind/core/rgetter.rb +19 -0
  16. data/lib/rbind/core/rnamespace.rb +305 -0
  17. data/lib/rbind/core/roperation.rb +128 -0
  18. data/lib/rbind/core/rparameter.rb +40 -0
  19. data/lib/rbind/core/rsetter.rb +20 -0
  20. data/lib/rbind/core/rstruct.rb +87 -0
  21. data/lib/rbind/default_parser.rb +253 -0
  22. data/lib/rbind/generator_c.rb +352 -0
  23. data/lib/rbind/generator_ruby.rb +357 -0
  24. data/lib/rbind/logger.rb +13 -0
  25. data/lib/rbind/rbind.rb +68 -0
  26. data/lib/rbind/templates/c/CMakeLists.txt +11 -0
  27. data/lib/rbind/templates/c/consts.h +5 -0
  28. data/lib/rbind/templates/c/conversions.cc +4 -0
  29. data/lib/rbind/templates/c/conversions.hpp +10 -0
  30. data/lib/rbind/templates/c/find_package.txt +5 -0
  31. data/lib/rbind/templates/c/operation_wrapper.cc +15 -0
  32. data/lib/rbind/templates/c/operations.cc +23 -0
  33. data/lib/rbind/templates/c/operations.h +20 -0
  34. data/lib/rbind/templates/c/type_conversion.cc +45 -0
  35. data/lib/rbind/templates/c/type_conversion.hpp +5 -0
  36. data/lib/rbind/templates/c/type_delete.h +14 -0
  37. data/lib/rbind/templates/c/type_typedef.h +2 -0
  38. data/lib/rbind/templates/c/type_wrapper.h +12 -0
  39. data/lib/rbind/templates/c/types.cc +6 -0
  40. data/lib/rbind/templates/c/types.h +17 -0
  41. data/lib/rbind/templates/ruby/rbind.rb +44 -0
  42. data/lib/rbind/templates/ruby/rmethod.rb +12 -0
  43. data/lib/rbind/templates/ruby/rnamespace.rb +7 -0
  44. data/lib/rbind/templates/ruby/rstatic_method.rb +5 -0
  45. data/lib/rbind/templates/ruby/rtype.rb +77 -0
  46. data/lib/rbind/templates/ruby/rtype_constructor.rb +4 -0
  47. data/rbind.gemspec +17 -0
  48. metadata +101 -0
@@ -0,0 +1,5 @@
1
+
2
+ module Rbind
3
+ class REnum < RDataType
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module Rbind
3
+ class RGetter < ROperation
4
+ attr_reader :attribute
5
+
6
+ def initialize(attr)
7
+ @attribute = attr
8
+ super("get_#{attr.name}",attr.type)
9
+ end
10
+
11
+ def attribute?
12
+ true
13
+ end
14
+
15
+ def signature
16
+ attribute.signature
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,305 @@
1
+
2
+ module Rbind
3
+ class RNamespace< RDataType
4
+ class << self
5
+ attr_accessor :default_type_names
6
+ end
7
+ self.default_type_names = [:int,:int64,:bool,:double,:float,:void,:char,:size_t]
8
+
9
+ attr_reader :operations
10
+ attr_reader :operation_alias
11
+ attr_reader :consts
12
+ attr_reader :used_namespaces
13
+ attr_accessor :root
14
+
15
+ def initialize(name,*flags)
16
+ @consts = Hash.new
17
+ @types = Hash.new
18
+ @operations = Hash.new{|hash,key| hash[key] = Array.new}
19
+ @operation_alias = Hash.new{|hash,key| hash[key] = Array.new}
20
+ @used_namespaces = Hash.new
21
+ super(name,*flags)
22
+ end
23
+
24
+ def root?
25
+ !!root
26
+ end
27
+
28
+ def constructor?
29
+ false
30
+ end
31
+
32
+ def types
33
+ @types.values
34
+ end
35
+
36
+ def delete_type(name)
37
+ ns = RBase.namespace(name)
38
+ if ns
39
+ type(ns).delete_type(RBase.basename(name))
40
+ else
41
+ @types.delete(name)
42
+ end
43
+ end
44
+
45
+ def use_namespace(namespace)
46
+ @used_namespaces[namespace.name] = namespace
47
+ end
48
+
49
+ def each_type(childs=true,&block)
50
+ if block_given?
51
+ types.each do |t|
52
+ yield t
53
+ t.each_type(&block) if childs && t.respond_to?(:each_type)
54
+ end
55
+ else
56
+ Enumerator.new(self,:each_type,childs)
57
+ end
58
+ end
59
+
60
+ def consts
61
+ @consts.values
62
+ end
63
+
64
+ def const(name,raise_ = true,search_owner = true)
65
+ c = if @consts.has_key?(name)
66
+ @consts[name]
67
+ else
68
+ if !!(ns = RBase.namespace(name))
69
+ t = type(ns,false)
70
+ t.const(RBase.basename(name),false,false) if t
71
+ end
72
+ end
73
+ c ||= begin
74
+ used_namespaces.values.each do |ns|
75
+ c = ns.const(name,false,false)
76
+ break if c
77
+ end
78
+ c
79
+ end
80
+ c ||= if search_owner && owner
81
+ owner.const(name,false)
82
+ end
83
+ raise RuntimeError,"#{full_name} has no const called #{name}" if raise_ && !c
84
+ end
85
+
86
+ def operations
87
+ @operations.values
88
+ end
89
+
90
+ def container?
91
+ true
92
+ end
93
+
94
+ def operation(name,raise_=true)
95
+ ops = @operations[name]
96
+ if(ops.size == 1)
97
+ ops.first
98
+ elsif ops.empty?
99
+ @operations.delete name
100
+ raise "#{full_name} has no operation called #{name}." if raise_
101
+ else
102
+ ops
103
+ end
104
+ end
105
+
106
+ def operation?(name)
107
+ !!operation(name,false)
108
+ end
109
+
110
+ def add_operation(op)
111
+ op.owner = self
112
+
113
+ # make sure there is no name clash
114
+ other = @operations[op.name].find do |o|
115
+ o.cname == op.cname
116
+ end
117
+ other ||= @operation_alias[op.name].find do |o|
118
+ o.cname == op.cname
119
+ end
120
+ op.alias = if !other
121
+ op.alias
122
+ elsif op.alias
123
+ name = "#{op.alias}#{@operations[op.name].size+1}"
124
+ ::Rbind.log.info "name clash: aliasing #{op.alias} --> #{name}"
125
+ name
126
+ else
127
+ name = "#{op.name}#{@operations[op.name].size+1}"
128
+ ::Rbind.log.info "name clash: #{op.name} --> #{name}"
129
+ name
130
+ end
131
+ @operations[op.name] << op
132
+ @operation_alias[op.alias] << op if op.alias
133
+ op
134
+ end
135
+
136
+ def add_namespace(namespace)
137
+ names = namespace.split("::")
138
+ current_type = self
139
+ while !names.empty?
140
+ name = names.shift
141
+ temp = current_type.type(name,false,false)
142
+ current_type = if temp
143
+ temp
144
+ else
145
+ ::Rbind.log.info "missing namespace: add #{current_type.full_name unless current_type.root?}::#{name}"
146
+ current_type.add_type(RNamespace.new(name))
147
+ end
148
+ end
149
+ current_type
150
+ end
151
+
152
+ def add_const(const)
153
+ if const(const.full_name,false,false)
154
+ raise ArgumentError,"#A const with the name #{const.full_name} already exists"
155
+ end
156
+ if const.namespace? && self.full_name != const.namespace
157
+ t=type(const.namespace,false)
158
+ t ||= add_namespace(const.namespace)
159
+ t.add_const(const)
160
+ else
161
+ const.owner = self
162
+ @consts[const.name] = const
163
+ end
164
+ const
165
+ end
166
+
167
+ def add_default_types
168
+ add_simple_types RNamespace.default_type_names
169
+ add_type ::Rbind::RDataType.new("uchar").cname("unsigned char")
170
+ add_type ::Rbind::RDataType.new("uint64").typedef("unsigned long long")
171
+ add_type ::Rbind::RDataType.new("c_string").cname("char *")
172
+ add_type ::Rbind::RDataType.new("const_c_string").cname("const char *")
173
+ end
174
+
175
+ def add_simple_type(name)
176
+ add_type(RDataType.new(name))
177
+ end
178
+
179
+ def add_simple_types(*names)
180
+ names.flatten!
181
+ names.each do |n|
182
+ add_simple_type(n)
183
+ end
184
+ end
185
+
186
+ def add_type(type)
187
+ raise ArgumentError, "wrong parmeter type #{type}" unless type.is_a? RDataType
188
+ if type(type.full_name,false,false)
189
+ raise ArgumentError,"A type with the name #{type.full_name} already exists"
190
+ end
191
+ # if self is not the right namespace
192
+ if type.namespace? && self.full_name != type.namespace && !(self.full_name =~/(.*)::#{type.namespace}/)
193
+ t=type(type.namespace,false)
194
+ t ||=add_namespace(type.namespace)
195
+ t.add_type(type)
196
+ else
197
+ type.owner = self
198
+ @types[type.name] = type
199
+ end
200
+ type
201
+ end
202
+
203
+ def type(name,raise_ = true,search_owner = true)
204
+ ptr = name.include?("*")
205
+ ref = name.include?("&")
206
+ if(ptr && ref)
207
+ raise ArgumentError,"given type is a reference and pointer at the same time: #{name}"
208
+ end
209
+ name = name.gsub("*","").gsub("&","")
210
+ name = name.chomp(" ")
211
+ t = if @types.has_key?(name)
212
+ @types[name]
213
+ else
214
+ if !!(ns = RBase.namespace(name))
215
+ ns = ns.split("::")
216
+ ns << RBase.basename(name)
217
+ t = type(ns.shift,false)
218
+ t.type(ns.join("::"),false,false) if t
219
+ end
220
+ end
221
+ t ||= begin
222
+ used_namespaces.values.each do |ns|
223
+ t = ns.type(name,false,false)
224
+ break if t
225
+ end
226
+ t
227
+ end
228
+ t ||= if search_owner && owner
229
+ owner.type(name,false)
230
+ end
231
+ raise RuntimeError,"#{full_name} has no type called #{name}" if raise_ && !t
232
+ if t && (ptr || ref)
233
+ t = t.clone
234
+ t.ref = ref
235
+ t.ptr = ptr
236
+ end
237
+ t
238
+ end
239
+
240
+ def pretty_print_name
241
+ "namespace #{full_name}#{" Flags: #{flags.join(", ")}" unless flags.empty?}"
242
+ end
243
+
244
+ def root?
245
+ !!root
246
+ end
247
+
248
+ def pretty_print(pp)
249
+ pp.text pretty_print_name
250
+
251
+ unless consts.empty?
252
+ pp.nest(2) do
253
+ pp.breakable
254
+ pp.text "Consts:"
255
+ pp.nest(2) do
256
+ consts.each do |c|
257
+ pp.breakable
258
+ pp.pp(c)
259
+ end
260
+ end
261
+ end
262
+ end
263
+ unless types.empty?
264
+ pp.nest(2) do
265
+ pp.breakable
266
+ pp.text "Types:"
267
+ pp.nest(2) do
268
+ types.each do |t|
269
+ pp.breakable
270
+ pp.pp(t)
271
+ end
272
+ end
273
+ end
274
+ end
275
+
276
+ unless operations.empty?
277
+ pp.nest(2) do
278
+ pp.breakable
279
+ pp.text "Operations:"
280
+ pp.nest(2) do
281
+ operations.each do |op|
282
+ op.each do |o|
283
+ pp.breakable
284
+ pp.pp(o)
285
+ end
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
291
+
292
+ def method_missing(m,*args)
293
+ t = type(m.to_s,false)
294
+ return t if t
295
+
296
+ op = operation(m.to_s,false)
297
+ return op if op
298
+
299
+ super
300
+ end
301
+ end
302
+ end
303
+
304
+
305
+
@@ -0,0 +1,128 @@
1
+
2
+ module Rbind
3
+ class ROperation < RBase
4
+ attr_accessor :return_type
5
+ attr_accessor :parameters
6
+ attr_accessor :cparameters
7
+ attr_accessor :base_class
8
+ attr_accessor :ambiguous_name
9
+
10
+ def initialize(name,return_type,*args)
11
+ super(name)
12
+ raise ArgumentError ,"wrong type #{return_type}" if return_type && !return_type.is_a?(RDataType)
13
+ @return_type = return_type
14
+ @parameters = args.flatten
15
+ @parameters.each do |para|
16
+ raise ArgumentError ,"wrong parameter type#{para}" if !para.is_a?(RParameter)
17
+ end
18
+ @cparameters = @parameters
19
+ end
20
+
21
+ def ==(other)
22
+ return false unless name == other.name
23
+ @parameters.each_with_index do |p,i|
24
+ return false if p != other.parameters[i]
25
+ end
26
+ true
27
+ end
28
+
29
+ # returns true if the operations is in inherit
30
+ # from one of the base classes
31
+ def inherit?
32
+ @base_class != @owner
33
+ end
34
+
35
+ def operator?
36
+ op = operator
37
+ op && op != '[]' && op != '()'
38
+ end
39
+
40
+ # for now returns true if the owner class
41
+ # has no constructor
42
+ def abstract?
43
+ !base_class.operation(base_class.name,false)
44
+ end
45
+
46
+ # operations with ambiguous name lookup due to multi inheritance
47
+ def ambiguous_name?
48
+ !!@ambiguous_name
49
+ end
50
+
51
+ def operator
52
+ name =~ /operator ?(.*)/
53
+ $1
54
+ end
55
+
56
+ def parameter(idx)
57
+ @parameters[idx]
58
+ end
59
+
60
+ def valid_flags
61
+ super << :S << :explicit
62
+ end
63
+
64
+ def static?
65
+ @flags.include?(:S)
66
+ end
67
+
68
+ def generate_signatures
69
+ s = "#{return_type.signature} " unless constructor?
70
+ s = "#{s}#{full_name}(#{parameters.map(&:signature).join(", ")})"
71
+
72
+ cs = if constructor?
73
+ owner.to_ptr.csignature if owner
74
+ else
75
+ if return_type.basic_type?
76
+ return_type.csignature
77
+ else
78
+ return_type.to_ptr.csignature
79
+ end
80
+ end
81
+ paras = cparameters.map do |p|
82
+ if p.type.basic_type?
83
+ p.csignature
84
+ else
85
+ tp = p.to_ptr
86
+ "#{tp.csignature}"
87
+ end
88
+ end.join(", ")
89
+ cs = "#{cs} #{cname}(#{paras})"
90
+ [s,cs]
91
+ end
92
+
93
+ def instance_method?
94
+ owner.is_a?(RStruct) && !constructor? && !static?
95
+ end
96
+
97
+ def owner=(obj)
98
+ super
99
+ @base_class ||=obj
100
+ @cparameters = if instance_method?
101
+ p = RParameter.new("rbind_obj",obj,nil,:IO)
102
+ [p] + @parameters
103
+ else
104
+ @parameters
105
+ end
106
+ @parameters.each do |para|
107
+ para.owner = self
108
+ end
109
+ self
110
+ end
111
+
112
+ def constructor?
113
+ !@return_type
114
+ end
115
+
116
+ def attribute?
117
+ false
118
+ end
119
+
120
+ def pretty_print(pp)
121
+ if cname
122
+ pp.text "#{signature} --> #{cname}"
123
+ else
124
+ pp.text signature
125
+ end
126
+ end
127
+ end
128
+ end