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.
@@ -3,6 +3,7 @@ module Rbind
3
3
  attr_accessor :name
4
4
  attr_accessor :cname
5
5
  attr_accessor :alias
6
+ attr_accessor :auto_alias # set to true if rbind is aliasing the object
6
7
  attr_accessor :namespace
7
8
  attr_accessor :owner
8
9
  attr_accessor :flags
@@ -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("::")
@@ -6,6 +6,7 @@ module Rbind
6
6
  attr_accessor :cparameters
7
7
  attr_accessor :base_class
8
8
  attr_accessor :ambiguous_name
9
+ attr_accessor :index # index if overloaded
9
10
 
10
11
  def initialize(name,return_type,*args)
11
12
  super(name)
@@ -23,7 +23,8 @@ module Rbind
23
23
  end
24
24
 
25
25
  def normalize_default_value(value)
26
- val = value.gsub(/(.?)std::vector<(.*)>/,'\1vector_\2')
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
@@ -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.type.name == "float"
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.normalize_basic_type_name(name)
92
- @@basic_type_map ||= {"char *" => "string","unsigned char" => "uchar" ,"const char *" => "string" }
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.normalize_basic_type_name name
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
- GeneratorRuby.normalize_method_name(__getobj__.alias || __getobj__.name)
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
- root.specialize_ruby
323
- else
324
- ""
325
- end
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
- @type_constructor_wrapper.result(ch.binding)
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
- @root.each_operation do |op|
361
- next if op.constructor?
362
- oph = OperationHelper.new(op)
363
- str += if op.instance_method?
364
- @method_wrapper.result(oph.binding)
365
- else
366
- @static_method_wrapper.result(oph.binding)
367
- end
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,6 @@
1
+ # wrapper for overloaded method <%= name %>
2
+ def <%=name%>(*args)
3
+ <%= add_methods %>
4
+ raise ArgumentError, "No overloaded signature fits to: #{args.map(&:class)}"
5
+ end
6
+
@@ -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
@@ -0,0 +1,6 @@
1
+ # wrapper for overloaded method <%= name %>
2
+ def self.<%=name%>(*args)
3
+ <%= add_methods %>
4
+ raise ArgumentError, "No overloaded signature fits to: #{args.map(&:class)}"
5
+ end
6
+
data/rbind.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rbind'
3
- s.version = '0.0.7'
4
- s.date = '2013-06-27'
3
+ s.version = '0.0.8'
4
+ s.date = '2013-06-30'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ['Alexander Duda']
7
7
  s.email = ['Alexander.Duda@dfki.de']
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
- date: 2013-06-27 00:00:00.000000000 Z
12
+
13
+ date: 2013-06-30 00:00:00 Z
13
14
  dependencies: []
14
- description: ''
15
- email:
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
- files:
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
- require_paths:
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: '0'
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
- has_rdoc:
104
+