rbind 0.0.7 → 0.0.8
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.
- data/lib/rbind/core/rbase.rb +1 -0
- data/lib/rbind/core/rnamespace.rb +12 -0
- data/lib/rbind/core/roperation.rb +1 -0
- data/lib/rbind/default_parser.rb +2 -1
- data/lib/rbind/generator_ruby.rb +103 -28
- data/lib/rbind/templates/ruby/roverloaded_method.rb +6 -0
- data/lib/rbind/templates/ruby/roverloaded_method_call.rb +19 -0
- data/lib/rbind/templates/ruby/roverloaded_static_method.rb +6 -0
- data/rbind.gemspec +2 -2
- metadata +30 -19
data/lib/rbind/core/rbase.rb
CHANGED
@@ -11,10 +11,12 @@ module Rbind
|
|
11
11
|
attr_reader :consts
|
12
12
|
attr_reader :used_namespaces
|
13
13
|
attr_accessor :root
|
14
|
+
attr_accessor :types_alias
|
14
15
|
|
15
16
|
def initialize(name,*flags)
|
16
17
|
@consts = Hash.new
|
17
18
|
@types = Hash.new
|
19
|
+
@types_alias = Hash.new
|
18
20
|
@operations = Hash.new{|hash,key| hash[key] = Array.new}
|
19
21
|
@operation_alias = Hash.new{|hash,key| hash[key] = Array.new}
|
20
22
|
@used_namespaces = Hash.new
|
@@ -177,10 +179,12 @@ module Rbind
|
|
177
179
|
::Rbind.log.debug "name clash: aliasing #{op.alias} --> #{name}"
|
178
180
|
name
|
179
181
|
else
|
182
|
+
op.auto_alias = true
|
180
183
|
name = "#{op.name}#{@operations[op.name].size+1}"
|
181
184
|
::Rbind.log.debug "name clash: #{op.name} --> #{name}"
|
182
185
|
name
|
183
186
|
end
|
187
|
+
op.index = @operations[op.name].size
|
184
188
|
@operations[op.name] << op
|
185
189
|
@operation_alias[op.alias] << op if op.alias
|
186
190
|
op
|
@@ -247,6 +251,12 @@ module Rbind
|
|
247
251
|
t.add_type(type)
|
248
252
|
else
|
249
253
|
type.owner = self
|
254
|
+
if type.alias
|
255
|
+
if type(type.alias,false,false)
|
256
|
+
raise ArgumentError,"A type with the name alias #{type.alias} already exists"
|
257
|
+
end
|
258
|
+
@types_alias[type.alias] = type
|
259
|
+
end
|
250
260
|
@types[type.name] = type
|
251
261
|
end
|
252
262
|
type
|
@@ -262,6 +272,8 @@ module Rbind
|
|
262
272
|
name = name.chomp(" ")
|
263
273
|
t = if @types.has_key?(name)
|
264
274
|
@types[name]
|
275
|
+
elsif @types_alias.has_key?(name)
|
276
|
+
@types_alias[name]
|
265
277
|
else
|
266
278
|
if !!(ns = RBase.namespace(name))
|
267
279
|
ns = ns.split("::")
|
data/lib/rbind/default_parser.rb
CHANGED
@@ -23,7 +23,8 @@ module Rbind
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def normalize_default_value(value)
|
26
|
-
|
26
|
+
value = value.gsub(/std::vector</,"vector<")
|
27
|
+
val = value.gsub(/(.?)vector<(.*)>/,'\1vector_\2')
|
27
28
|
if value != val
|
28
29
|
normalize_default_value(val)
|
29
30
|
else
|
data/lib/rbind/generator_ruby.rb
CHANGED
@@ -4,6 +4,9 @@ require 'erb'
|
|
4
4
|
|
5
5
|
module Rbind
|
6
6
|
class GeneratorRuby
|
7
|
+
@@ruby_default_value_map ||= {"true" => "true","TRUE" => "true", "false" => "false","FALSE" => "false"}
|
8
|
+
@@ffi_type_map ||= {"char *" => "string","unsigned char" => "uchar" ,"const char *" => "string" }
|
9
|
+
|
7
10
|
def self.keyword?(name)
|
8
11
|
%w{__FILE__ __LINE__ alias and begin BEGIN break case class def defined? do else elsif end END ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield}.include? name
|
9
12
|
end
|
@@ -26,10 +29,12 @@ module Rbind
|
|
26
29
|
def self.normalize_default_value(parameter)
|
27
30
|
return nil unless parameter.default_value
|
28
31
|
val = if parameter.type.basic_type? || parameter.type.ptr?
|
29
|
-
if parameter.
|
32
|
+
if @@ruby_default_value_map.has_key?(parameter.default_value)
|
33
|
+
@@ruby_default_value_map[parameter.default_value]
|
34
|
+
elsif parameter.type.name == "float"
|
30
35
|
parameter.default_value.gsub("f","")
|
31
36
|
elsif parameter.type.name == "double"
|
32
|
-
parameter.default_value.gsub(/\.$/,".0")
|
37
|
+
parameter.default_value.gsub(/\.$/,".0").gsub(/^\./,"0.")
|
33
38
|
else
|
34
39
|
normalize_type_name(parameter.default_value)
|
35
40
|
end
|
@@ -72,6 +77,10 @@ module Rbind
|
|
72
77
|
|
73
78
|
|
74
79
|
def self.normalize_type_name(name)
|
80
|
+
if name =~ /^u?int\d*$/ || name =~ /^u?int\d+_t$/
|
81
|
+
return "Fixnum"
|
82
|
+
end
|
83
|
+
name = name.gsub(/^_/,"")
|
75
84
|
names = name.split("::").map do |n|
|
76
85
|
n.gsub(/^(\w)(.*)/) do
|
77
86
|
$1.upcase+$2
|
@@ -88,9 +97,8 @@ module Rbind
|
|
88
97
|
end.join("")
|
89
98
|
end
|
90
99
|
|
91
|
-
def self.
|
92
|
-
|
93
|
-
n = @@basic_type_map[name]
|
100
|
+
def self.normalize_basic_type_name_ffi(name)
|
101
|
+
n = @@ffi_type_map[name]
|
94
102
|
n ||= name
|
95
103
|
if n =~ /\*/
|
96
104
|
"pointer"
|
@@ -179,7 +187,7 @@ module Rbind
|
|
179
187
|
end
|
180
188
|
|
181
189
|
def normalize_bt(name)
|
182
|
-
GeneratorRuby.
|
190
|
+
GeneratorRuby.normalize_basic_type_name_ffi name
|
183
191
|
end
|
184
192
|
|
185
193
|
def normalize_m(name)
|
@@ -248,6 +256,26 @@ module Rbind
|
|
248
256
|
|
249
257
|
class RTypeHelper < HelperBase
|
250
258
|
class OperationHelper < SimpleDelegator
|
259
|
+
def min_number_of_parameters
|
260
|
+
count = 0
|
261
|
+
parameters.each do |p|
|
262
|
+
break if p.default_value
|
263
|
+
count +=1
|
264
|
+
end
|
265
|
+
count
|
266
|
+
end
|
267
|
+
|
268
|
+
def signature_default_values
|
269
|
+
str = parameters.map do |p|
|
270
|
+
if p.default_value
|
271
|
+
GeneratorRuby.normalize_default_value p
|
272
|
+
else
|
273
|
+
"nil"
|
274
|
+
end
|
275
|
+
end.join(", ")
|
276
|
+
"[#{str}]"
|
277
|
+
end
|
278
|
+
|
251
279
|
def wrap_parameters_signature
|
252
280
|
parameters.map do |p|
|
253
281
|
n = GeneratorRuby.normalize_arg_name p.name
|
@@ -257,11 +285,6 @@ module Rbind
|
|
257
285
|
n
|
258
286
|
end
|
259
287
|
end.join(", ")
|
260
|
-
rescue RuntimeError
|
261
|
-
::Rbind.log.warn "ignoring all default parameter values for #{full_name} because of missing definitions."
|
262
|
-
parameters.map do |p|
|
263
|
-
GeneratorRuby.normalize_arg_name p.name
|
264
|
-
end.join(", ")
|
265
288
|
end
|
266
289
|
|
267
290
|
def wrap_parameters_call
|
@@ -282,7 +305,12 @@ module Rbind
|
|
282
305
|
"#{name}="
|
283
306
|
end
|
284
307
|
else
|
285
|
-
|
308
|
+
name = if auto_alias
|
309
|
+
__getobj__.name
|
310
|
+
else
|
311
|
+
__getobj__.alias || __getobj__.name
|
312
|
+
end
|
313
|
+
GeneratorRuby.normalize_method_name(name)
|
286
314
|
end
|
287
315
|
end
|
288
316
|
|
@@ -295,12 +323,39 @@ module Rbind
|
|
295
323
|
end
|
296
324
|
end
|
297
325
|
|
326
|
+
class OverloadedOperationHelper < HelperBase
|
327
|
+
def initialize(root)
|
328
|
+
raise "expect an array of methods but got #{root}" if root.size < 1
|
329
|
+
super(GeneratorRuby.normalize_method_name(root.first.alias || root.first.name),root)
|
330
|
+
@overload_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","roverloaded_method_call.rb")).read,nil,"-")
|
331
|
+
end
|
332
|
+
|
333
|
+
def add_methods
|
334
|
+
str = @root.map do |method|
|
335
|
+
next if method.ignore?
|
336
|
+
raise "Cannot overload attributes" if method.attribute?
|
337
|
+
op = if method.is_a? OperationHelper
|
338
|
+
method
|
339
|
+
else
|
340
|
+
OperationHelper.new(method)
|
341
|
+
end
|
342
|
+
@overload_wrapper.result(op.binding)
|
343
|
+
end.join("\n")
|
344
|
+
end
|
345
|
+
|
346
|
+
def binding
|
347
|
+
Kernel.binding
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
298
351
|
def initialize(name, root,compact_namespace = false)
|
299
352
|
@type_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","rtype.rb")).read,nil,"-")
|
300
|
-
@type_constructor_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","rtype_constructor.rb")).read,nil,"-")
|
301
353
|
@namespace_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","rnamespace.rb")).read,nil,"-")
|
302
354
|
@static_method_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","rstatic_method.rb")).read)
|
303
355
|
@method_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","rmethod.rb")).read,nil,'-')
|
356
|
+
@overloaded_method_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","roverloaded_method.rb")).read,nil,"-")
|
357
|
+
@overloaded_static_method_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","roverloaded_static_method.rb")).read,nil,"-")
|
358
|
+
@overloaded_method_call_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","ruby","roverloaded_method_call.rb")).read,nil,"-")
|
304
359
|
@compact_namespace = compact_namespace
|
305
360
|
super(name,root)
|
306
361
|
end
|
@@ -319,10 +374,10 @@ module Rbind
|
|
319
374
|
|
320
375
|
def add_specializing(root = @root)
|
321
376
|
str = if @root.respond_to?(:specialize_ruby)
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
377
|
+
root.specialize_ruby
|
378
|
+
else
|
379
|
+
""
|
380
|
+
end
|
326
381
|
root.each_type(false) do |t|
|
327
382
|
next if t.basic_type? && !t.is_a?(RNamespace)
|
328
383
|
str += add_specialize(t) if name == GeneratorRuby.normalize_type_name(t.full_name)
|
@@ -333,11 +388,10 @@ module Rbind
|
|
333
388
|
def add_constructor
|
334
389
|
raise "there is no constructor for namespaces!" if self.is_a?(RNamespace)
|
335
390
|
ops = Array(@root.operation(@root.name,false))
|
336
|
-
return until ops
|
337
391
|
ops.map do |c|
|
338
392
|
next if c.ignore?
|
339
393
|
ch = OperationHelper.new(c)
|
340
|
-
@
|
394
|
+
@overloaded_method_call_wrapper.result(ch.binding)
|
341
395
|
end.join("\n")
|
342
396
|
end
|
343
397
|
|
@@ -356,18 +410,39 @@ module Rbind
|
|
356
410
|
end
|
357
411
|
|
358
412
|
def add_methods(root=@root)
|
413
|
+
# sort all method according their target name
|
414
|
+
ops = Hash.new do |h,k|
|
415
|
+
h[k] = Array.new
|
416
|
+
end
|
417
|
+
root.each_operation do |o|
|
418
|
+
next if o.constructor? || o.ignore?
|
419
|
+
op = OperationHelper.new(o)
|
420
|
+
if op.instance_method?
|
421
|
+
ops["rbind_instance_#{op.name}"] << op
|
422
|
+
else
|
423
|
+
ops["rbind_static_#{op.name}"] << op
|
424
|
+
end
|
425
|
+
end
|
426
|
+
# render method
|
359
427
|
str = ""
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
428
|
+
ops.each_value do |o|
|
429
|
+
if o.size == 1
|
430
|
+
op = o.first
|
431
|
+
str += if op.instance_method?
|
432
|
+
@method_wrapper.result(op.binding)
|
433
|
+
else
|
434
|
+
@static_method_wrapper.result(op.binding)
|
435
|
+
end
|
436
|
+
else
|
437
|
+
helper = OverloadedOperationHelper.new(o)
|
438
|
+
str += if o.first.instance_method?
|
439
|
+
@overloaded_method_wrapper.result(helper.binding)
|
440
|
+
else
|
441
|
+
@overloaded_static_method_wrapper.result(helper.binding)
|
442
|
+
end
|
443
|
+
end
|
368
444
|
end
|
369
445
|
return str unless @compact_namespace
|
370
|
-
|
371
446
|
root.each_type(false) do |t|
|
372
447
|
next if t.basic_type? && !t.is_a?(RNamespace)
|
373
448
|
str += add_methods(t) if name == GeneratorRuby.normalize_type_name(t.full_name)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# wrapper for <%= signature %>
|
2
|
+
@@<%=cname%>_defaults<%= index %> ||= <%= signature_default_values %>
|
3
|
+
if(args.size >= <%= min_number_of_parameters %> && args.size <= <%= parameters.size %>)
|
4
|
+
args.size.upto(<%= parameters.size-1%>) do |i|
|
5
|
+
args[i] = @@<%=cname%>_defaults<%=index%>[i]
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
<%- if !return_type || return_type.basic_type? || operator? -%>
|
9
|
+
return Rbind::<%= cname %>(*args)
|
10
|
+
<%- else -%>
|
11
|
+
result = Rbind::<%= cname %>(*args)
|
12
|
+
# store owner insight the pointer to not get garbage collected
|
13
|
+
result.instance_variable_get(:@__obj_ptr__).instance_variable_set(:@__owner__,self) if !result.__owner__?
|
14
|
+
return result
|
15
|
+
<%- end -%>
|
16
|
+
rescue TypeError => e
|
17
|
+
@error = e
|
18
|
+
end
|
19
|
+
end
|
data/rbind.gemspec
CHANGED
metadata
CHANGED
@@ -1,23 +1,28 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbind
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.7
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 0.0.8
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Alexander Duda
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
12
|
+
|
13
|
+
date: 2013-06-30 00:00:00 Z
|
13
14
|
dependencies: []
|
14
|
-
|
15
|
-
|
15
|
+
|
16
|
+
description: ""
|
17
|
+
email:
|
16
18
|
- Alexander.Duda@dfki.de
|
17
19
|
executables: []
|
20
|
+
|
18
21
|
extensions: []
|
22
|
+
|
19
23
|
extra_rdoc_files: []
|
20
|
-
|
24
|
+
|
25
|
+
files:
|
21
26
|
- lib/rbind.rb
|
22
27
|
- lib/rbind/core.rb
|
23
28
|
- lib/rbind/core/.roperation.rb.swp
|
@@ -59,6 +64,9 @@ files:
|
|
59
64
|
- lib/rbind/templates/ruby/rbind.rb
|
60
65
|
- lib/rbind/templates/ruby/rmethod.rb
|
61
66
|
- lib/rbind/templates/ruby/rnamespace.rb
|
67
|
+
- lib/rbind/templates/ruby/roverloaded_method.rb
|
68
|
+
- lib/rbind/templates/ruby/roverloaded_method_call.rb
|
69
|
+
- lib/rbind/templates/ruby/roverloaded_static_method.rb
|
62
70
|
- lib/rbind/templates/ruby/rstatic_method.rb
|
63
71
|
- lib/rbind/templates/ruby/rtype.rb
|
64
72
|
- lib/rbind/templates/ruby/rtype_constructor.rb
|
@@ -67,27 +75,30 @@ files:
|
|
67
75
|
- test/test_generator_ruby.rb
|
68
76
|
homepage: http://github.com/
|
69
77
|
licenses: []
|
78
|
+
|
70
79
|
post_install_message:
|
71
80
|
rdoc_options: []
|
72
|
-
|
81
|
+
|
82
|
+
require_paths:
|
73
83
|
- lib
|
74
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
85
|
none: false
|
76
|
-
requirements:
|
77
|
-
- -
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version:
|
80
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
91
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
85
95
|
version: 1.3.6
|
86
96
|
requirements: []
|
97
|
+
|
87
98
|
rubyforge_project:
|
88
99
|
rubygems_version: 1.8.23
|
89
100
|
signing_key:
|
90
101
|
specification_version: 3
|
91
102
|
summary: Library for genereating automated ffi-bindings for c/c++ libraries
|
92
103
|
test_files: []
|
93
|
-
|
104
|
+
|