rbind 0.0.16 → 0.0.17

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.
Files changed (54) hide show
  1. data/lib/rbind.rb +1 -0
  2. data/lib/rbind/clang/clang.rb +3699 -0
  3. data/lib/rbind/clang/clang_types.rb +327 -0
  4. data/lib/rbind/clang_parser.rb +451 -0
  5. data/lib/rbind/core.rb +7 -4
  6. data/lib/rbind/core/rattribute.rb +17 -21
  7. data/lib/rbind/core/rbase.rb +98 -64
  8. data/lib/rbind/core/rcallback.rb +15 -0
  9. data/lib/rbind/core/rclass.rb +79 -16
  10. data/lib/rbind/core/rdata_type.rb +40 -39
  11. data/lib/rbind/core/renum.rb +18 -0
  12. data/lib/rbind/core/rnamespace.rb +189 -52
  13. data/lib/rbind/core/roperation.rb +52 -20
  14. data/lib/rbind/core/rparameter.rb +43 -8
  15. data/lib/rbind/core/rpointer.rb +70 -0
  16. data/lib/rbind/core/rreference.rb +54 -0
  17. data/lib/rbind/core/rtemplate_class.rb +49 -0
  18. data/lib/rbind/core/rtype_qualifier.rb +60 -0
  19. data/lib/rbind/default_parser.rb +48 -36
  20. data/lib/rbind/generator_c.rb +2 -2
  21. data/lib/rbind/generator_extern.rb +1 -3
  22. data/lib/rbind/generator_ruby.rb +201 -47
  23. data/lib/rbind/logger.rb +3 -0
  24. data/lib/rbind/rbind.rb +25 -9
  25. data/lib/rbind/templates/c/CMakeLists.txt +6 -6
  26. data/lib/rbind/templates/ruby/rbind.rb +1 -1
  27. data/lib/rbind/templates/ruby/rmethod.rb +4 -1
  28. data/lib/rbind/templates/ruby/rnamespace.rb +2 -1
  29. data/lib/rbind/templates/ruby/roverloaded_method.rb +3 -1
  30. data/lib/rbind/templates/ruby/roverloaded_method_call.rb +1 -0
  31. data/lib/rbind/templates/ruby/roverloaded_static_method.rb +3 -2
  32. data/lib/rbind/templates/ruby/rstatic_method.rb +4 -1
  33. data/lib/rbind/templates/ruby/rtype.rb +19 -16
  34. data/lib/rbind/templates/ruby/rtype_template.rb +7 -0
  35. data/lib/rbind/{core/rstring.rb → types/std_string.rb} +8 -8
  36. data/lib/rbind/types/std_vector.rb +100 -0
  37. data/rbind.gemspec +2 -2
  38. data/test/headers/cfunctions.h +7 -0
  39. data/test/headers/classes.hpp +29 -0
  40. data/test/headers/constants.hpp +14 -0
  41. data/test/headers/enums.hpp +22 -0
  42. data/test/headers/std_string.hpp +26 -0
  43. data/test/headers/std_vector.hpp +31 -0
  44. data/test/headers/structs.hpp +34 -0
  45. data/test/headers/templates.hpp +20 -0
  46. data/test/test_clang_parser.rb +146 -0
  47. data/test/test_generator_ruby.rb +0 -5
  48. data/test/test_roperation.rb +144 -0
  49. data/test/test_rparameter.rb +88 -0
  50. metadata +24 -7
  51. data/lib/rbind/core/.roperation.rb.swp +0 -0
  52. data/lib/rbind/core/rconst.rb +0 -35
  53. data/lib/rbind/core/rstruct.rb +0 -87
  54. data/lib/rbind/core/rvector.rb +0 -27
@@ -7,19 +7,39 @@ module Rbind
7
7
  attr_accessor :base_class
8
8
  attr_accessor :ambiguous_name
9
9
  attr_accessor :index # index if overloaded
10
+ attr_accessor :static
11
+ attr_accessor :cplusplus_alias
10
12
 
11
- def initialize(name,return_type,*args)
13
+ def initialize(name,return_type=nil,*args)
12
14
  super(name)
13
- raise ArgumentError ,"wrong type #{return_type}" if return_type && !return_type.is_a?(RDataType)
14
15
  @return_type = return_type
15
16
  @parameters = args.flatten
