rbind 0.0.22 → 0.0.23

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1d454d9b534689a66f1be06bc64fe72b14b8721
4
- data.tar.gz: 546e600622265fda135f5bba965b4566693ae207
3
+ metadata.gz: a49ac912bcaf33b590650a1a9764e4055e1324f6
4
+ data.tar.gz: 2711d7f9cfbbf28b32aa7765914971f9f07f1da6
5
5
  SHA512:
6
- metadata.gz: cb922be3df7b1180cf0a8ee5672884e918dde3db4755f7f115228887acc08af46626aae629994f254d668bd51e4dd1417e28ee79c03023a513b9ec7c8a46367f
7
- data.tar.gz: e338f1e479038179af4316d48cce047d5a62638410a334d4da844cac3179dd8be9d6c26095b75af623ddba025a3d821fb7452cecaa7844d452dc3d6bd94834ce
6
+ metadata.gz: 2b5964e2a7e3b260879ded95cd659af9c918c16d78e7cd729ad34c720571d68a1eccdc620883ab8d246ef84dce2cea10ccb86eced4d7ee918bc42385967cb3f2
7
+ data.tar.gz: 8e855c1b6e0599cc5b9a966a794fe2badbdc4d7ba4ba1069d1b13560869c3c67319449ba5264a553014145ca46ec56fdd1b890c4b5ba6557e43aca00ff556086
@@ -0,0 +1 @@
1
+ gem build rbind.gemspec; gem install --no-rdoc --no-ri rbind-0.0.21.gem
@@ -5,6 +5,10 @@ module::Clang
5
5
  module Rbind
6
6
  extend FFI::Library
7
7
  clang_names = ['clang']
8
+
9
+ clang_names = Dir.glob("/usr/lib/libclang*")
10
+ clang_names.flatten!
11
+
8
12
  %w{3.4 3.3 3.2}.each do |llvm_version|
9
13
  clang_names << File.join("/", "usr", "lib", "llvm-#{llvm_version}", "lib", "libclang.so")
10
14
  end
@@ -85,6 +85,8 @@ module Clang
85
85
  # extend Structs to support auto dispose
86
86
  module Rbind
87
87
  class Cursor < FFI::Struct
88
+ extend ::Rbind::Logger
89
+
88
90
  def null?
89
91
  1 == Rbind::cursor_is_null(self)
90
92
  end
@@ -149,13 +151,22 @@ module Clang
149
151
  while !cursor.translation_unit?
150
152
  namespace << cursor.spelling
151
153
  cursor = cursor.semantic_parent
154
+ if cursor.invalid_file?
155
+ Cursor.log.warn "Cursor #{self} with invalid file"
156
+ break
157
+ end
152
158
  end
159
+ namespace = namespace.select{|s| !s.empty?}
153
160
  namespace.reverse.join("::")
154
161
  end
155
162
 
156
163
  def translation_unit?
157
164
  kind == :translation_unit
158
165
  end
166
+
167
+ def invalid_file?
168
+ kind == :invalid_file
169
+ end
159
170
 
160
171
  def expression
161
172
  num = FFI::MemoryPointer.new(:uint,1)
@@ -198,7 +209,7 @@ module Clang
198
209
  Rbind::get_cursor_type self
199
210
  end
200
211
 
201
- def virtul_base?
212
+ def virtual_base?
202
213
  1 == Rbind::is_virtual_base(self)
203
214
  end
204
215
 
@@ -40,13 +40,28 @@ module Rbind
40
40
  include Hooks
41
41
  extend ::Rbind::Logger
42
42
 
43
+ def self.default_arguments
44
+ @default_arguments || ["-xc++","-fno-rtti"]
45
+ end
46
+
47
+ def self.default_arguments=(args)
48
+ if not args.kind_of?(Array)
49
+ raise ArgumentError, "Clang::default_arguments require Array"
50
+ end
51
+ @default_arguments = args
52
+ end
53
+
54
+ def self.reset_default_arguments
55
+ @default_arguments = []
56
+ end
57
+
43
58
  def initialize(root=nil)
44
59
  super(nil,root)
45
60
  add_default_types if !root
46
61
  @clang = Clang::Clang.new
47
62
  end
48
63
 
49
- def parse(file_path,args = ["-xc++","-fno-rtti"])
64
+ def parse(file_path, args = ClangParser.default_arguments)
50
65
  tu = @clang.translation_unit(file_path,args)
51
66
  process(tu.cursor)
52
67
  self
@@ -78,7 +93,8 @@ module Rbind
78
93
  end
79
94
 
80
95
  # if rbind_type is given only pointer/ref or qualifier are applied
