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
@@ -1,7 +1,6 @@
1
1
  require 'rbind/logger.rb'
2
2
  require 'rbind/core/rbase.rb'
3
3
  require 'rbind/core/rdata_type.rb'
4
- require 'rbind/core/rconst.rb'
5
4
  require 'rbind/core/renum.rb'
6
5
  require 'rbind/core/rattribute.rb'
7
6
  require 'rbind/core/rparameter.rb'
@@ -9,7 +8,11 @@ require 'rbind/core/roperation.rb'
9
8
  require 'rbind/core/rgetter.rb'
10
9
  require 'rbind/core/rsetter.rb'
11
10
  require 'rbind/core/rnamespace.rb'
12
- require 'rbind/core/rstruct.rb'
13
11
  require 'rbind/core/rclass.rb'
14
- require 'rbind/core/rvector.rb'
15
- require 'rbind/core/rstring.rb'
12
+ require 'rbind/core/rtemplate_class.rb'
13
+ require 'rbind/core/rreference.rb'
14
+ require 'rbind/core/rpointer.rb'
15
+ require 'rbind/core/rtype_qualifier.rb'
16
+
17
+ require 'rbind/types/std_vector.rb'
18
+ require 'rbind/types/std_string.rb'
@@ -2,11 +2,12 @@ module Rbind
2
2
  class RAttribute < RBase
3
3
  attr_accessor :type
4
4
 
5
- def initialize(name,type,*flags)
6
- super(name,*flags)
5
+ def initialize(name,type)
6
+ super(name)
7
7
  raise ArgumentError,"no type" unless type
8
- raise "wrong name #{name}" if name =~/.*\*.*/
9
8
  @type = type
9
+ @readable = true
10
+ @writable = false
10
11
  end
11
12
 
12
13
  def ==(other)
@@ -14,32 +15,27 @@ module Rbind
14
15
  end
15
16
 
16
17
  def generate_signatures
17
- s = "#{type.signature}#{" " if !type.ptr? && !type.ref?}#{name}"
18
- cs= "#{type.csignature}#{" " if !type.ptr? && !type.ref?}#{name}"
19
-
20
- if read_only? && !type.basic_type?
21
- s = "const #{s}"
22
- cs = "const #{cs}"
18
+ @type.generate_signatures.map do |s|
19
+ "#{s} #{name}"
23
20
  end
24
- [s,cs]
25
21
  end
26
22
 
27
- def valid_flags
28
- super << :RW
23
+ def readable!(value = true)
24
+ @readable = value
25
+ self
29
26
  end
30
27
 
31
- def to_ptr
32
- a = self.dup
33
- a.type = type.to_ptr
34
- a
28
+ def writeable!(value = true)
29
+ @writeable = value
30
+ self
35
31
  end
36
32
 
37
- def read_only?
38
- !write?
33
+ def readable?
34
+ !!@readable
39
35
  end
40
-
41
- def write?
42
- flags.include?(:RW) || flags.include?(:IO) || flags.include?(:O)
36
+
37
+ def writeable?
38
+ !!@writeable
43
39
  end
44
40
  end
45
41
  end
@@ -6,11 +6,12 @@ module Rbind
6
6
  attr_accessor :auto_alias # set to true if rbind is aliasing the object
7
7
  attr_accessor :namespace
8
8
  attr_accessor :owner
9
- attr_accessor :flags
10
9
  attr_accessor :version
11
10
  attr_accessor :signature
12
11
  attr_accessor :csignature
13
12
  attr_accessor :ignore
13
+ attr_accessor :extern_package_name
14
+ attr_accessor :doc
14
15
 
15
16
  class << self
16
17
  attr_accessor :cprefix
@@ -18,23 +19,26 @@ module Rbind
18
19
  def to_cname(name)
19
20
  name = normalize(name)
20
21
  cn = "#{cprefix}#{name.gsub("::","_")}"