16
- @parameters.each do |para|
17
- raise ArgumentError ,"wrong parameter type#{para}" if !para.is_a?(RParameter)
17
+ @cplusplus_alias = true
18
+ end
19
+
20
+ # indicates if an alias method shall be added
21
+ # having the same name style like the c++ method
22
+ def cplusplus_alias?
23
+ !!@cplusplus_alias
24
+ end
25
+
26
+ def add_parameter(para,&block)
27
+ para = if para.is_a? String
28
+ raise "No owner. Cannot create parameter" unless owner
29
+ para = RParameter.new(para,owner.void)
30
+ owner.instance_exec(para,&block) if block
31
+ para
32
+ else
33
+ para
34
+ end
35
+ if @parameters.find{|p| p.name == para.name}
36
+ raise RuntimeError,"duplicate parameter name #{para}"
18
37
  end
19
- @cparameters = @parameters
38
+ @parameters << para
20
39
  end
21
40
 
22
41
  def ==(other)
42
+ return false if other.class != self.class
23
43
  return false unless name == other.name
24
44
  @parameters.each_with_index do |p,i|
25
45
  return false if p != other.parameters[i]
@@ -58,33 +78,34 @@ module Rbind
58
78
  @parameters[idx]
59
79
  end
60
80
 
61
- def valid_flags
62
- super << :S << :explicit
81
+ def static?
82
+ !instance_method?
63
83
  end
64
84
 
65
- def static?
66
- @flags.include?(:S)
85
+ def to_static
86
+ op = self.dup
87
+ op.static = true
88
+ op
67
89
  end
68
90
 
69
91
  def generate_signatures
70
92
  s = "#{return_type.signature} " unless constructor?
71
93
  s = "#{s}#{full_name}(#{parameters.map(&:signature).join(", ")})"
72
-
94
+
73
95
  cs = if constructor?
74
96
  owner.to_ptr.csignature if owner
75
97
  else
76
98
  if return_type.basic_type?
77
99
  return_type.csignature
78
100
  else
79
- return_type.to_ptr.csignature
101
+ return_type.to_single_ptr.csignature
80
102
  end
81
103
  end
82
104
  paras = cparameters.map do |p|
83
105
  if p.type.basic_type?
84
106
  p.csignature
85
107
  else
86
- tp = p.to_ptr
87
- "#{tp.csignature}"
108
+ p.to_single_ptr.csignature
88
109
  end
89
110
  end.join(", ")
90
111
  cs = "#{cs} #{cname}(#{paras})"
@@ -92,28 +113,39 @@ module Rbind
92
113
  end
93
114
 
94
115
  def instance_method?
95
- owner.is_a?(RStruct) && !constructor? && !static?
116
+ owner.is_a?(RClass) && !constructor? && !@static
117
+ end
118
+
119
+ def cparameters
120
+ return @cparameters if @cparameters
121
+ if instance_method?
122
+ p = RParameter.new("rbind_obj",owner)
123
+ [p] + @parameters
124
+ else
125
+ @parameters.dup
126
+ end
96
127
  end
97
128
 
98
129
  def owner=(obj)
99
130
  super
100
131
  @base_class ||=obj
101
- @cparameters = if instance_method?
102
- p = RParameter.new("rbind_obj",obj,nil,:IO)
103
- [p] + @parameters
104
- else
105
- @parameters
106
- end
107
132
  @parameters.each do |para|
108
133
  para.owner = self
109
134
  end
110
135
  self
111
136
  end
112
137
 
138
+ # generates documentation based on the method signature
139
+ def generate_doc
140
+
141
+ end
142
+
113
143
  def constructor?
114
144
  !@return_type
115
145
  end
116
146
 
147
+ # returns true if the method is a setter or getter
148
+ # generated for a class attribute
117
149
  def attribute?
118
150
  false
119
151
  end
@@ -3,13 +3,14 @@ module Rbind
3
3
  class RParameter < RAttribute
4
4
  attr_accessor :default_value
5
5
 
6
- def initialize(name,type,default_value=nil,*flags)
7
- super(name,type,*flags)
6
+ def initialize(name,type,default_value=nil)
7
+ super(name,type)
8
8
  self.default_value = default_value
9
9
  end
10
10
 
11
11
  def default_value=(val)
12
- @default_value = if val && !val.empty?
12
+ val = val.to_s
13
+ @default_value = if !val.empty?
13
14
  val.chomp.chomp(" ")
14
15
  else
15
16
  nil
@@ -25,16 +26,50 @@ module Rbind
25
26
  end
26
27
  end
27
28
 