81
- def to_rbind_type(parent,cursor,rbind_type=nil,type_getter = :type,canonical = true)
96
+ def to_rbind_type(parent,cursor,rbind_type=nil,type_getter = :type,canonical = true, use_fallback = true)
97
+ ClangParser.log.debug "Parent: #{parent} --> cursor: #{cursor.expression}, spelling #{cursor.spelling}"
82
98
  clang_type = cursor.send(type_getter)
83
99
  return nil if clang_type.null?
84
100
  clang_type = clang_type.canonical_type if canonical
@@ -110,8 +126,13 @@ module Rbind
110
126
  end
111
127
  t = parent.type(name,!canonical)
112
128
  end
113
- # try again without canonical
114
- return to_rbind_type(parent,cursor,rbind_type,type_getter,false) if !t
129
+
130
+ # try again without canonical when type could not be found or type is template
131
+ if use_fallback
132
+ if !t || t.template?
133
+ return to_rbind_type(parent,cursor,rbind_type,type_getter,false, false)
134
+ end
135
+ end
115
136
 
116
137
  # add pointer level
117
138
  1.upto(level) do
@@ -133,74 +154,85 @@ module Rbind
133
154
  end
134
155
 
135
156
  # entry call to parse a file
136
- def process(cursor,parent = self)
137
- access = :public
157
+ def process(cursor, parent = self, access = :public)
138
158
  last_obj = nil
139
159
  cursor.visit_children(false) do |cu,cu_parent|
140
- # puts "----->#{cu.kind} #{cu.spelling} #{cu.type.kind} #{cu.specialized_template.kind}"
141
- last_obj = case cu.kind
142
- when :namespace
143
- process_namespace(cu,parent)
144
- when :enum_decl
145
- process_enum(cu,parent) if access == :public
146
- when :union_decl
147
- # puts "got union declaration #{cu.spelling}"
148
- when :struct_decl
149
- if access == :public
150
- process_class(cu,parent)
151
- end
152
- when :class_decl
153
- if access == :public
154
- access = :private
155
- klass = process_class(cu,parent)
156
- access = :public
157
- klass
158
- end
159
- when :function_decl
160
- process_function(cu,parent) if access == :public
161
- when :macro_expansion # CV_WRAP ...
162
- # puts "got macro #{cu.spelling} #{cu.location}"
163
- when :function_template
164
- # puts "got template fuction #{cu.spelling} #{cu.location}"
165
- when :class_template
166
- process_class_template(cu,parent)
167
- when :template_type_parameter
168
- # if !cu.spelling.empty?
169
- # parent.add_type(RTemplateParameter.new(cu.spelling))
170
- # else
171
- # ClangParser.log.info "no template parameter name"
172
- # end
173
- when :x_access_specifier
174
- access = normalize_accessor(cu.cxx_access_specifier)
175
- when :x_base_specifier
176
- local_access = normalize_accessor(cu.cxx_access_specifier)
177
- p = parent.type(RBase.normalize(cu.spelling),false)
178
- ClangParser.log.info "auto add parent class #{cu.spelling}" unless p
179
- p ||= parent.add_type(RClass.new(RBase.normalize(cu.spelling)))
180
- parent.add_parent p,local_access
181
- when :field_decl
182
- process_field(cu,parent) if cu.public? || access == :public
183
- when :constructor
184
- if access == :public
185
- f = process_function(cu,parent)
186
- f.return_type = nil if f
187
- f
188
- end
189
- when :x_method
190
- process_function(cu,parent) if access == :public
191
- when :typedef_decl
192
- # rename object if parent has no name
193
- if last_obj && last_obj.name =~ /no_name/
194
- ClangParser.log.info "rename #{last_obj.name} to #{cu.spelling}"
195
- last_obj.rename(cu.spelling)
196
- last_obj
160
+ ClangParser.log.debug "process ----->#{cu.kind} #{cu.spelling} #{cu.type.kind} #{cu.specialized_template.kind} ---> expr: #{cu.expression.join('|')} -- public: #{cu.public?} access: #{access}"
161
+ begin
162
+ last_obj = case cu.kind
163
+ when :namespace
164
+ process_namespace(cu,parent)
165
+ when :enum_decl
166
+ process_enum(cu,parent) if access == :public
167
+ when :union_decl
168
+ # puts "got union declaration #{cu.spelling}"
169
+ when :struct_decl
170
+ process_class(cu,parent,:public) if access == :public
171
+ when :class_decl
172
+ process_class(cu,parent, :private) if access == :public
173
+ when :function_decl
174
+ process_function(cu,parent) if access == :public
175
+ when :macro_expansion # CV_WRAP ...
176
+ # puts "got macro #{cu.spelling} #{cu.location}"
177
+ when :function_template
178
+ # puts "got template fuction #{cu.spelling} #{cu.location}"
179
+ when :class_template
180
+ process_class_template(cu,parent, access) if access == :public
181
+ when :template_type_parameter
182
+ if !cu.spelling.empty?
183
+ parent.add_type(RTemplateParameter.new(cu.spelling))
184
+ else
185
+ ClangParser.log.info "no template parameter name"
186
+ end
187
+ when :x_access_specifier
188
+ access = normalize_accessor(cu.cxx_access_specifier)
189
+ when :x_base_specifier
190
+ if access == :public
191
+ next
192
+ end
193
+ local_access = normalize_accessor(cu.cxx_access_specifier)
194
+ klass_name = cu.spelling
195
+ if cu.spelling =~ /\s?([^\s]+$)/
196
+ klass_name = $1
197
+ end
198
+ ClangParser.log.info "auto add parent class #{klass_name} if needed"
199
+ p = parent.type(RClass.new(RBase.normalize(klass_name)), true)
200
+ parent.add_parent p,local_access
201
+ when :field_decl
202
+ process_field(cu,parent) if access == :public
203
+ when :constructor
204
+ if access == :public
205
+ f = process_function(cu,parent)
206
+ f.return_type = nil if f
207
+ f
208
+ end
209
+ when :x_method
210
+ process_function(cu,parent) if access == :public
211
+ when :typedef_decl
212
+ if access != :public
213
+ next
214
+ end
215
+ # rename object if parent has no name
216
+ if last_obj && last_obj.respond_to?(:name) && last_obj.name =~ /no_name/
217
+ ClangParser.log.info "rename #{last_obj.name} to #{cu.spelling}"
218
+ last_obj.rename(cu.spelling)
219
+ last_obj
220
+ else
221
+ process_typedef(cu, parent)
222
+ end
223
+ when :var_decl
224
+ process_variable(cu,parent) if access == :public
225
+ when :unexposed_decl
226
+ process(cu) if access == :public
227
+ else
228
+ #puts "skip: #{cu.spelling}"
197
229
  end
