root/software/misc/preproc.py @ ffb481f4
| 04cc161c | David Sorber | import sys
|
|
from clang.cindex import Config
|
|||
from clang.cindex import CursorKind
|
|||
from clang.cindex import Index
|
|||
from clang.cindex import TranslationUnit
|
|||
# Set these according to the location and version of libclang on your system
|
|||
LIBCLANG_PATH = '/usr/lib/llvm-3.4/lib'
|
|||
LIBCLANG_NAME = 'libclang-3.4.so'
|
|||
def display_node(node):
|
|||
""" A helper function to pretty print the particulars of the passed in
|
|||
Cursor object
|
|||
"""
|
|||
start_line = node.extent.start.line
|
|||
start_col = node.extent.start.column
|
|||
end_line = node.extent.end.line
|
|||
end_col = node.extent.end.column
|
|||
print '{:s} ({:d}:{:d} - {:d}:{:d})'.format(node.displayname,
|
|||
start_line, start_col,
|
|||
end_line, end_col)
|
|||
def find_function_calls(node):
|
|||
""" A recursive function call to find all function calls that are children
|
|||
of the passed in Cursor object
|
|||
"""
|
|||
results = []
|
|||
for child_node in node.get_children():
|
|||
if child_node.kind == CursorKind.CALL_EXPR:
|
|||
results.append(child_node)
|
|||
else:
|
|||
results.extend(find_function_calls(child_node))
|
|||
return results
|
|||
def main():
|
|||
""" This is a very simple utility that uses the Clang compiler frontend
|
|||
to parse a C source file and return a list of function declarations within
|
|||
that file along with the lines on which each declaration starts and ends.
|
|||
"""
|
|||
if len(sys.argv) < 2:
|
|||
print 'ERROR: not enough arguments provided\n'
|
|||
print 'USAGE: python ddc_preproc.py <file.c>'
|
|||
return -1
|
|||
# Configure the library (not sure why this has to be done manually)
|
|||
Config.set_library_path(LIBCLANG_PATH)
|
|||
Config.set_library_file(LIBCLANG_NAME)
|
|||
# Build the TU from the passed file argument
|
|||
source_file = sys.argv[1]
|
|||
tu = TranslationUnit.from_source(source_file)
|
|||
# Loop through all of the children nodes and extract function definitions
|
|||
# along with their start and end lines from the specified source file
|
|||
print 'Function declarations:'
|
|||
print '-' * 80
|
|||
main_func = None
|
|||
for child in tu.cursor.get_children():
|
|||
if str(child.location.file) == source_file and \
|
|||
child.kind == CursorKind.FUNCTION_DECL:
|
|||
# Store a reference to the main function
|
|||
if child.spelling == 'main':
|
|||
main_func = child
|
|||
display_node(child)
|
|||
print '\n'
|
|||
# Find all function calls originating from the main function
|
|||
print 'Function calls:'
|
|||
print '-' * 80
|
|||
for child in find_function_calls(main_func):
|
|||
display_node(child)
|
|||
if __name__ == '__main__':
|
|||
sys.exit(main())
|