28
- def valid_flags
29
- [:IO,:O]
29
+ def to_single_ptr
30
+ t = self.clone
31
+ t.type = type.to_single_ptr
32
+ t
33
+ end
34
+
35
+ def remove_const!
36
+ @type = type.remove_const
37
+ self
38
+ end
39
+
40
+ def const!
41
+ return self if const?
42
+ @type = type.to_const
43
+ self
44
+ end
45
+
46
+ def to_const
47
+ return self if const?
48
+ para = self.dup
49
+ para.type = type.to_const
50
+ self
51
+ end
52
+
53
+ def const?
54
+ type.const?
55
+ end
56
+
57
+ def ref?
58
+ type.ref?
59
+ end
60
+
61
+ def basic_type?
62
+ type.basic_type?
30
63
  end
31
64
 
32
65
  def generate_signatures
33
- c,cs = super
34
66
  if default_value
35
- c = "#{c}=#{default_value}"
67
+ sigs = super
68
+ sigs[0] += " = #{default_value}"
69
+ sigs
70
+ else
71
+ super
36
72
  end
37
- [c,cs]
38
73
  end
39
74
  end
40
75
  end
@@ -0,0 +1,70 @@
1
+ require 'delegate'
2
+
3
+ module Rbind
4
+ class RPointer < SimpleDelegator
5
+ attr_accessor :const
6
+
7
+ def initialize(type)
8
+ super(type)
9
+ end
10
+
11
+ def name
12
+ super.to_s + "*"
13
+ end
14
+
15
+ def full_name
16
+ super.to_s + "*"
17
+ end
18
+
19
+ def signature(sig=nil)
20
+ super.to_s + "*"
21
+ end
22
+
23
+ def csignature(sig=nil)
24
+ super.to_s + "*"
25
+ end
26
+
27
+ def ptr?
28
+ true
29
+ end
30
+
31
+ def ref?
32
+ false
33
+ end
34
+
35
+ def raw?
36
+ false
37
+ end
38
+
39
+ def remove_const
40
+ RPointer.new __getobj__.remove_const
41
+ end
42
+
43
+ def to_ptr
44
+ RPointer.new(self)
45
+ end
46
+
47
+ def to_ref
48
+ RReference.new(self)
49
+ end
50
+
51
+ def to_const
52
+ return self if const?
53
+ RTypeQualifier.new(self,:const => true)
54
+ end
55
+
56
+ def signature(sig=nil)
57
+ generate_signatures[0]
58
+ end
59
+
60
+ def csignature(sig=nil)
61
+ generate_signatures[1]
62
+ end
63
+
64
+ def generate_signatures
65
+ __getobj__.generate_signatures.map do |s|
66
+ s + "*"
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,54 @@
1
+ require 'delegate'
2
+
3
+ module Rbind
4
+ class RReference < SimpleDelegator
5
+ attr_accessor :const
6
+
7
+ def initialize(type)
8
+ super(type)
9
+ end
10
+
11
+ def ref?
12
+ true
13
+ end
14
+
15
+ def ptr?
16
+ false
17
+ end
18
+
19
+ def raw?
20
+ false
21
+ end
22
+
23
+ def to_ptr
24
+ RPointer.new(self)
25
+ end
26
+
27
+ def to_ref
28
+ RReference.new(self)
29
+ end
30
+
31
+ def to_const
32
+ return self if const?
33
+ RTypeQualifier.new(self,:const => true)
34
+ end
35
+
36
+ def remove_const
37
+ RReference.new __getobj__.remove_const
38
+ end
39
+
40
+ def signature(sig=nil)
41
+ generate_signatures[0]
42
+ end
43
+
44
+ def csignature(sig=nil)
45
+ generate_signatures[1]
46
+ end
47
+
48
+ def generate_signatures
49
+ __getobj__.generate_signatures.map do |s|
50
+ s + "&"
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,49 @@
1
+
2
+ module Rbind
3
+ class RTemplateParameter < RDataType
4
+ def template?
5
+ true
6
+ end
7
+ end
8
+
9
+ class RTemplateClassSpecialization < RClass
10
+ attr_accessor :template,:template_parameters
11
+
12
+ def initialize(name,template,*parameters)
13
+ super(name)
14
+ @name = @name.gsub(">>","> >") # force overwrite to match c++ syntax
15
+ @template = template
16
+ @template_parameteres = parameters
17
+ end
18
+
19
+ def specialize_ruby
20
+ template.specialize_ruby_specialization(self)
21
+ end
22
+ end
23
+
24
+ class RTemplateClass < RClass
25
+ def initialize(name,*parent_classes)
26
+ raise "parent classes for template classes are not supported!" if !parent_classes.empty?
27
+ super
28
+ end
29
+
30
+ def template?
31
+ true
32
+ end
33
+
34
+ # called by RNamespace
35
+ def do_specialize(name,*parameters)
36
+ klass = RTemplateClassSpecialization.new(name,self,*parameters)
37
+ specialize(klass,*parameters)
38
+ end
39
+
40
+ # hook for implementing the specialization
41
+ def specialize(klass,*parameters)
42
+ end
43
+
44
+ # hook for generating additional ruby code going to be embedded into the
45
+ # class definition
46
+ def specialize_ruby_specialization(klass)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,60 @@
1
+ require 'delegate'
2
+
3
+ module Rbind
4
+ class RTypeQualifier < SimpleDelegator
5
+ attr_accessor :const
6
+
7
+ def initialize(type,options=Hash.new)
8
+ super(type)
9
+ @const = options[:const]
10
+ end
11
+
12
+ def const?
13
+ !!@const
14
+ end
15
+
16
+ def to_single_ptr
17
+ t = to_raw
18
+ t = t.to_const if const?
19
+ t.to_ptr
20
+ end
21
+
22
+ def to_ptr
23
+ RPointer.new(self)
24
+ end
25
+
26
+ def to_ref
27
+ RReference.new(self)
28
+ end
29
+
30
+ def to_const
31
+ return self if const?
32
+ RTypeQualifier.new(self,:const => true)
33
+ end
34
+
35
+ def remove_const
36
+ __getobj__
37
+ end
38
+
39
+ def raw?
40
+ false
41
+ end
42
+
43
+ def signature(sig=nil)
44
+ generate_signatures[0]
45
+ end
46
+
47
+ def csignature(sig=nil)
48
+ generate_signatures[1]
49
+ end
50
+
51
+ def generate_signatures
52
+ str = if const?
53
+ "const "
54
+ end
55
+ __getobj__.generate_signatures.map do |s|
56
+ str + s
57
+ end
58
+ end
59
+ end
60
+ end
@@ -3,35 +3,25 @@ module Rbind
3
3
  class DefaultParser < RNamespace