198
- when :var_decl
199
- process_variable(cu,parent) if access == :public
200
- else
201
- #puts "skip: #{cu.spelling}"
202
- end
203
- raise ClangParserError.new("jjj",cu) if last_obj.is_a? Fixnum
230
+ rescue Exception => e
231
+ ClangParser.log.debug "Parsing failed -- skipping"
232
+ end
233
+ raise ClangParserError.new("jjj",cu) if last_obj.is_a? Fixnum
234
+
235
+
204
236
  end
205
237
  end
206
238
 
@@ -262,7 +294,7 @@ module Rbind
262
294
  a
263
295
  end
264
296
 
265
- def process_class_template(cursor,parent)
297
+ def process_class_template(cursor,parent,access)
266
298
  class_name = cursor.spelling
267
299
  ClangParser.log.info "processing class template #{parent}::#{class_name}"
268
300
 
@@ -275,11 +307,11 @@ module Rbind
275
307
  ClangParser.log.info " reopening existing class template #{klass}"
276
308
  klass
277
309
  end
278
- process(cursor,klass)
310
+ process(cursor,klass, access)
279
311
  klass
280
312
  end
281
313
 
282
- def process_class(cursor,parent)
314
+ def process_class(cursor,parent,access)
283
315
  class_name = cursor.spelling
284
316
  class_name = if class_name.empty?
285
317
  "no_name_class"
@@ -306,13 +338,13 @@ module Rbind
306
338
  ClangParser.log.info " skipping template #{name}"
307
339
  nil
308
340
  else
309
- ClangParser.log.warn " skipping non empty clas #{name}"
341
+ ClangParser.log.warn " skipping non empty class #{name}"
310
342
  #raise "Cannot reopening existing class #{klass} which is non-empty!"
311
343
  nil
312
344
  end
313
345
  end
314
346
  #klass.extern_package_name = nil
315
- process(cursor,klass) if klass
347
+ process(cursor,klass,access) if klass
316
348
  klass
317
349
  end
318
350
 
@@ -339,8 +371,10 @@ module Rbind
339
371
  # to prevent name clashes
340
372
  expression = cursor.expression.join()
341
373
  args.each_with_index do |arg,idx|
