Guest User

Untitled

a guest
Jul 18th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.88 KB | None | 0 0
  1. require 'rubygems'
  2. require 'ffi'
  3.  
  4. module Clang
  5. module Lib
  6. extend FFI::Library
  7.  
  8. ffi_lib "clang"
  9.  
  10. attach_function :create_index, :clang_createIndex, [:int, :int], :pointer
  11. attach_function :dispose_index, :clang_disposeIndex, [:pointer], :void
  12. attach_function :parse_translation_unit, :clang_parseTranslationUnit, [:pointer, :string, :pointer, :int, :pointer, :uint, :uint], :pointer
  13. attach_function :dispose_translation_unit, :clang_disposeTranslationUnit, [:pointer], :void
  14. attach_function :get_num_diagnostics, :clang_getNumDiagnostics, [:pointer], :uint
  15. attach_function :get_diagnostic, :clang_getDiagnostic, [:pointer, :uint], :pointer
  16. attach_function :dispose_diagnostic, :clang_disposeDiagnostic, [:pointer], :void
  17. attach_function :format_diagnostic, :clang_formatDiagnostic, [:pointer, :uint], :pointer
  18. attach_function :default_diagnostic_display_options, :clang_defaultDiagnosticDisplayOptions, [], :uint
  19. attach_function :get_c_string, :clang_getCString, [:pointer], :string
  20. attach_function :dispose_string, :clang_disposeString, [:pointer], :void
  21. attach_function :get_diagnostic_location, :clang_getDiagnosticLocation, [:pointer], :pointer
  22. attach_function :equal_locations, :clang_equalLocations, [:pointer, :pointer], :uint
  23. end
  24.  
  25. class TranslationUnit
  26. def initialize(ptr)
  27. @ptr = FFI::AutoPointer.new(ptr, Lib.method(:dispose_translation_unit))
  28. end
  29.  
  30. def diagnostics
  31. n = Lib.get_num_diagnostics(@ptr)
  32. 0.upto(n - 1).map do |idx|
  33. Diagnostic.new(Lib.get_diagnostic(@ptr, idx))
  34. end
  35. end
  36. end
  37.  
  38. class Diagnostic
  39. def initialize(ptr)
  40. @ptr = FFI::AutoPointer.new(ptr, Lib.method(:dispose_diagnostic))
  41. end
  42.  
  43. def format(opts = {})
  44. raise NotImplementedError, "#{self.class}#format options" unless opts.empty?
  45.  
  46. cxstring = Lib.format_diagnostic(@ptr, Lib.default_diagnostic_display_options)
  47. result = Lib.get_c_string(cxstring)
  48. Lib.dispose_string(cxstring)
  49.  
  50. result
  51. end
  52.  
  53. def severity
  54. raise NotImplementedError
  55. end
  56.  
  57. def source_location
  58. SourceLocation.new(Lib.get_diagnostic_location(@ptr))
  59. end
  60.  
  61. def fixits
  62. raise NotImplementedError
  63. # unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag);
  64. # – CXString clang_getDiagnosticFixIt(CXDiagnostic Diag,
  65. # unsigned FixIt,
  66. # CXSourceRange *ReplacementRange);
  67.  
  68. end
  69.  
  70. def spelling
  71. raise NotImplementedError
  72. end
  73. end
  74.  
  75. class SourceLocation
  76. def initialize(ptr)
  77. # no release? should we keep a reference to TU / diagnostic?
  78. @ptr = ptr
  79. end
  80.  
  81. def ==(other)
  82. return unless other.kind_of? self.class
  83. Lib.equal_locations(@ptr, other.ptr) != 0
  84. end
  85.  
  86. alias_method :eql?, :==
  87.  
  88. protected
  89.  
  90. def ptr
  91. @ptr
  92. end
  93. end
  94.  
  95. class Index
  96. def initialize(opts = {})
  97. exclude_declarations_from_pch = opts[:exclude_declarations_from_pch] ? 1 : 0
  98. display_diagnostics = opts[:display_diagnostics] ? 1 : 0
  99.  
  100. @ptr = FFI::AutoPointer.new Lib.create_index(exclude_declarations_from_pch, display_diagnostics),
  101. Lib.method(:dispose_index)
  102.  
  103. end
  104.  
  105. def parse_translation_unit(source_file, command_line_args = nil, opts = {})
  106. command_line_args = Array(command_line_args)
  107. args_pointer = FFI::MemoryPointer.new(:pointer)
  108. strings = command_line_args.map do |arg|
  109. FFI::MemoryPointer.from_string(arg.to_s)
  110. end
  111.  
  112. args_pointer.put_array_of_pointer(strings) unless strings.empty?
  113.  
  114. raise NotImplementedError, "options for #{self.class}#parse_translation_unit" unless opts.empty?
  115. tu = Lib.parse_translation_unit(@ptr, source_file, args_pointer, command_line_args.size, nil, 0, 0)
  116.  
  117. raise "error parsing #{source_file.inspect}" if tu.nil? || tu.null?
  118.  
  119. TranslationUnit.new tu
  120. end
  121. end
  122.  
  123.  
  124. end
Add Comment
Please, Sign In to add comment