4
4
  extend ::Rbind::Logger
5
5
 
6
- def initialize
7
- super("root")
8
- self.root = true
9
- add_default_types
10
- @on_type_not_found
6
+ def initialize(root = nil)
7
+ super(nil,root)
8
+ add_default_types if !root
11
9
  end
12
10
 
13
- def normalize_flags(line_number,flags)
11
+ def normalize_flags(line_number,flags,*valid_flags)
14
12
  flags.map do |flag|
15
13
  next if flag.empty?
16
14
  if flag =~ /(\w*)(.*)/
17
15
  DefaultParser.log.debug "input line #{line_number}: ignoring flag #{$2}" unless $2.empty?
18
- $1.to_sym
16
+ flag = $1.to_sym
17
+ DefaultParser.log.debug "input line #{line_number}: ignoring flag #{$1}" unless valid_flags.include?(flag)
18
+ flag
19
19
  else
20
20
  raise "cannot parse flag #{flag.inspect}"
21
21
  end
22
22
  end.compact
23
23
  end
24
24
 
25
- def normalize_default_value(value)
26
- value = value.gsub(/std::vector</,"vector<")
27
- val = value.gsub(/(.?)vector<(.*)>/,'\1vector_\2')
28
- if value != val
29
- normalize_default_value(val)
30
- else
31
- val
32
- end
33
- end
34
-
35
25
  def add_data_type_name(name)
36
26
  t = RDataType.new(name)
37
27
  add_type t
@@ -44,12 +34,6 @@ module Rbind
44
34
  ns
45
35
  end
46
36
 
47
- def add_struct_name(name)
48
- s = RStruct.new(name)
49
- add_type s
50
- s
51
- end
52
-
53
37
  def add_class_name(name)
54
38
  klass = RClass.new(name)
55
39
  add_type klass
@@ -60,11 +44,28 @@ module Rbind
60
44
  @on_type_not_found = block
61
45
  end
62
46
 
47
+ # reverse template masking done by the opencv parser
48
+ def unmask_template(type_name)
49
+ if(type_name =~/<.*>/)
50
+ return type_name
51
+ end
52
+
53
+ if(type_name =~/^vector/ || type_name =~/^Ptr/)
54
+ if(type_name =~ /^([a-zA-Z\d]*)_([_a-zA-Z\d]*) ?(\(?.*)\)? */)
55
+ "#{$1}<#{unmask_template($2)}>#{$3}"
56
+ else
57
+ type_name
58
+ end
59
+ else
60
+ type_name
61
+ end
62
+ end
63
63
 