342
- if(!arg.default_value && (expression =~ /#{arg.name}=(\w*)/))
343
- arg.default_value = $1
374
+ if(!arg.default_value && (expression =~ /#{arg.name}(=\w*)?[,)]/))
375
+ if $1 and !$1.empty?
376
+ arg.default_value = $1.sub("=","")
377
+ end
344
378
  end
345
379
  arg.name = if(arg.name == "no_name_arg")
346
380
  arg.name + idx.to_s
@@ -368,6 +402,7 @@ module Rbind
368
402
 
369
403
  # type_getter is also used for :result_type
370
404
  def process_parameter(cursor,parent,type_getter = :type)
405
+ ClangParser.log.debug "process_parameter: spelling: '#{cursor.spelling}' type: '#{cursor.type}' kind '#{cursor.type.kind} parent #{parent}"
371
406
  para_name = cursor.spelling
372
407
  para_name = if para_name.empty?
373
408
  "no_name_arg"
@@ -380,6 +415,7 @@ module Rbind
380
415
  name_space = []
381
416
 
382
417
  cursor.visit_children do |cu,_|
418
+ ClangParser.log.info "process parameter: cursor kind: #{cu.kind} #{cu.expression}"
383
419
  case cu.kind
384
420
  when :integer_literal
385
421
  exp = cu.expression
@@ -412,6 +448,14 @@ module Rbind
412
448
  name_space << cu.spelling
413
449
  when :type_ref
414
450
  type_cursor = cu
451
+ when :compound_stmt
452
+ when :parm_decl
453
+ when :member_ref
454
+ when :constant_array
455
+ exp = cu.expression
456
+ exp.pop
457
+ default_value = exp.gsub("{","[")
458
+ default_value = default_value.gsub("}","]")
415
459
  end
416
460
  end
417
461
  type = if template_name.empty?
@@ -447,5 +491,33 @@ module Rbind
447
491
  rescue RuntimeError => e
448
492
  raise ClangParserError.new(e.to_s,cursor)
449
493
  end
494
+
495
+ def process_typedef(cu, parent)
496
+ ClangParser.log.debug "process_typedef: #{cu}: expression: #{cu.expression} parent: #{parent}"
497
+ exp = cu.expression.join(" ")
498
+
499
+ # Remove typedef label and extract orig type and alias
500
+ orig_and_alias = exp.sub("typedef","")
501
+ orig_and_alias = orig_and_alias.sub(";","").strip
502
+ orig_type = nil
503
+ alias_type = nil
504
+
505
+ if orig_and_alias =~ /(.*)\s+([^\s]+)/
506
+ orig_type = $1
507
+ alias_type = $2
508
+ else
509
+ raise RuntimeError,"Cannot parse typedef expression #{exp}"
510
+ end
511
+
512
+ begin
513
+ t = parent.type(orig_type)
514
+ ClangParser.log.debug "process_typedef: orig: '#{orig_type}' alias: #{alias_type}"
515
+ parent.add_type_alias(t, alias_type)
516
+ rescue RuntimeError => e
517
+ ClangParser.log.warn "Cannot process typedef expression for orig: '#{orig_type}' alias: '#{alias_type}' : #{e}"
518
+ end
519
+ parent
520
+ end
521
+
450
522
  end
451
523
  end
@@ -17,3 +17,4 @@ require 'rbind/core/rtype_qualifier.rb'
17
17
 
18
18
  require 'rbind/types/std_vector.rb'
19
19
  require 'rbind/types/std_string.rb'
20
+ require 'rbind/types/std_map.rb'
@@ -20,25 +20,17 @@ module Rbind
20
20
  name = normalize(name)
21
21
  cn = "#{cprefix}#{name.gsub("::","_")}"
22
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")
23
+ # Use alias instead of operator symbol for name
24
+ RNamespace.default_operator_alias.each do |op, alias_name|
25
+ cn = cn.gsub("operator#{op}","operator_#{alias_name}")
26
+ end
36
27
  end
37
28
  cn = cn.gsub("*","_ptr")
38
29
  cn = cn.gsub("&","_ref")
39
30
  cn = cn.gsub("<","_")
40
31
  cn = cn.gsub(">","")
41
32
  cn = cn.gsub(",","__")
33
+ cn
42
34
  end
43
35
 
44
36
  def normalize(name)
@@ -84,7 +84,7 @@ module Rbind
84
84
  []
85
85
  end
86
86
  other_ops.delete_if do |other_op|
87
- next true if !other_op
87
+ next true if !other_op || other_op.constructor?
88
88
  op = ops.find do |o|
89
89
  o == other_op
90
90
  end
@@ -26,7 +26,7 @@ module Rbind
26
26
  def cname(value=nil)
27
27
  if !value
28
28
  if basic_type? && !@cname
29
- name
29
+ full_name
30
30
  else
31
31
  super
32
32
  end
@@ -9,7 +9,7 @@ module Rbind
9
9
  end
10
10
 
11
11
  def generate_signatures
12
- ["#{full_name} = #{values}","const #{cname} = #{values}"]
12
+ ["#{full_name}","#{cname}"]
13
13
  end
14
14
 
15
15
  def basic_type?