forked from svaarala/duktape
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind_func_calls.py
80 lines (66 loc) · 2.09 KB
/
find_func_calls.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
#!/usr/bin/env python2
#
# Extract function call names from source C/H files.
#
# Useful for e.g. hunting non-Duktape library calls. Function calls can
# also be determined from object files, but some function calls are
# compilation option specific, so it's better to find them from source
# files.
#
# Example run:
#
# $ python util/find_func_calls.py src-input/*.c src-input/*.h | \
# grep -v -i -P ^duk_ | grep -v -P '^(sizeof|va_start|va_end|va_arg)' | \
# sort | uniq | less
#
import os
import sys
import re
re_linecont = re.compile(r'\\\n')
re_comment = re.compile(r'/\*.*?\*/', re.DOTALL)
re_func_call = re.compile(r'([A-Za-z_][A-Za-z0-9_]+)\(')
re_string = re.compile(r'"(\\"|[^"])*"')
def stripLineContinuations(x):
res = re.sub(re_linecont, ' ', x)
#print(res)
return res
def stripComments(x):
res = re.sub(re_comment, '/*omit*/', x)
#print(res)
return res
def stripStrings(x):
res = re.sub(re_string, '"..."', x)
#print(res)
return res
def findFuncCalls(d, fn):
res = []
for line in d.split('\n'):
if len(line) >= 1 and line[0] == '#':
# Preprocessor lines contain function call like
# syntax but are not function calls.
continue
for m in re_func_call.finditer(line):
res.append({
'name': m.group(1),
'filename': fn
})
return res
def main():
# Duktape code does not have a space between a function name and
# an open parenthesis. If the regexp includes an optional space,
# it will provide a lot of false matches.
for fn in sys.argv[1:]:
f = open(fn, 'rb')
d = f.read()
f.close()
# Strip line continuations, comments, and strings so that
# we minimize false matches.
d = stripLineContinuations(d)
d = stripComments(d)
d = stripStrings(d)
# Find function calls (close enough).
for i in findFuncCalls(d, fn):
#print '%s' % i['name']
print '%-25s%s' % (i['name'], i['filename'])
if __name__ == '__main__':
main()