64
64
  def find_type(owner,type_name)
65
+ type_name = unmask_template(type_name)
65
66
  t = owner.type(type_name,false)
66
67
  return t if t
67
-
68
+
68
69
  normalized = type_name.split("_")
69
70
  name = normalized.shift
70
71
  while !normalized.empty?
@@ -88,10 +89,15 @@ module Rbind
88
89
  array = flags.shift.split(" ")
89
90
  type_name = array.shift
90
91
  para_name = array.shift
91
- default = normalize_default_value(array.join(" "))
92
+ default = unmask_template(array.join(" "))
92
93
  type = find_type(owner,type_name)
93
- flags = normalize_flags(line_number,flags)
94
- RParameter.new(para_name,type,default,flags)
94
+ flags = normalize_flags(line_number,flags,:IO,:O)
95
+ type = if flags.include?(:O) || flags.include?(:IO) || type.basic_type?
96
+ type
97
+ else
98
+ type.to_const
99
+ end
100
+ RParameter.new(para_name,type,default)
95
101
  rescue RuntimeError => e
96
102
  raise "input line #{line_number}: #{e}"
97
103
  end
@@ -102,8 +108,10 @@ module Rbind
102
108
  type_name = array[0]
103
109
  name = array[1]
104
110
  type = find_type(owner,type_name)
105
- flags = normalize_flags(line_number,flags)
106
- RAttribute.new(name,type,flags)
111
+ flags = normalize_flags(line_number,flags,:RW,:R)
112
+ a = RAttribute.new(name,type)
113
+ a.writeable!(true) if flags.include? :RW
114
+ a
107
115
  rescue RuntimeError => e
108
116
  raise "input line #{line_number}: #{e}"
109
117
  end
@@ -111,7 +119,7 @@ module Rbind
111
119
  def parse_class(line_number,string)
112
120
  lines = string.split("\n")
113
121
  a = lines.shift.rstrip
114
- unless a =~ /class ([a-zA-Z\.\d_:]*) ?:?([a-zA-Z\.\:, \d_]*)(.*)/
122
+ unless a =~ /class ([<>a-zA-Z\.\d_:]*) ?:?([<>a-zA-Z\.\:, \d_]*)(.*)/
115
123
  raise "cannot parse class #{a}"
116
124
  end
117
125
  name = $1
@@ -134,7 +142,7 @@ module Rbind
134
142
  end
135
143
  end
136
144
  flags = if flags
137
- normalize_flags(line_number,flags.gsub(" ","").split("/").compact)
145
+ normalize_flags(line_number,flags.gsub(" ","").split("/").compact,:Simple)
138
146
  end
139
147
  t = RClass.new(name,*parent_classes)
140
148
  t = if t2 = type(t.full_name,false)
@@ -147,10 +155,10 @@ module Rbind
147
155
  t2
148
156
  end
149
157
  else
158
+ t.name = t.name.gsub(">>","> >")
150
159
  add_type(t)
151
160
  t
152
161
  end
153
- t.flags = flags if flags
154
162
  line_counter = 1
155
163
  lines.each do |line|
156
164
  a = attribute(line_counter+line_number,line,t)
@@ -169,7 +177,7 @@ module Rbind
169
177
  flags = first_line.split(" /")
170
178
  name = flags.shift.split(" ")[1]
171
179
  flags = normalize_flags(line_number,flags)
172
- klass = RStruct.new(name,flags)
180
+ klass = RClass.new(name)
173
181
  add_type(klass)
174
182
  line_counter = 1
175
183
  a.each do |line|
@@ -195,8 +203,7 @@ module Rbind
195
203
  normalize_flags(line_number,flags.gsub(" ","").split("/").compact)
196
204
  end
197
205
 
198
- c = RConst.new(name,value)
199
- c.flags = flags if flags
206
+ c = RParameter.new(name,find_type(self,"const int"),value)
200
207
  c.extern_package_name = @extern_package_name
201
208
  add_const(c)
202
209
  [c,1]
@@ -237,7 +244,12 @@ module Rbind
237
244
  end
238
245
  op = ::Rbind::ROperation.new(name,return_type,*args)
239
246
  op.alias = alias_name if alias_name && !alias_name.empty?
240
- op.flags = normalize_flags(line_number,flags)
247
+ flags = normalize_flags(line_number,flags,:S)
248
+ op = if flags.include?(:S)
249
+ op.to_static
250
+ else
251
+ op
252
+ end
241
253
  type(op.namespace,true).add_operation(op)
242
254
  [op,line_counter]
243
255
  end