-
Notifications
You must be signed in to change notification settings - Fork 0
/
cpp_func_def.py
executable file
·97 lines (83 loc) · 3.92 KB
/
cpp_func_def.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python3
import sys
import argparse
import clang.cindex
from clang.cindex import Index
from clang.cindex import Config
class ClangFuncRangeParser:
def __init__(self, filepath):
self.filepath = filepath
self.index = Index.create()
# NOTE: for avoid search extra include files
# NOTE: Maybe, system-header-prefix is not needed?
# NOTE: If you want to see the help of clang index parser, add '--help' options to below list
# args = ['-nobuiltininc', '-nostdinc++', '--system-header-prefix=".*"']
args = ['-nobuiltininc']
self.tu = self.index.parse("", [filepath, *args])
if not self.tu:
parser.error("unable to load input")
def print_func_decl_range_all(self):
def _lambda(node):
if (node.kind.name == 'FUNCTION_DECL'):
if (str(node.extent.start.file) == self.filepath):
print("file : %s" % node.extent.start.file)
print("function : %s" % node.displayname)
print(" from line:%s column:%s" % (node.extent.start.line, node.extent.start.column))
print(" to line:%s column:%s" % (node.extent.end.line, node.extent.end.column))
return True
self.traverse(_lambda)
def print_func_range_all(self):
def _lambda(node):
if (any(node.kind.name in s for s in ['FUNCTION_DECL', 'CONSTRUCTOR', 'CXX_METHOD', 'FUNCTION_TEMPLATE'])):
if (str(node.extent.start.file) == self.filepath):
print("file : %s" % node.extent.start.file)
print("function : %s" % node.displayname)
print(" from line:%s column:%s" % (node.extent.start.line, node.extent.start.column))
print(" to line:%s column:%s" % (node.extent.end.line, node.extent.end.column))
return True
self.traverse(_lambda)
def print_func_range(self, line):
found_flag = False
def _lambda(node):
nonlocal found_flag
if (any(node.kind.name in s for s in ['FUNCTION_DECL', 'CONSTRUCTOR', 'CXX_METHOD', 'FUNCTION_TEMPLATE'])):
if (str(node.extent.start.file) == self.filepath):
if (node.extent.start.line <= line and line <= node.extent.end.line):
print("%s %s" % (node.extent.start.line, node.extent.end.line))
found_flag = True
return False
return True
self.traverse(_lambda)
return found_flag
def print_all(self):
def _lambda(node):
if (True or str(node.extent.start.file) == self.filepath):
print("file : %s" % node.extent.start.file)
print("kind : %s" % node.kind.name)
print("function : %s" % node.displayname)
print(" from line:%s column:%s" % (node.extent.start.line, node.extent.start.column))
print(" to line:%s column:%s" % (node.extent.end.line, node.extent.end.column))
return True
self.traverse(_lambda)
def traverse(self, f):
self.traverse_body(self.tu.cursor, f)
def traverse_body(self, node, f):
ret = f(node)
if not ret:
return
for child in node.get_children():
ret = self.traverse_body(child, f)
if not ret:
break
return ret
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-l', '--line', required=True, type=int)
parser.add_argument('filepath')
args, extra_args = parser.parse_known_args()
clang_func_range_parser = ClangFuncRangeParser(args.filepath)
# clang_func_range_parser.print_all()
# clang_func_range_parser.print_func_range_all()
# clang_func_range_parser.print_func_decl_range_all()
found_flag = clang_func_range_parser.print_func_range(args.line)
sys.exit(0 if found_flag else 1)