xref: /petsc/lib/petsc/bin/maint/PetscStaticFunctionCandidates.py (revision f14a7c29b82d1117d8e3de344377442be395a55f)
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