1#!/usr/bin/env python3 2import os 3import re 4from collections import defaultdict 5 6path = "./src/ts/" 7 8 9# 10# Build a list of files in src/ by list comprehension. Fortran-stuff is ignored 11# 12print("Stage 1: Building function dictionary from source files in " + path); 13 14sourcefiles = [os.path.join(root, name) 15 for root, dirs, files in os.walk(path) 16 for name in files 17 if name.endswith((".c", ".h")) and root.find("ftn-custom") < 0 and root.find("examples") < 0] 18 19# 20# Iterate over all source files and collect function names in dictionary (key-type: function name, value-type: filename where function is defined) 21# 22 23print("Stage 2: Building function dictionary...") 24function_dict = defaultdict(set); 25 26for file in sourcefiles: 27 f = open(file, "r"); 28 for line in f.readlines(): 29 m = re.match('^PetscErrorCode\s*([^\s]*)\(', line) 30 if m: 31 function_dict[m.group(1)] = file; 32 else: 33 m = re.match(' void\s*([^\s]*)\(', line) 34 if m: 35 function_dict[m.group(1)] = file; 36 37# 38# Consistency check: There might be function names used multiple times. 39# 40 41# TODO 42 43 44 45 46 47# 48# Iterate over all source files and scan for the use of any of the registered functions 49# 50 51print("Stage 3: Building function calling dictionary (this might take a while)...") 52function_calling_dict = defaultdict(set); # Dictionary which records all calls to a function 53 54for file in sourcefiles: 55 f = open(file, "r"); 56 for line in f.readlines(): 57 if line.find(".seealso") >= 0: 58 continue; 59 60 for funcname in function_dict.keys(): 61 if line.find(' ' + funcname + '(') >= 0 or line.find("=" + funcname + '(') >= 0: #Note: Might not have perfect accuracy, but is much faster than regular expressions. 62 function_calling_dict[funcname].add(file); 63# print line; 64 65 66# 67# Now extract all functions which are only used in one file 68# 69 70static_functions_for_file = defaultdict(list); 71 72for func in function_calling_dict.keys(): 73 if len(function_calling_dict[func]) < 2: 74 static_functions_for_file[function_calling_dict[func].pop()].append(func); 75 76 77# 78# Output 'static' functions per file: 79# 80 81print("#") 82print("# Functions only used in one file:") 83print("#") 84 85for filename in static_functions_for_file.keys(): 86 print(filename + ": "); 87 for func in static_functions_for_file[filename]: 88 print(" " + func); 89 90# print func + ": " + str(len(function_calling_dict[func])) + " uses"; 91 92 93 94 95#print "Function dictionary:" 96#print function_dict; 97 98#print "Function-calling dictionary:" 99#print function_calling_dict; 100 101