21
- cn = cn.gsub("()","_fct")
22
- cn = cn.gsub("<=","_smaller_equal")
23
- cn = cn.gsub(">=","_greater_equal")
24
- cn = cn.gsub("!=","_unequal")
25
- cn = cn.gsub("==","_equal")
26
- cn = cn.gsub("&=","_and_set")
27
- cn = cn.gsub("+=","_add")
28
- cn = cn.gsub("-=","_sub")
29
- cn = cn.gsub("+","_plus")
30
- cn = cn.gsub("-","_minus")
31
- cn = cn.gsub("*","_mult")
32
- cn = cn.gsub("/","_div")
33
- cn = cn.gsub("!","_not")
34
- cn = cn.gsub("&","_and")
35
- cn = cn.gsub("<","_smaller")
36
- cn = cn.gsub(">","_greater")
37
- cn.gsub("[]","_array")
22
+ if cn =~ /operator/
23
+ cn = cn.gsub("operator()","operator_fct")
24
+ cn = cn.gsub("operator!=","operator_unequal")
25
+ cn = cn.gsub("operator==","operator_equal")
26
+ cn = cn.gsub("operator&=","operator_and_set")
27
+ cn = cn.gsub("operator+=","operator_add")
28
+ cn = cn.gsub("operator-=","operator_sub")
29
+ cn = cn.gsub("operator+","operator_plus")
30
+ cn = cn.gsub("operator-","operator_minus")
31
+ cn = cn.gsub("operator*","operator_mult")
32
+ cn = cn.gsub("operator/","operator_div")
33
+ cn = cn.gsub("operator!","operator_not")
34
+ cn = cn.gsub("operator&","operator_and")
35
+ cn = cn.gsub("operator[]","operator_array")
36
+ end
37
+ cn = cn.gsub("*","_ptr")
38
+ cn = cn.gsub("&","_ref")
39
+ cn = cn.gsub("<","_")
40
+ cn = cn.gsub(">","")
41
+ cn = cn.gsub(",","__")
38
42
  end
39
43
 
40
44
  def normalize(name)
@@ -45,37 +49,36 @@ module Rbind
45
49
  name.gsub(".","::").gsub(" ","")
46
50
  end
47
51
 
48
- def basename(name)
52
+ def split_name(name)
49
53
  name = normalize(name)
50
- if !!(name =~/.*::(.*)$/)
51
- $1
54
+ # check for template
55
+ if(name =~/([\w:]*)(<.*)$/)
56
+ result = split_name($1)
57
+ [result[0],result[1]+$2]
58
+ elsif(name =~/(.*)::(.*)$/)
59
+ [$1,$2]
52
60
  else
53
- name
61
+ [nil,name]
54
62
  end
55
63
  end
56
64
 
57
65
  def namespace(name)
58
- name = normalize(name)
59
- if !!(name =~/(.*)::.*$/)
60
- $1
61
- else
62
- nil
63
- end
66
+ split_name(name)[0]
67
+ end
68
+
69
+ def basename(name)
70
+ split_name(name)[1]
64
71
  end
65
72
  end
66
73
  self.cprefix = "rbind_"
67
74
 
68
75
  def pretty_print(pp)
69
- pp.text "#{signature}#{" Flags: #{flags.join(", ")}" unless flags.empty?}"
76
+ pp.text "#{signature}"
70
77
  end
71
78
 
72
- def initialize(name,*flags)
73
- name = RBase::normalize(name)
74
- raise ArgumentError, "no name" unless name && name.size > 0
75
- @name = RBase::basename(name)
76
- @namespace = RBase::namespace(name)
79
+ def initialize(name)
80
+ rename(name)
77
81
  @version = 1
78
- self.flags = flags.flatten
79
82
  end
80
83
 
81
84
  def generate_signatures
@@ -86,6 +89,11 @@ module Rbind
86
89
  !!@ignore
87
90
  end
88
91
 
92
+ # returns true if this object is defined in another extern package
93
+ def extern?
94
+ extern_package_name && !extern_package_name.empty?
95
+ end
96
+
89
97
  def signature(sig=nil)
90
98
  return @signature || generate_signatures[0] unless sig
91
99
  @signature = sig
@@ -122,43 +130,26 @@ module Rbind
122
130
  end
123
131
  end
124
132
 
125
- def flags=(*flags)
126
- flags.flatten!
127
- validate_flags(flags)
128
- @flags = flags
129
- end
130
-
131
- def add_flag(*flags)
132
- @flags += flags
133
- self
134
- end
135
-
136
- def valid_flags
137
- []
138
- end
139
-
140
- def validate_flags(flags,valid_flags = self.valid_flags)
141
- valid_flags.flatten!
142
- flags.each do |flag|
143
- if !valid_flags.include?(flag)
144
- raise "flag #{flag} is not supported for #{self.class.name}. Supported flags are #{valid_flags}"
145
- end
146
- end
147
- end
148
-
149
133
  def owner=(obj)
