rbind 0.0.27 → 0.0.33

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 35c0ae5064a1ce8f8300cd4c05a55023ea335709
4
- data.tar.gz: 199b59b9b1276492efc6c8dc1ae647f1767948f5
2
+ SHA256:
3
+ metadata.gz: eea754672174a0aa6ab449d1df8bea30400e7720f5a0cd701b74bd01d377f60b
4
+ data.tar.gz: d771496b0cea68ecc142775ff45a4f41397f4f40b114c6748aea8dc67c9118c3
5
5
  SHA512:
6
- metadata.gz: 1cdc8e6a92bf75d18c22b51e2bb8f109eba3d40e7ea098ec06ecef746cb42266c6b6fe9970f4287d16ea567eb3770b3909c0103473aca774e386436ed9d66602
7
- data.tar.gz: 9a7da3274763ca86e8d898b8f941d58a802daa7b3c6a6dda3fdded7bbe307c8fea0dc423f130f303cfb996e26653d3f2df1c4fd5cf1ca84ff77d7d3cc7a32fb3
6
+ metadata.gz: 4813c2cb91f792c17587adb578d367fe1998f66d8cafea9290e19f3b6d146786b3d1acaebd10f47cb6fd30aaa26764bfa9c33fd8eeed1b95cd80d0da5cc23660
7
+ data.tar.gz: 1182a9bcf4d35623d50eb866be4fdc48a2ada495d1e1f7e54bc5a61e45341ca89f1ea70b9e0b80110e36d8dfba93cf3b11565b4df829a2033569c75160fb4fa5
@@ -123,7 +123,7 @@ module Rbind
123
123
  end
124
124
 
125
125
  def owner=(obj)
126
- raise ArgumentError,"Cannot at self as owner" if obj.object_id == self.object_id
126
+ raise ArgumentError,"Cannot add self as owner" if obj.object_id == self.object_id
127
127
  @owner = obj
128
128
  @namespace = nil
129
129
  end
@@ -8,6 +8,7 @@ module Rbind
8
8
  @static = true
9
9
  para << RParameter.new("ptr",from_class.to_ptr)
10
10
  end
11
+ para << RParameter.new("parse_ownership",to_class.type("bool"))
11
12
  super(name,to_class.to_ptr,para)
12
13
  end
13
14
  end
@@ -86,37 +86,43 @@ module Rbind
86
86
  # temporarily add all base class operations
87
87
  own_ops = @operations.dup
88
88
  parent_classes.each do |k|
89
- add_operation RCastOperation.new("castTo#{k.name}",k)
90
- if k.polymorphic?
91
- add_operation RCastOperation.new("castFrom#{k.name}",self,k)
92
- end
93
- k.operations.each do |other_ops|
94
- next if other_ops.empty?
95
- ops = if @operations.has_key?(other_ops.first.name)
96
- @operations[other_ops.first.name]
97
- else
98
- []
99
- end
100
- other_ops.delete_if do |other_op|
101
- next true if !other_op || other_op.constructor?
102
- op = ops.find do |o|
103
- o == other_op
104
- end
105
- next false if !op
106
- next true if op.base_class == self
107
- next true if op.base_class == other_op.base_class
108
- # ambiguous name look up due to multi
109
- # inheritance
110
- op.ambiguous_name = true
111
- other_op.ambiguous_name = true
112
- false
113
- end
114
- other_ops = other_ops.map(&:dup)
115
- other_ops.each do |other|
116
- old = other.alias
117
- add_operation other
118
- end
89
+ add_operation RCastOperation.new("castTo#{k.name.gsub(/[:,<>]/,"_")}",k)
90
+ if k.polymorphic? && polymorphic?
91
+ add_operation RCastOperation.new("castFrom#{k.name.gsub(/[:,<>]/,"_")}",self,k)
119
92
  end
