class ParseC::SourceFile
Source file contains C-function definitions and header file inclusions.
Attributes
name[R]
File name.
Public Class Methods
new( name, headerPath )
click to toggle source
Set file to parse and path for header search. Finally, perform parsing for the file.
# File lib/parsec.rb, line 48 def initialize( name, headerPath ) @name = name @headerPath = headerPath @localHeader = {} @funcdefs = {} @funcalls = {} @conf = {} @conf[ :defsonly ] = false @conf[ :mainonly ] = false end
parseLocalDefs( name, headerPath )
click to toggle source
# File lib/parsec.rb, line 37 def SourceFile.parseLocalDefs( name, headerPath ) file = SourceFile.new( name, headerPath ) file.conf( :defsonly, true ) file.conf( :mainonly, true ) file.parse file end
Public Instance Methods
conf( opt, value = nil )
click to toggle source
# File lib/parsec.rb, line 62 def conf( opt, value = nil ) if value @conf[ opt ] = value else @conf[ opt ] end end
display()
click to toggle source
Display c-file content.
# File lib/parsec.rb, line 190 def display puts "File: #{@name}" puts " Includes:" @localHeader.each_value do |i| puts " #{i.name} | #{i.path}" end puts " Functions:" @funcdefs.each_value do |f| puts " #{f.declaration}" end end
dump( headerPath = @headerPath )
click to toggle source
Show raw content of c-file.
# File lib/parsec.rb, line 204 def dump( headerPath = @headerPath ) index = FFI::Clang::Index.new translation_unit = index.parse_translation_unit( @name, headerPath ) cursor = translation_unit.cursor cursor.visit_children do |cursor, parent| puts "#{cursor.kind} #{cursor.spelling}" next :recurse end end
funcalls()
click to toggle source
# File lib/parsec.rb, line 90 def funcalls @funcalls end
funcdefs()
click to toggle source
Return list of defined functions. Can be used e.g. to generate function declarations to a header file (automatically).
@return [Array<HeaderFile>] Functions.
# File lib/parsec.rb, line 85 def funcdefs @funcdefs end
headers()
click to toggle source
Return list of included (local) header files. Can be used e.g. for c-to-h file dependence.
@return [Array<HeaderFile>] Headers.
# File lib/parsec.rb, line 75 def headers @localHeader end
isLocalHeader?( file )
click to toggle source
Return true if file name is for a local header.
# File lib/parsec.rb, line 96 def isLocalHeader?( file ) if file[0] != '/' && /\.h$/.match( file ) true else false end end
parse( headerPath = @headerPath )
click to toggle source
Parse c-file.
@param headerPath [String] Path for system header lookup.
# File lib/parsec.rb, line 108 def parse( headerPath = @headerPath ) index = FFI::Clang::Index.new translation_unit = index.parse_translation_unit( @name, headerPath ) cursor = translation_unit.cursor # Get list of included local headers. translation_unit.inclusions do |header| if isLocalHeader? header @localHeader[ header ] = HeaderFile.new( header ) end end # Recursively travel the c-file hierarchy to detect # function definitions. cursor.visit_children do |cursor, parent| if cursor.kind == :cursor_function # Check that function is in the file that is being # analysed. Might also be from an included header. if ( @conf[:mainonly] == false ) || cursor.location.from_main_file? f = Function.new( cursor.spelling, cursor.variadic? ) f.setReturnType( cursor.result_type.spelling ) # Get argument list. cursor.visit_children do |cursor, parent| case cursor.kind when :cursor_parm_decl f.addArgument( cursor.spelling, cursor.type.spelling ) else # puts cursor.kind true end next :continue end # Mark function complete and add to list. @funcdefs[ f.name ] = f.done if @conf[:defsonly] # Don't recurse anymore. next :continue else next :recurse end else next :continue end elsif cursor.kind == :cursor_call_expr # if cursor.location.from_main_file? f = FunCall.new( cursor.spelling ) @funcalls[ f.name ] = f # end next :recurse else # Non-functions are not interesting. next :recurse end end end