150
- if obj.respond_to?(:root?) && !obj.root?
151
- @namespace = obj.full_name
152
- else
153
- @namespace = nil
154
- end
134
+ raise ArgumentError,"Cannot at self as owner" if obj.object_id == self.object_id
155
135
  @owner = obj
136
+ @namespace = nil
156
137
  end
157
138
 
158
139
  def ignore?
159
140
  !!@ignore
160
141
  end
161
142
 
143
+ def namespace
144
+ if @namespace
145
+ @namespace
146
+ elsif @owner.respond_to?(:root?) && !@owner.root?
147
+ @owner.full_name
148
+ else
149
+ nil
150
+ end
151
+ end
152
+
162
153
  def namespace?
163
154
  namespace && namespace.size != 0
164
155
  end
@@ -167,6 +158,10 @@ module Rbind
167
158
  map_to_namespace(name)
168
159
  end
169
160
 
161
+ def to_s
162
+ signature
163
+ end
164
+
170
165
  def map_to_namespace(name)
171
166
  if namespace
172
167
  "#{namespace}::#{name}"
@@ -175,8 +170,47 @@ module Rbind
175
170
  end
176
171
  end
177
172
 
173
+ def rename(name)
174
+ old_name = self.name
175
+ name = RBase::normalize(name)
176
+ raise ArgumentError, "no name" unless name && name.size > 0
177
+ @name = RBase::basename(name)
178
+ @namespace = RBase::namespace(name)
179
+ if @owner
180
+ @owner.delete_type old_name
181
+ @owner.add_type(self)
182
+ end
183
+ end
184
+
185
+ def delete!
186
+ if @owner
187
+ @owner.delete_type self.name
188
+ else
189
+ raise "#{self} has no owner."
190
+ end
191
+ end
192
+
178
193
  def binding
179
194
  Kernel.binding
180
195
  end
196
+
197
+ def doc(&block)
198
+ if block
199
+ @doc = block
200
+ elsif @doc.is_a? Proc
201
+ @doc.call
202
+ else
203
+ @doc
204
+ end
205
+ end
206
+
207
+ # specialize
208
+ def specialize_ruby(&block)
209
+ if block
210
+ @specialize_ruby = block
211
+ elsif @specialize_ruby
212
+ @specialize_ruby.call
213
+ end
214
+ end
181
215
  end
182
216
  end
@@ -0,0 +1,15 @@
1
+
2
+ module Rbind
3
+ class RCallback < RDataType
4
+ attr_reader :fct
5
+
6
+ def initialize(name,return_type,*args)
7
+ @fct = ROperation.new(name,return_type,*args)
8
+ super(name)
9
+ end
10
+
11
+ def callback?
12
+ true
13
+ end
14
+ end
15
+ end
@@ -1,10 +1,13 @@
1
1
 
2
2
  module Rbind
3
- class RClass < RStruct
3
+ class RClass < RNamespace
4
4
  attr_reader :parent_classes
5
+ attr_reader :attributes
6
+ ParentClass = Struct.new(:type,:accessor)
5
7
 
6
8
  def initialize(name,*parent_classes)
7
9
  @parent_classes = Hash.new
10
+ @attributes = Hash.new
8
11
  parent_classes.flatten!
9
12
  parent_classes.each do |p|
10
13
  add_parent(p)
@@ -12,10 +15,39 @@ module Rbind
12
15
  super(name)
13
16
  end
14
17
 
18
+ def basic_type?
19
+ false
20
+ end
21
+
22
+ def constructor?
23
+ ops = Array(operation(name,false))
24
+ return false unless ops
25
+ op = ops.find do |op|
26
+ op.constructor?
27
+ end
28
+ !!op
29
+ end
30
+
31
+ def add_attribute(attr)
32
+ if attr.namespace?
33
+ type(attr.namespace).add_attribute(attr)
34
+ else
35
+ if @attributes.has_key? attr.name
36
+ raise "#An attribute with the name #{attr.name} already exists"
37
+ end
38
+ attr.owner = self
39
+ @attributes[attr.name] = attr
40
+ # add getter and setter methods to the object
41
+ add_operation(RGetter.new(attr)) if attr.readable?
42
+ add_operation(RSetter.new(attr)) if attr.writeable?
43
+ end
44
+ self
45
+ end
46
+
15
47
  def attributes
16
48
  attribs = @attributes.values
17
49
  parent_classes.each do |k|
18
- others = k.attributes
50
+ others = k.type.attributes
19
51
  others.delete_if do |other|