93
+ k.operations.each do |other_ops|
94
+ next if other_ops.empty?
95
+ ops = if @operations.has_key?(other_ops.first.name)
96
+ @operations[other_ops.first.name]
97
+ else
98
+ []
99
+ end
100
+ other_ops.delete_if do |other_op|
101
+ next true if !other_op || other_op.constructor? || other_op.static?
102
+ #check for name hiding
103
+ if own_ops.has_key?(other_op.name)
104
+ #puts "#{other_op} is shadowed by #{own_ops[other_op.name].first}"
105
+ next true
106
+ end
107
+ op = ops.find do |o|
108
+ o == other_op
109
+ end
110
+ next false if !op
111
+ next true if op.base_class == self
112
+ next true if op.base_class == other_op.base_class
113
+
114
+ # ambiguous name look up due to multi
115
+ # inheritance
116
+ op.ambiguous_name = true
117
+ other_op.ambiguous_name = true
118
+ false
119
+ end
120
+ other_ops = other_ops.map(&:dup)
121
+ other_ops.each do |other|
122
+ old = other.alias
123
+ add_operation other
124
+ end
125
+ end
120
126
  end
121
127
  # copy embedded arrays other wise they might get modified outside
122
128
  result = @operations.values.map(&:dup)
@@ -214,12 +220,15 @@ module Rbind
214
220
  raise ArgumentError, "klass name is empty"
215
221
  end
216
222
  if parent? klass
217
- raise ArgumentError,"#A parent class with the name #{klass.name} already exists"
223
+ puts "ignore: parent class #{klass.name} was added multiple time to class #{name}"
224
+ return self
218
225
  end
219
226
  if klass.full_name == full_name || klass == self
220
- raise ArgumentError,"class #{klass.full_name} cannot be parent of its self"
227
+ puts "ignore: class #{klass.name} cannot be parent class of itself"
228
+ return self
221
229
  end
222
230
  @parent_classes[klass.name] = ParentClass.new(klass,accessor)
231
+ raise "Cannot use namespace #{klass.full_name} as parent class for #{self.full_name}" unless(klass.respond_to?(:child?))
223
232
  klass.add_child(self,accessor) unless klass.child?(self)
224
233
  self
225
234
  end
@@ -5,7 +5,7 @@ module Rbind
5
5
 
6
6
  def initialize(attr)
7
7
  @attribute = attr
8
- super("get_#{attr.name}",attr.type)
8
+ super("get_#{attr.name}",attr.type.to_const)
9
9
  end
10
10
 
11
11
  def attribute?
@@ -13,8 +13,8 @@ module Rbind
13
13
  attr_accessor :default_operator_alias
14
14
  end
15
15
  # TODO move somewhere else
