rbind 0.0.27 → 0.0.28
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 +4 -4
- data/lib/rbind/core/rbase.rb +1 -1
- data/lib/rbind/core/rcast_operation.rb +1 -0
- data/lib/rbind/core/rclass.rb +37 -30
- data/lib/rbind/core/rgetter.rb +1 -1
- data/lib/rbind/core/rnamespace.rb +26 -7
- 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 +35 -6
- data/lib/rbind/generator_c.rb +19 -10
- data/lib/rbind/generator_ruby.rb +20 -8
- 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 +52 -26
- 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 +3 -3
- metadata +4 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e930dbda0aa8e1f1acf8758c78fad9324c0019bd
|
4
|
+
data.tar.gz: 62cf7fb25736383555dad7621b1df2fa0ddb5542
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b75baa4b7012be3076556b6980addc786630124005f2ff72e258cca0f0aa1e6a04e5623214c2723e159bbef661a0cced3f6b1b7778b0afd98d2794c996c24cc
|
7
|
+
data.tar.gz: 10d0e92af7049191962ea3c3197ffb08eec3f1eb09f88febe61993e78cf054da5f45d4e206071303878f6287b6542b6a62411f1e4fdd3b9f65e547a8c58cb9e8
|
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 o.base_class == self
|
112
|
+
next true if o.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)
|
@@ -220,6 +226,7 @@ module Rbind
|
|
220
226
|
raise ArgumentError,"class #{klass.full_name} cannot be parent of its self"
|
221
227
|
end
|
222
228
|
@parent_classes[klass.name] = ParentClass.new(klass,accessor)
|
229
|
+
raise "Cannot use namespace #{klass.full_name} as parent class for #{self.full_name}" unless(klass.respond_to?(:child?))
|
223
230
|
klass.add_child(self,accessor) unless klass.child?(self)
|
224
231
|
self
|
225
232
|
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,
|
@@ -260,12 +260,12 @@ module Rbind
|
|
260
260
|
op.alias = if !other
|
261
261
|
op.alias
|
262
262
|
elsif op.alias
|
263
|
-
name = "#{op.alias}#{@operations[op.name].size+1}"
|
263
|
+
name = "#{op.alias}__#{@operations[op.name].size+1}"
|
264
264
|
::Rbind.log.debug "add_operation: name clash: aliasing #{op.alias} --> #{name}"
|
265
265
|
name
|
266
266
|
else
|
267
267
|
op.auto_alias = true
|
268
|
-
name = "#{op.name}#{@operations[op.name].size+1}"
|
268
|
+
name = "#{op.name}__#{@operations[op.name].size+1}"
|
269
269
|
::Rbind.log.debug "add_operation: name clash: #{op.name} --> #{name}"
|
270
270
|
name
|
271
271
|
end
|
@@ -292,6 +292,11 @@ module Rbind
|
|
292
292
|
current_type
|
293
293
|
end
|
294
294
|
|
295
|
+
def add_const_val(name,value)
|
296
|
+
c = RParameter.new(name,type("const int"),value)
|
297
|
+
add_const(c)
|
298
|
+
end
|
299
|
+
|
295
300
|
def add_const(const)
|
296
301
|
const.const!
|
297
302
|
if(c = const(const.full_name,false,false))
|
@@ -415,10 +420,23 @@ module Rbind
|
|
415
420
|
# under the given name
|
416
421
|
t ||= if search_owner && name =~ /([:\w]*)<(.*)>$/
|
417
422
|
t = type($1,false) if $1 && !$1.empty?
|
418
|
-
|
423
|
+
t2 = if $2 && !$2.empty?
|
424
|
+
t2 = $2.split(',')
|
425
|
+
bok = true
|
426
|
+
t2 = t2.map do |t3|
|
427
|
+
t3 = type(t3,false)
|
428
|
+
bok = false unless t3
|
429
|
+
t3
|
430
|
+
end
|
431
|
+
if bok
|
432
|
+
t2
|
433
|
+
else
|
434
|
+
nil
|
435
|
+
end
|
436
|
+
end
|
419
437
|
# template is known to this library
|
420
438
|
if t && t2
|
421
|
-
|
439
|
+
name = "#{t.name}<#{t2.map{|t|t.full_name}.join(",")}>"
|
422
440
|
t3 ||= t.owner.type(name,false,false)
|
423
441
|
t3 ||= begin
|
424
442
|
if !t.template?
|
@@ -439,7 +457,8 @@ module Rbind
|
|
439
457
|
# generic template is unknown
|
440
458
|
# check if specialised template is known
|
441
459
|
elsif t2 && $1 && !$1.empty?
|
442
|
-
|
460
|
+
real_name = t2.map{|v|v.full_name}.join(",");
|
461
|
+
real_name = "#{$1}<#{real_name}>".gsub(">>","> >")
|
443
462
|
type(real_name,false) if(real_name != name) # prevent stack level too deep
|
444
463
|
else
|
445
464
|
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
@@ -138,7 +138,25 @@ module Rbind
|
|
138
138
|
parent_classes = $2
|
139
139
|
flags = $3
|
140
140
|
parent_classes = if parent_classes
|
141
|
-
parent_classes.gsub(" ","").split(",")
|
141
|
+
classes = parent_classes.gsub(" ","").split(",")
|
142
|
+
# join templates
|
143
|
+
classes.each_with_index do |val,i|
|
144
|
+
next unless val
|
145
|
+
if val.include?("<")
|
146
|
+
val = [val]
|
147
|
+
(i+1).upto(classes.size-1) do |i2|
|
148
|
+
val2 = classes[i2]
|
149
|
+
val << val2
|
150
|
+
classes[i2] = nil
|
151
|
+
if val2.include?(">")
|
152
|
+
break
|
153
|
+
end
|
154
|
+
end
|
155
|
+
classes[i] = val.join(",")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
classes.compact!
|
159
|
+
classes.map do |name|
|
142
160
|
#TODO this should also call the user callback
|
143
161
|
t = type(RBase.normalize(name),false)
|
144
162
|
# remove namespace and try again
|
@@ -155,6 +173,11 @@ module Rbind
|
|
155
173
|
end
|
156
174
|
# auto add parent class
|
157
175
|
t ||= begin
|
176
|
+
# TODO fix error in parser
|
177
|
+
# the parser always adds the current namespace
|
178
|
+
# class Blas : public ::cv::Test
|
179
|
+
# --> cv::::cv::Test
|
180
|
+
name = name.gsub(/^.*::::/,"")
|
158
181
|
t = add_type(RClass.new(RBase.normalize(name)))
|
159
182
|
t.extern_package_name = @extern_package_name
|
160
183
|
t
|
@@ -262,11 +285,17 @@ module Rbind
|
|
262
285
|
flags = normalize_flags(line_number,flags,:S,:O)
|
263
286
|
return_type = if return_type_name && !return_type_name.empty?
|
264
287
|
t = find_type(owner,return_type_name)
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
288
|
+
if flags.include?(:O)
|
289
|
+
if t.ptr?
|
290
|
+
t
|
291
|
+
else
|
292
|
+
t.to_ref # the opencv parser encodes references as flags
|
293
|
+
end
|
294
|
+
elsif t.basic_type? && t.name != "c_string"
|
295
|
+
t
|
296
|
+
else
|
297
|
+
t.to_const
|
298
|
+
end
|
270
299
|
end
|
271
300
|
line_counter = 1
|
272
301
|
args = a.map do |line|
|
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
|
data/lib/rbind/generator_ruby.rb
CHANGED
@@ -15,7 +15,7 @@ module Rbind
|
|
15
15
|
end
|
16
16
|
self.ruby_default_value_map ||= {"true" => "true","TRUE" => "true", "false" => "false","FALSE" => "false"}
|
17
17
|
self.ffi_type_map ||= {"char *" => "string","unsigned char" => "uchar" ,"const char *" => "string","uint8_t" => "uint8",
|
18
|
-
"uint32_t" => "uint32","uint64_t" => "uint64","int8_t" => "int8","int32_t" => "int32","int64_t" => "int64" }
|
18
|
+
"uint16_t" => "uint16","int16_t" => "int16", "uint32_t" => "uint32","uint64_t" => "uint64","int8_t" => "int8","int32_t" => "int32","int64_t" => "int64" }
|
19
19
|
|
20
20
|
|
21
21
|
def self.keyword?(name)
|
@@ -62,6 +62,8 @@ module Rbind
|
|
62
62
|
val = if parameter.type.basic_type? || parameter.type.ptr?
|
63
63
|
if ruby_default_value_map.has_key?(parameter.default_value)
|
64
64
|
ruby_default_value_map[parameter.default_value]
|
65
|
+
elsif parameter.type.is_a? REnum
|
66
|
+
":#{parameter.default_value.split("::").last}"
|
65
67
|
elsif parameter.type.name == "float"
|
66
68
|
parameter.default_value.gsub("f","").gsub(/\.$/,".0").gsub(/^\./,"0.")
|
67
69
|
elsif parameter.type.name == "double"
|
@@ -131,7 +133,12 @@ module Rbind
|
|
131
133
|
# map template classes
|
132
134
|
# std::vector<std::string> -> Std::Vector::Std_String
|
133
135
|
if name =~ /([\w:]*)<(.*)>$/
|
134
|
-
|
136
|
+
name = $1
|
137
|
+
names = $2.split(",")
|
138
|
+
names.map! do |val|
|
139
|
+
normalize_type_name(val,true).gsub("::","_")
|
140
|
+
end
|
141
|
+
return "#{normalize_type_name(name,true)}::#{names.join("_")}"
|
135
142
|
else
|
136
143
|
name
|
137
144
|
end
|
@@ -332,11 +339,10 @@ module Rbind
|
|
332
339
|
op_return_type = klass if klass.kind_of?(REnum)
|
333
340
|
end
|
334
341
|
end
|
335
|
-
|
336
342
|
if op_return_type.basic_type?
|
337
343
|
if op_return_type.ptr?
|
338
344
|
":pointer"
|
339
|
-
|
345
|
+
elsif op.return_type.to_raw.kind_of?(REnum)
|
340
346
|
":#{normalize_enum op_return_type.to_raw.csignature}"
|
341
347
|
else
|
342
348
|
":#{normalize_bt op_return_type.to_raw.csignature}"
|
@@ -344,7 +350,7 @@ module Rbind
|
|
344
350
|
else
|
345
351
|
if op_return_type.extern_package_name
|
346
352
|
normalize_t("::#{op_return_type.extern_package_name}::#{op_return_type.to_raw.full_name}")
|
347
|
-
|
353
|
+
elsif op_return_type.to_raw.kind_of?(REnum)
|
348
354
|
":#{normalize_enum op_return_type.to_raw.full_name}"
|
349
355
|
else
|
350
356
|
normalize_t op_return_type.to_raw.full_name
|
@@ -361,7 +367,7 @@ module Rbind
|
|
361
367
|
if p_type.basic_type?
|
362
368
|
if p_type.ptr? || p.type.ref?
|
363
369
|
":pointer"
|
364
|
-
|
370
|
+
elsif p.type.to_raw.kind_of?(REnum)
|
365
371
|
# Includes enums, which need to be defined accordingly
|
366
372
|
# using ffi:
|
367
373
|
# enum :normalized_name, [:first, 1,
|
@@ -375,7 +381,7 @@ module Rbind
|
|
375
381
|
else
|
376
382
|
if p_type.extern_package_name
|
377
383
|
normalize_t("::#{p_type.extern_package_name}::#{p_type.to_raw.full_name}")
|
378
|
-
|
384
|
+
elsif p_type.to_raw.kind_of?(REnum)
|
379
385
|
":#{normalize_enum p_type.to_raw.full_name}"
|
380
386
|
else
|
381
387
|
normalize_t p_type.to_raw.full_name
|
@@ -383,6 +389,7 @@ module Rbind
|
|
383
389
|
end
|
384
390
|
end
|
385
391
|
fct_name = normalize_m op.cname
|
392
|
+
str += "@blocking = true; "if op.blocking?
|
386
393
|
str += "attach_function :#{fct_name},:#{op.cname},[#{args.join(",")}],#{return_type}\n"
|
387
394
|
str
|
388
395
|
end
|
@@ -675,7 +682,12 @@ module Rbind
|
|
675
682
|
HelperBase.log.warn "#{c.name}: no default value"
|
676
683
|
next
|
677
684
|
else
|
678
|
-
|
685
|
+
val = begin
|
686
|
+
eval(c.default_value)
|
687
|
+
rescue
|
688
|
+
GeneratorRuby::normalize_type_name(c.default_value)
|
689
|
+
end
|
690
|
+
" #{c.name} = #{val}\n"
|
679
691
|
end
|
680
692
|
end.join
|
681
693
|
return str unless @compact_namespace
|
@@ -17,7 +17,7 @@ const <%= cname %>* toC(const <%= full_name %>* ptr, bool owner)
|
|
17
17
|
}
|
18
18
|
|
19
19
|
// converts const <%= cname %> to const <%= full_name %>
|
20
|
-
const <%= full_name %>* fromC(const <%= cname %>* ptr)
|
20
|
+
const <%= full_name %>* fromC(const <%= cname %>* ptr,bool parse_owner)
|
21
21
|
{
|
22
22
|
if(ptr == NULL)
|
23
23
|
throw std::runtime_error("<%= full_name %>: Null Pointer!");
|
@@ -38,14 +38,20 @@ const <%= full_name %>* fromC(const <%= cname %>* ptr)
|
|
38
38
|
// check size
|
39
39
|
if(ptr->size && sizeof(<%= full_name %>) > ptr->size)
|
40
40
|
throw std::runtime_error("wrong object size for <%= full_name %>.");
|
41
|
+
if(parse_owner)
|
42
|
+
throw std::runtime_error("cannot parse ownerhsip for const parameter for <%= full_name %>.");
|
41
43
|
return static_cast<const <%= full_name %>*>(ptr->obj_ptr);
|
42
44
|
}
|
43
45
|
|
44
46
|
// converts <%= cname %>* to <%= full_name %>*
|
45
|
-
<%= full_name %>* fromC(<%= cname %>* ptr)
|
47
|
+
<%= full_name %>* fromC(<%= cname %>* ptr,bool parse_owner)
|
46
48
|
{
|
47
49
|
if(ptr == NULL)
|
48
50
|
return NULL;
|
49
|
-
|
51
|
+
if(parse_owner && !ptr->bowner)
|
52
|
+
throw std::runtime_error("Cannot parse ownership. The given object is already owned by someone else <%= full_name %>.");
|
53
|
+
if(parse_owner)
|
54
|
+
ptr->bowner = false;
|
55
|
+
return const_cast<<%= full_name %>*>(fromC(static_cast<const <%= cname %>*>(ptr),false));
|
50
56
|
}
|
51
57
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// convert functions for <%= full_name %>* to and from <%= cname %>*
|
2
2
|
const <%= cname %>* toC(const <%= full_name %>* ptr, bool owner = true);
|
3
3
|
<%= cname %>* toC(<%= full_name %>* ptr, bool owner = true);
|
4
|
-
const <%= full_name %>* fromC(const <%= cname %>* ptr);
|
5
|
-
<%= full_name %>* fromC(<%= cname %>* ptr);
|
4
|
+
const <%= full_name %>* fromC(const <%= cname %>* ptr,bool parse_ownership=false);
|
5
|
+
<%= full_name %>* fromC(<%= cname %>* ptr,bool parse_ownership=false);
|
6
6
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
|
3
3
|
from __future__ import print_function
|
4
|
-
import os, sys, re, string
|
4
|
+
import os, sys, re, string, io
|
5
5
|
|
6
6
|
# the list only for debugging. The real list, used in the real OpenCV build, is specified in CMakeLists.txt
|
7
7
|
opencv_hdr_list = [
|
@@ -17,7 +17,7 @@ opencv_hdr_list = [
|
|
17
17
|
"../../objdetect/include/opencv2/objdetect.hpp",
|
18
18
|
"../../imgcodecs/include/opencv2/imgcodecs.hpp",
|
19
19
|
"../../videoio/include/opencv2/videoio.hpp",
|
20
|
-
"../../highgui/include/opencv2/highgui.hpp"
|
20
|
+
"../../highgui/include/opencv2/highgui.hpp",
|
21
21
|
]
|
22
22
|
|
23
23
|
"""
|
@@ -31,13 +31,17 @@ where the list of modifiers is yet another nested list of strings
|
|
31
31
|
|
32
32
|
class CppHeaderParser(object):
|
33
33
|
|
34
|
-
def __init__(self):
|
34
|
+
def __init__(self, generate_umat_decls=False):
|
35
|
+
self._generate_umat_decls = generate_umat_decls
|
36
|
+
|
35
37
|
self.BLOCK_TYPE = 0
|
36
38
|
self.BLOCK_NAME = 1
|
37
39
|
self.PROCESS_FLAG = 2
|
38
40
|
self.PUBLIC_SECTION = 3
|
39
41
|
self.CLASS_DECL = 4
|
40
42
|
|
43
|
+
self.namespaces = set()
|
44
|
+
|
41
45
|
def batch_replace(self, s, pairs):
|
42
46
|
for before, after in pairs:
|
43
47
|
s = s.replace(before, after)
|
@@ -366,7 +370,7 @@ class CppHeaderParser(object):
|
|
366
370
|
print(decl_str)
|
367
371
|
return decl
|
368
372
|
|
369
|
-
def parse_func_decl(self, decl_str):
|
373
|
+
def parse_func_decl(self, decl_str, use_umat=False):
|
370
374
|
"""
|
371
375
|
Parses the function or method declaration in the form:
|
372
376
|
[([CV_EXPORTS] <rettype>) | CVAPI(rettype)]
|
@@ -443,6 +447,12 @@ class CppHeaderParser(object):
|
|
443
447
|
|
444
448
|
rettype, funcname, modlist, argno = self.parse_arg(decl_start, -1)
|
445
449
|
|
450
|
+
# determine original return type, hack for return types with underscore
|
451
|
+
original_type = None
|
452
|
+
i = decl_start.rfind(funcname)
|
453
|
+
if i > 0:
|
454
|
+
original_type = decl_start[:i].replace("&", "").replace("const", "").strip()
|
455
|
+
|
446
456
|
if argno >= 0:
|
447
457
|
classname = top[1]
|
448
458
|
if rettype == classname or rettype == "~" + classname:
|
@@ -529,41 +539,45 @@ class CppHeaderParser(object):
|
|
529
539
|
a = a[:eqpos].strip()
|
530
540
|
arg_type, arg_name, modlist, argno = self.parse_arg(a, argno)
|
531
541
|
if self.wrap_mode:
|
542
|
+
mat = "UMat" if use_umat else "Mat"
|
543
|
+
|
544
|
+
# TODO: Vectors should contain UMat, but this is not very easy to support and not very needed
|
545
|
+
vector_mat = "vector_{}".format("Mat")
|
546
|
+
vector_mat_template = "vector<{}>".format("Mat")
|
547
|
+
|
532
548
|
if arg_type == "InputArray":
|
533
|
-
arg_type =
|
549
|
+
arg_type = mat
|
534
550
|
elif arg_type == "InputOutputArray":
|
535
|
-
arg_type =
|
551
|
+
arg_type = mat
|
536
552
|
modlist.append("/IO")
|
537
553
|
elif arg_type == "OutputArray":
|
538
|
-
arg_type =
|
554
|
+
arg_type = mat
|
539
555
|
modlist.append("/O")
|
540
556
|
elif arg_type == "InputArrayOfArrays":
|
541
|
-
arg_type =
|
557
|
+
arg_type = vector_mat
|
542
558
|
elif arg_type == "InputOutputArrayOfArrays":
|
543
|
-
arg_type =
|
559
|
+
arg_type = vector_mat
|
544
560
|
modlist.append("/IO")
|
545
561
|
elif arg_type == "OutputArrayOfArrays":
|
546
|
-
arg_type =
|
562
|
+
arg_type = vector_mat
|
547
563
|
modlist.append("/O")
|
548
|
-
defval = self.batch_replace(defval, [("InputArrayOfArrays",
|
549
|
-
("InputOutputArrayOfArrays",
|
550
|
-
("OutputArrayOfArrays",
|
551
|
-
("InputArray",
|
552
|
-
("InputOutputArray",
|
553
|
-
("OutputArray",
|
564
|
+
defval = self.batch_replace(defval, [("InputArrayOfArrays", vector_mat_template),
|
565
|
+
("InputOutputArrayOfArrays", vector_mat_template),
|
566
|
+
("OutputArrayOfArrays", vector_mat_template),
|
567
|
+
("InputArray", mat),
|
568
|
+
("InputOutputArray", mat),
|
569
|
+
("OutputArray", mat),
|
554
570
|
("noArray", arg_type)]).strip()
|
555
571
|
args.append([arg_type, arg_name, defval, modlist])
|
556
572
|
npos = arg_start-1
|
557
573
|
|
558
|
-
npos = decl_str.replace(" ", "").find("=0", npos)
|
559
|
-
if npos >= 0:
|
560
|
-
# skip pure virtual functions
|
561
|
-
return []
|
562
|
-
|
563
574
|
if static_method:
|
564
575
|
func_modlist.append("/S")
|
565
576
|
|
566
|
-
|
577
|
+
if original_type is None:
|
578
|
+
return [funcname, rettype, func_modlist, args]
|
579
|
+
else:
|
580
|
+
return [funcname, rettype, func_modlist, args, original_type]
|
567
581
|
|
568
582
|
def get_dotted_name(self, name):
|
569
583
|
"""
|
@@ -598,7 +612,7 @@ class CppHeaderParser(object):
|
|
598
612
|
n = "cv.Algorithm"
|
599
613
|
return n
|
600
614
|
|
601
|
-
def parse_stmt(self, stmt, end_token):
|
615
|
+
def parse_stmt(self, stmt, end_token, use_umat=False):
|
602
616
|
"""
|
603
617
|
parses the statement (ending with ';' or '}') or a block head (ending with '{')
|
604
618
|
|
@@ -690,7 +704,7 @@ class CppHeaderParser(object):
|
|
690
704
|
# since we filtered off the other places where '(' can normally occur:
|
691
705
|
# - code blocks
|
692
706
|
# - function pointer typedef's
|
693
|
-
decl = self.parse_func_decl(stmt)
|
707
|
+
decl = self.parse_func_decl(stmt, use_umat=use_umat)
|
694
708
|
# we return parse_flag == False to prevent the parser to look inside function/method bodies
|
695
709
|
# (except for tracking the nested blocks)
|
696
710
|
return stmt_type, "", False, decl
|
@@ -737,7 +751,7 @@ class CppHeaderParser(object):
|
|
737
751
|
"""
|
738
752
|
self.hname = hname
|
739
753
|
decls = []
|
740
|
-
f = open(hname,
|
754
|
+
f = io.open(hname, 'rt', encoding='utf-8')
|
741
755
|
linelist = list(f.readlines())
|
742
756
|
f.close()
|
743
757
|
|
@@ -833,6 +847,18 @@ class CppHeaderParser(object):
|
|
833
847
|
decls.append(d)
|
834
848
|
else:
|
835
849
|
decls.append(decl)
|
850
|
+
|
851
|
+
if self._generate_umat_decls:
|
852
|
+
# If function takes as one of arguments Mat or vector<Mat> - we want to create the
|
853
|
+
# same declaration working with UMat (this is important for T-Api access)
|
854
|
+
args = decl[3]
|
855
|
+
has_mat = len(list(filter(lambda x: x[0] in {"Mat", "vector_Mat"}, args))) > 0
|
856
|
+
if has_mat:
|
857
|
+
_, _, _, umat_decl = self.parse_stmt(stmt, token, use_umat=True)
|
858
|
+
decls.append(umat_decl)
|
859
|
+
if stmt_type == "namespace":
|
860
|
+
chunks = [block[1] for block in self.block_stack if block[0] == 'namespace'] + [name]
|
861
|
+
self.namespaces.add('.'.join(chunks))
|
836
862
|
else:
|
837
863
|
stmt_type, name, parse_flag = "block", "", False
|
838
864
|
|
@@ -869,7 +895,7 @@ class CppHeaderParser(object):
|
|
869
895
|
print()
|
870
896
|
|
871
897
|
if __name__ == '__main__':
|
872
|
-
parser = CppHeaderParser()
|
898
|
+
parser = CppHeaderParser(generate_umat_decls=False)
|
873
899
|
decls = []
|
874
900
|
# for hname in opencv_hdr_list:
|
875
901
|
# decls += parser.parse(hname)
|
data/lib/rbind/types/std_map.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Rbind
|
2
2
|
class StdMap < RTemplateClass
|
3
|
-
def specialize(klass
|
3
|
+
def specialize(klass,parameters)
|
4
4
|
if parameters.size < 2
|
5
5
|
raise ArgumentError,"StdMap does require at least two template parameters. Got: #{parameters}}"
|
6
6
|
end
|
@@ -17,7 +17,6 @@ module Rbind
|
|
17
17
|
|
18
18
|
klass.add_operation ROperation.new("size",type("size_t"))
|
19
19
|
klass.add_operation ROperation.new("clear",type("void"))
|
20
|
-
klass.add_operation ROperation.new("capacity",type("size_t"))
|
21
20
|
klass.add_operation ROperation.new("empty",type("bool"))
|
22
21
|
klass.add_operation ROperation.new("operator[]",map_value_type, RParameter.new("key_type", map_key_type))
|
23
22
|
klass.add_operation ROperation.new("at",map_value_type, RParameter.new("key_type",map_key_type))
|
data/manifest.xml
CHANGED
data/rbind.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rbind'
|
3
|
-
s.version = '0.0.
|
4
|
-
s.date = '
|
3
|
+
s.version = '0.0.28'
|
4
|
+
s.date = '2018-07-10'
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = ['Alexander Duda']
|
7
|
-
s.email = ['Alexander.Duda@
|
7
|
+
s.email = ['Alexander.Duda@me.com']
|
8
8
|
s.homepage = 'http://github.com/D-Alex/rbind'
|
9
9
|
s.summary = 'Library for genereating automated ffi-bindings for c/c++ libraries'
|
10
10
|
s.description = 'Rbind is developed to automatically generate ruby bindings for OpenCV '\
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbind
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Duda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -28,7 +28,7 @@ description: Rbind is developed to automatically generate ruby bindings for Open
|
|
28
28
|
but is not tight to this library.This gem is still under heavy development and the
|
29
29
|
API might change in the future.
|
30
30
|
email:
|
31
|
-
- Alexander.Duda@
|
31
|
+
- Alexander.Duda@me.com
|
32
32
|
executables: []
|
33
33
|
extensions: []
|
34
34
|
extra_rdoc_files: []
|
@@ -123,9 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
version: 1.3.6
|
124
124
|
requirements: []
|
125
125
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.2.
|
126
|
+
rubygems_version: 2.5.2.3
|
127
127
|
signing_key:
|
128
128
|
specification_version: 4
|
129
129
|
summary: Library for genereating automated ffi-bindings for c/c++ libraries
|
130
130
|
test_files: []
|
131
|
-
has_rdoc:
|