20
52
  attribs.inclue? other
21
53
  end
@@ -32,7 +64,7 @@ module Rbind
32
64
  attrib = @attributes[name]
33
65
  attrib ||= begin
34
66
  p = parent_classes.find do |k|
35
- k.attribute(name)
67
+ k.type.attribute(name)
36
68
  end
37
69
  a = p.attribute(name).dup if p
38
70
  a.owner = self if a
@@ -44,7 +76,7 @@ module Rbind
44
76
  # temporarily add all base class operations
45
77
  own_ops = @operations.dup
46
78
  parent_classes.each do |k|
47
- k.operations.each do |other_ops|
79
+ k.type.operations.each do |other_ops|
48
80
  next if other_ops.empty?
49
81
  ops = if @operations.has_key?(other_ops.first.name)
50
82
  @operations[other_ops.first.name]
@@ -81,7 +113,7 @@ module Rbind
81
113
  def used_namespaces
82
114
  namespaces = super.clone
83
115
  parent_classes.each do |k|
84
- namespaces.merge k.used_namespaces
116
+ namespaces += k.type.used_namespaces
85
117
  end
86
118
  namespaces
87
119
  end
@@ -93,7 +125,7 @@ module Rbind
93
125
  []
94
126
  end
95
127
  parent_classes.each do |k|
96
- other_ops = Array(k.operation(name,false))
128
+ other_ops = Array(k.type.operation(name,false))
97
129
  other_ops.delete_if do |other_op|
98
130
  ops.include? other_op
99
131
  end
@@ -108,19 +140,27 @@ module Rbind
108
140
  end
109
141
  end
110
142
 
111
- def parent_classes
112
- @parent_classes.values
143
+ def cdelete_method
144
+ if @cdelete_method
145
+ @cdelete_method
146
+ else
147
+ if cname =~ /^#{RBase.cprefix}(.*)/
148
+ "#{RBase.cprefix}delete_#{$1}"
149
+ else
150
+ "#{RBase.cprefix}delete_#{name}"
151
+ end
152
+ end
113
153
  end
114
154
 
115
- def parent_class(name)
116
- @parent_classes[name]
155
+ def empty?
156
+ super && parent_classes.empty? && attributes.empty?
117
157
  end
118
158
 
119
159
  def pretty_print_name
120
- str = "class #{full_name}"
160
+ str = "#{"template " if template?}class #{full_name}"
121
161
  unless parent_classes.empty?
122
162
  parents = parent_classes.map do |p|
123
- p.full_name
163
+ p.type.full_name
124
164
  end
125
165
  str += " : " + parents.join(", ")
126
166
  end
@@ -129,24 +169,47 @@ module Rbind
129
169
 
130
170
  def pretty_print(pp)
131
171
  super
172
+ unless attributes.empty?
173
+ pp.nest(2) do
174
+ pp.breakable
175
+ pp.text "Attributes:"
176
+ pp.nest(2) do
177
+ attributes.each do |a|
178
+ pp.breakable
179
+ pp.pp(a)
180
+ end
181
+ end
182
+ end
183
+ end
132
184
  end
133
185
 
134
- def add_parent(klass)
186
+ def add_parent(klass,accessor=:public)
187
+ klass,accessor = if klass.is_a?(ParentClass)
188
+ [klass.type,klass.accessor]
189
+ else
190
+ [klass,accessor]
191
+ end
135
192
  if @parent_classes.has_key? klass.name
136
193
  raise ArgumentError,"#A parent class with the name #{klass.name} already exists"
137
194
  end
138
195
  if klass.full_name == full_name || klass == self
139
196
  raise ArgumentError,"class #{klass.full_name} cannot be parent of its self"
140
197
  end
141
- # we have to disable the type check for the parent class
198
+ # we have to disable the type check for the parent class
142
199
  # otherwise derived types cannot be parsed
143
200
  klass.check_type = false
144
- @parent_classes[klass.name] = klass
201
+ @parent_classes[klass.name] = ParentClass.new(klass,accessor)
145
202
  self
146
203
  end
147
204
 
148
205
  def parent_class(name)
149
- @parent_class[name]
206
+ @parent_class[name].type
207
+ end
208
+
209
+ def parent_classes(accessor = :public)
210
+ @parent_classes.values.find_all do |k|
211
+ k.accessor = accessor
212
+ end
150
213
  end
151
214
  end
152
215
  end