16
- self.default_type_names = [:int,:int8,:int32,:int64,:uint,:uint8,:uint32,:uint64,
17
- :int8_t,:int32_t,:int64_t,:uint8_t,:uint32_t,:uint64_t,
16
+ self.default_type_names = [:int,:int8,:int16,:int32,:int64,:uint,:uint8,:uint16,:uint32,:uint64,
17
+ :int8_t,:int16_t,:int32_t,:int64_t,:uint8_t,:uint16_t,:uint32_t,:uint64_t,
18
18
  :bool,:double,:float,:void,:char,:size_t,:long,
19
19
  :uchar, :char16, :char32, :ushort, :ulong, :ulong_long,
20
20
  :uint128, :short, :long_long, :int128, :long_double,
@@ -132,13 +132,28 @@ module Rbind
132
132
  end
133
133
  end
134
134
 
135
+ def enum_hash
136
+ @enum_hash ||= Hash.new # cache values so that they can be modified
137
+ @types.each_value do |t|
138
+ next unless t.is_a? REnum
139
+ t.values.each do |key,value|
140
+ next if @enum_hash.has_key?(key)
141
+ p = RParameter.new(key,type("const int"),value)
142
+ p.owner = self
143
+ @enum_hash[key] = p
144
+ end
145
+ end
146
+ @enum_hash
147
+ end
148
+
135
149
  def consts
136
- @consts.values
150
+ @consts.values+enum_hash.values
137
151
  end
138
152
 
139
153
  def const(name,raise_ = true,search_owner = true)
140
- c = if @consts.has_key?(name)
141
- @consts[name]
154
+ hash = @consts.merge(enum_hash)
155
+ c = if hash.has_key?(name)
156
+ hash[name]
142
157
  else
143
158
  if !!(ns = RBase.namespace(name))
144
159
  t = type(ns,false)
@@ -260,12 +275,12 @@ module Rbind
260
275
  op.alias = if !other
261
276
  op.alias
262
277
  elsif op.alias
263
- name = "#{op.alias}#{@operations[op.name].size+1}"
278
+ name = "#{op.alias}__#{@operations[op.name].size+1}"
264
279
  ::Rbind.log.debug "add_operation: name clash: aliasing #{op.alias} --> #{name}"
265
280
  name
266
281
  else
267
282
  op.auto_alias = true
268
- name = "#{op.name}#{@operations[op.name].size+1}"
283
+ name = "#{op.name}__#{@operations[op.name].size+1}"
269
284
  ::Rbind.log.debug "add_operation: name clash: #{op.name} --> #{name}"
270
285
  name
271
286
  end
@@ -292,6 +307,11 @@ module Rbind
292
307
  current_type
293
308
  end
294
309
 
310
+ def add_const_val(name,value)
311
+ c = RParameter.new(name,type("const int"),value)
312
+ add_const(c)
313
+ end
314
+
295
315
  def add_const(const)
296
316
  const.const!
297
317
  if(c = const(const.full_name,false,false))
@@ -415,10 +435,23 @@ module Rbind
415
435
  # under the given name
416
436
  t ||= if search_owner && name =~ /([:\w]*)<(.*)>$/
417
437
  t = type($1,false) if $1 && !$1.empty?
418
- t2 = type($2,false) if $2 && !$2.empty?
438
+ t2 = if $2 && !$2.empty?
439
+ t2 = $2.split(',')
440
+ bok = true
441
+ t2 = t2.map do |t3|
442
+ t3 = type(t3,false)
443
+ bok = false unless t3
444
+ t3
445
+ end
446
+ if bok
447
+ t2
448
+ else
449
+ nil
450
+ end
451
+ end
419
452
  # template is known to this library
420
453
  if t && t2
421
- name = "#{t.name}<#{t2.full_name}>"
454
+ name = "#{t.name}<#{t2.map{|t|t.full_name}.join(",")}>"
422
455
  t3 ||= t.owner.type(name,false,false)
423
456
  t3 ||= begin
424
457
  if !t.template?
@@ -439,7 +472,8 @@ module Rbind
439
472
  # generic template is unknown
440
473
  # check if specialised template is known
441
474
  elsif t2 && $1 && !$1.empty?
442
- real_name = "#{$1}<#{t2.full_name}>".gsub(">>","> >")
475
+ real_name = t2.map{|v|v.full_name}.join(",");
476
+ real_name = "#{$1}<#{real_name}>".gsub(">>","> >")
443
477
  type(real_name,false) if(real_name != name) # prevent stack level too deep
444
478
  else
445
479
  nil
@@ -10,6 +10,7 @@ module Rbind
10
10
  attr_accessor :ambiguous_name
11
11
  attr_accessor :index # index if overloaded
12
12
  attr_accessor :static
13
+ attr_accessor :blocking
13
14
  attr_accessor :cplusplus_alias
14
15
 
15
16
  def initialize(name,return_type=nil,*args)
@@ -17,6 +18,7 @@ module Rbind
17
18
  @return_type = return_type
18
19
  @parameters = args.flatten
19
20
  @cplusplus_alias = true
21
+ @blocking = false
20
22
  end
21
23
 
22
24
  # indicates if an alias method shall be added
@@ -25,6 +27,10 @@ module Rbind
25
27
  !!@cplusplus_alias
26
28
  end
27
29
 
30
+ def blocking?
31
+ !!@blocking
32
+ end
33
+
28
34
  def add_parameter(para,&block)
29
35
  para = if para.is_a? String
30
36
  raise "No owner. Cannot create parameter" unless owner
@@ -2,6 +2,7 @@
2
2
  module Rbind
3
3
  class RParameter < RAttribute
4
4
  attr_accessor :default_value
5
+ attr_accessor :parse_ownership
5
6
 
6
7
  def initialize(name,type,default_value=nil)
7
8
  super(name,type)
@@ -26,6 +27,10 @@ module Rbind
26
27
  end
27
28
  end
28
29
 
30
+ def parse_ownership?
31
+ @parse_ownership != nil
32
+ end
33
+
29
34
  def to_single_ptr
30
35
  t = self.clone
31
36
  t.type = type.to_single_ptr
@@ -93,7 +93,7 @@ module Rbind
93
93
  end
94
94
 
95
95
  def to_ref
96
- to_annotation? :ref,true
96
+ to_annotation :ref,true
97
97
  end
98
98
 
99
99
  def ref?
@@ -50,6 +50,7 @@ module Rbind
50
50
  return type_name
51
51
  end
52
52
 
53
+ type_name = type_name.gsub("cv::vector","vector") # fix namespace
53
54
  if(type_name =~/^vector/ || type_name =~/^Ptr/)
54
55
  if(type_name =~ /^([a-zA-Z\d]*)_([_a-zA-Z\d]*) ?(\(?.*)\)? */)
55
56
  "#{$1}<#{unmask_template($2)}>#{$3}"
@@ -89,7 +90,8 @@ module Rbind
89
90
  array = flags.shift.split(" ")
90
91
  type_name = array.shift
91
92
  para_name = array.shift
92
- default = unmask_template(array.join(" "))
93
+ default = unmask_template(array.join(" ").gsub("/C",""))
94
+ default.gsub!("/Ref","")
93
95
  type = find_type(owner,type_name)
94
96
  flags = normalize_flags(line_number,flags,:IO,:O)
95
97
  type = if flags.include?(:O) || flags.include?(:IO)
@@ -131,14 +133,35 @@ module Rbind
131
133
  def parse_class(line_number,string)
132
134
  lines = string.split("\n")
133
135
  a = lines.shift.rstrip
134
- unless a =~ /class ([<>a-zA-Z\.\d_:]*) ?:?([<>a-zA-Z\.\:, \d_]*)(.*)/
136
+ unless a =~ /class ([,<>a-zA-Z\.\d_:]*) ?:?([<>a-zA-Z\.\:, \d_]*)(.*)/
135
137
  raise "cannot parse class #{a}"
136
138
  end
137
139
  name = $1
138
140
  parent_classes = $2
139
141
  flags = $3
140
142
  parent_classes = if parent_classes
141
- parent_classes.gsub(" ","").split(",").map do |name|
143
+ classes = parent_classes.gsub(" ","").split(",")
144
+ # join templates
145
+ classes.each_with_index do |val,i|
146
+ next unless val
147
+ if val.include?("<")
148
+ val = [val]
149
+ (i+1).upto(classes.size-1) do |i2|
150
+ val2 = classes[i2]
151
+ val << val2
152
+ classes[i2] = nil
153
+ if val2.include?(">")
154
+ break
155
+ end
156
+ end
157
+ classes[i] = val.join(",")
158
+ elsif val =="cv::class" # bug in parser
159
+ puts "ignore: parent class #{val} which is invalid for #{$1}"
160
+ classes[i] = nil
161
+ end
162
+ end
163
+ classes.compact!
164
+ classes.map do |name|
142
165
  #TODO this should also call the user callback
143
166
  t = type(RBase.normalize(name),false)
144
167
  # remove namespace and try again
@@ -155,6 +178,11 @@ module Rbind
155
178
  end
156
179
  # auto add parent class
157
180
  t ||= begin
181
+ # TODO fix error in parser
182
+ # the parser always adds the current namespace
183
+ # class Blas : public ::cv::Test
184
+ # --> cv::::cv::Test
185
+ name = name.gsub(/^.*::::/,"")
158
186
  t = add_type(RClass.new(RBase.normalize(name)))
159
187
  t.extern_package_name = @extern_package_name
160
188
  t
@@ -234,7 +262,50 @@ module Rbind
234
262
  [c,1]
235
263
  end
236
264
 
265
+ def parse_enum(line_number,string)
266
+ lines = string.split("\n")
267
+ a = lines.shift.rstrip.gsub("enum struct ","enum ")
268
+ a = a.gsub("enum class ","enum ")
269
+ unless a =~ /enum ([<>a-zA-Z\.\d_:]*)/
270
+ raise "cannot parse enum#{a}"
271
+ end
272
+ name = $1.gsub("<unnamed>","Unknown")
273
+ renum = REnum.new(name)
274
+ renum = begin
275
+ add_type(renum)
276
+ rescue => e
277
+ t = type(name)
278
+ if !t.is_a? REnum || (renum.name != "Unknown" && !renum.values.empty?)
279
+ raise "cannot overwrite #{t.class}: #{t} with #{renum.class}: #{renum}. Use forward declaration?"
280
+ end
281
+ t
282
+ end
283
+
284
+ line_counter = 1
285
+ lines.each do |line|
286
+ line_counter += 1
287
+ line =~ /const ([<>a-zA-Z\.\d_:]*) (.*) \[\]/
288
+ val = $2.strip
289
+ name = $1.strip
290
+ name = name.gsub("#{renum.full_name.gsub("::",".")}.","") # bug in hdl_parser giving full name for some of the types
291
+ name = name.gsub("#{renum.namespace.gsub("::",".")}.","")
292
+ Set.new(val.split(/[ ><\+\-\*\/\&\|\)\(\~]/)).each do |v|
293
+ c = const(v,false)
294
+ if c
295
+ val.gsub!(v,c.full_name)
296
+ elsif renum.values.include? v
297
+ val.gsub!(v,renum.values[v])
298
+ end
299
+ end
300
+ renum.add_value(name,val)
301
+ end
302
+ [renum,line_counter]
303
+ rescue RuntimeError => e
304
+ raise "input line #{line_number}: #{e}"
305
+ end
306
+
237
307
  def parse_operation(line_number,string)
308
+ string = string.gsub(";"," ") # strip wrong characters from the parser
238
309
  a = string.split("\n")
239
310
  line = a.shift
240
311
  flags = line.split(" /")
@@ -262,11 +333,17 @@ module Rbind
262
333
  flags = normalize_flags(line_number,flags,:S,:O)
263
334
  return_type = if return_type_name && !return_type_name.empty?
264
335
  t = find_type(owner,return_type_name)
265
- if !t.ptr? && flags.include?(:O)
266
- t.to_ref
267
- else
268
- t
269
- end
336
+ if flags.include?(:O)
337
+ if t.ptr?
338
+ t
339
+ else
340
+ t.to_ref # the opencv parser encodes references as flags
341
+ end
342
+ elsif t.basic_type? && t.name != "c_string"
343
+ t
344
+ else
345
+ t.to_const
346
+ end
270
347
  end
271
348
  line_counter = 1
272
349
  args = a.map do |line|
@@ -303,6 +380,8 @@ module Rbind
303
380
  parse_class(line_number,block)
304
381
  elsif first == "struct"
305
382
  parse_struct(line_number,block)
383
+ elsif first == "enum"
384
+ parse_enum(line_number,block)
306
385
  else
307
386
  parse_operation(line_number,block)
308
387
  end
@@ -187,7 +187,7 @@ module Rbind
187
187
  def wrap_parameters
188
188
  cparameters.map do |arg|
189
189
  next if arg.type.basic_type?
190
- "#{arg.type.to_single_ptr.signature} #{arg.name}_ = fromC(#{arg.name});\n\t"
190
+ "#{arg.type.to_single_ptr.signature} #{arg.name}_ = fromC(#{arg.name},#{arg.parse_ownership?});\n\t"
191
191
  end.compact.join("")
192
192
  end
193
193
 
@@ -208,15 +208,24 @@ module Rbind
208
208
  end
209
209
  end
210
210
  elsif __getobj__.is_a?(RCastOperation)
211
- param = if paras.empty?
212
- "rbind_obj_"
213
- else
214
- paras
215
- end
216
- str = "#{return_type} *__rbind_temp_ = dynamic_cast<#{return_type}*>(#{param});\n"
217
- str += "\tif(!__rbind_temp_)\n"
218
- str += "\t\t throw std::runtime_error(\"Typecast failed, incompatible types\");\n"
219
- str + "\treturn toC(__rbind_temp_,false);"
211
+ param1,param2,param3 = if parameters.size == 1
212
+ ["rbind_obj_",paras,"rbind_obj"]
213
+ else
214
+ a = paras.split(",")
215
+ a << parameters.first.name
216
+ a
217
+ end
218
+ str = "#{return_type} *__rbind_temp_ = dynamic_cast<#{return_type}*>(#{param1});\n"
219
+ str += "\tif(!__rbind_temp_)\n"
220
+ str += "\t\t throw std::runtime_error(\"Typecast failed, incompatible types\");\n"
221
+ str += "\tif(#{param2})\n"
222
+ str += "\t{\n"
223
+ str += "\t\tif(!#{param3}->bowner)\n"
224
+ str += "\t\t throw std::runtime_error(\"Cannot pass ownership. Object is owned by someone else. \");\n"
225
+ str += "\t\telse\n"
226
+ str += "\t\t #{param3}->bowner = false;\n"
227
+ str += "\t}\n"
228
+ str + "\treturn toC(__rbind_temp_,#{param2});"
220
229
  else
221
230
  fct = if !constructor? && (return_type.name != "void" || return_type.ptr?)
222
231
  # operator+, operator++ etc