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 +5 -5
- data/lib/rbind/core/rbase.rb +1 -1
- data/lib/rbind/core/rcast_operation.rb +1 -0
- data/lib/rbind/core/rclass.rb +41 -32
- data/lib/rbind/core/rgetter.rb +1 -1
- data/lib/rbind/core/rnamespace.rb +44 -10
- data/lib/rbind/core/roperation.rb +6 -0
- data/lib/rbind/core/rparameter.rb +5 -0
- data/lib/rbind/core/rtype_annotation.rb +1 -1
- data/lib/rbind/default_parser.rb +87 -8
- data/lib/rbind/generator_c.rb +19 -10
- data/lib/rbind/generator_extern.rb +3 -1
- data/lib/rbind/generator_ruby.rb +40 -13
- data/lib/rbind/templates/c/type_conversion.cc +9 -3
- data/lib/rbind/templates/c/type_conversion.hpp +2 -2
- data/lib/rbind/tools/hdr_parser.py +167 -64
- data/lib/rbind/types/std_map.rb +1 -2
- data/lib/rbind/types/std_vector.rb +1 -1
- data/manifest.xml +2 -0
- data/rbind.gemspec +4 -4
- metadata +13 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: eea754672174a0aa6ab449d1df8bea30400e7720f5a0cd701b74bd01d377f60b
|
4
|
+
data.tar.gz: d771496b0cea68ecc142775ff45a4f41397f4f40b114c6748aea8dc67c9118c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4813c2cb91f792c17587adb578d367fe1998f66d8cafea9290e19f3b6d146786b3d1acaebd10f47cb6fd30aaa26764bfa9c33fd8eeed1b95cd80d0da5cc23660
|
7
|
+
data.tar.gz: 1182a9bcf4d35623d50eb866be4fdc48a2ada495d1e1f7e54bc5a61e45341ca89f1ea70b9e0b80110e36d8dfba93cf3b11565b4df829a2033569c75160fb4fa5
|
data/lib/rbind/core/rbase.rb
CHANGED
@@ -123,7 +123,7 @@ module Rbind
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def owner=(obj)
|
126
|
-
raise ArgumentError,"Cannot
|
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
|
data/lib/rbind/core/rclass.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/rbind/core/rgetter.rb
CHANGED
@@ -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
|
-
|
141
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/rbind/default_parser.rb
CHANGED
@@ -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 ([
|
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(",")
|
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
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
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
|
data/lib/rbind/generator_c.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
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
|