|
@ -7,23 +7,50 @@ |
|
|
# compilation option specific, so it's better to find them from source |
|
|
# compilation option specific, so it's better to find them from source |
|
|
# files. |
|
|
# files. |
|
|
# |
|
|
# |
|
|
|
|
|
# Example run: |
|
|
|
|
|
# |
|
|
|
|
|
# $ python util/find_func_calls.py src/*.c src/*.h | \ |
|
|
|
|
|
# grep -v -i -P ^duk_ | grep -v -P '^(sizeof|va_start|va_end|va_arg)' | \ |
|
|
|
|
|
# sort | uniq | less |
|
|
|
|
|
# |
|
|
|
|
|
|
|
|
import os |
|
|
import os |
|
|
import sys |
|
|
import sys |
|
|
import re |
|
|
import re |
|
|
|
|
|
|
|
|
|
|
|
re_linecont = re.compile(r'\\\n') |
|
|
re_comment = re.compile(r'/\*.*?\*/', re.DOTALL) |
|
|
re_comment = re.compile(r'/\*.*?\*/', re.DOTALL) |
|
|
re_func_call = re.compile(r'([A-Za-z_][A-Za-z0-9_]+)\(', re.MULTILINE) |
|
|
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(d): |
|
|
def stripComments(x): |
|
|
res = re.sub(re_comment, '/*omit*/', d) |
|
|
res = re.sub(re_comment, '/*omit*/', x) |
|
|
#print(res) |
|
|
#print(res) |
|
|
return res |
|
|
return res |
|
|
|
|
|
|
|
|
def findFuncCalls(d): |
|
|
def stripStrings(x): |
|
|
|
|
|
res = re.sub(re_string, '"..."', x) |
|
|
|
|
|
#print(res) |
|
|
|
|
|
return res |
|
|
|
|
|
|
|
|
|
|
|
def findFuncCalls(d, fn): |
|
|
res = [] |
|
|
res = [] |
|
|
for m in re_func_call.finditer(d): |
|
|
for line in d.split('\n'): |
|
|
res.append(m.group(1)) |
|
|
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 |
|
|
return res |
|
|
|
|
|
|
|
|
def main(): |
|
|
def main(): |
|
@ -36,14 +63,18 @@ def main(): |
|
|
d = f.read() |
|
|
d = f.read() |
|
|
f.close() |
|
|
f.close() |
|
|
|
|
|
|
|
|
# Strip block comments. |
|
|
# Strip line continuations, comments, and strings so that |
|
|
|
|
|
# we minimize false matches. |
|
|
|
|
|
|
|
|
|
|
|
d = stripLineContinuations(d) |
|
|
d = stripComments(d) |
|
|
d = stripComments(d) |
|
|
|
|
|
d = stripStrings(d) |
|
|
|
|
|
|
|
|
# Find function calls (close enough). |
|
|
# Find function calls (close enough). |
|
|
|
|
|
|
|
|
for i in findFuncCalls(d): |
|
|
for i in findFuncCalls(d, fn): |
|
|
print(i) |
|
|
#print '%s' % i['name'] |
|
|
|
|
|
print '%-25s%s' % (i['name'], i['filename']) |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
if __name__ == '__main__': |
|
|
main() |
|
|
main() |
|
|