CMS 3D CMS Logo

data-class-funcs.py
Go to the documentation of this file.
1 #! /usr/bin/env python3
2 from __future__ import print_function
3 import fileinput
4 import networkx as nx
5 import re
6 datacl = re.compile("^class ")
7 bfunc = re.compile("^function ")
8 mbcl = re.compile("(base|data) class")
9 farg = re.compile(r"(.*)\(\w+\)")
10 nsep = re.compile(r"\:\:")
11 topfunc = re.compile(
12  r"::(produce|analyze|filter|beginLuminosityBlock|beginRun|beginStream)\(")
13 baseclass = re.compile(
14  r"edm::(one::|stream::|global::)?ED(Producer|Filter|Analyzer)(Base)?")
15 getfunc = re.compile(
16  r"edm::eventsetup::EventSetupRecord::get<.*>\((.*)&\) const")
17 handle = re.compile("(.*),?class edm::ES(.*)Handle<(.*)>")
18 skip = re.compile(
19  "edm::serviceregistry::ServicesManager::MakerHolder::add() const")
20 statics = set()
21 toplevelfuncs = set()
22 onefuncs = set()
23 dataclassfuncs = set()
24 virtfuncs = set()
25 virtclasses = set()
26 badfuncs = set()
27 badclasses = set()
28 esdclasses = set()
29 dclasses = set()
30 dataclasses = set()
31 flaggedclasses = set()
32 G = nx.DiGraph()
33 H = nx.DiGraph()
34 
35 f = open('classes.txt.dumperft')
36 for line in f:
37  if datacl.search(line):
38  classname = line.split("'")[1]
39  dclasses.add(classname)
40 f.close()
41 
42 f = open('classes.txt.inherits')
43 for line in f:
44  if datacl.search(line):
45  classname = line.split("'")[1]
46  dataclasses.add(classname)
47 f.close()
48 
49 
50 f = open('class-checker.txt')
51 for line in f:
52  if mbcl.search(line):
53  fields = line.split("'")
54  classname = fields[1]
55  funcname = fields[3]
56  badclasses.add(classname)
57  badfuncs.add(funcname)
58 f.close()
59 
60 
61 f = open('classes.txt.dumperall')
62 for line in f:
63  if mbcl.search(line):
64  fields = line.split("'")
65  if fields[2] == ' member data class ':
66  H.add_edge(fields[1], fields[3], kind=fields[2])
67  if fields[2] == ' templated member data class ':
68  H.add_edge(fields[1], fields[3], kind=fields[2])
69  if fields[2] == ' base class ':
70  H.add_edge(fields[1], fields[3], kind=fields[2])
71 f.close()
72 
73 
74 for line in fileinput.input(files=('function-statics-db.txt', 'function-calls-db.txt')):
75  if not bfunc.search(line):
76  continue
77  fields = line.split("'")
78  if skip.search(fields[1]) or skip.search(fields[3]):
79  continue
80  if fields[2] == ' calls function ':
81  G.add_edge(fields[1], fields[3], kind=' calls function ')
82  if getfunc.search(fields[3]):
83  dataclassfuncs.add(fields[3])
84  m = getfunc.match(fields[3])
85  n = handle.match(m.group(1))
86  if n:
87  o = n.group(3)
88  else:
89  o = m.group(1)
90  p = re.sub("class ", "", o)
91  dataclass = re.sub("struct ", "", p)
92  dataclasses.add(dataclass)
93  if fields[2] == ' overrides function ':
94  if baseclass.search(fields[3]):
95  G.add_edge(fields[1], fields[3], kind=' overrides function ')
96  if topfunc.search(fields[3]):
97  toplevelfuncs.add(fields[1])
98  else:
99  G.add_edge(fields[3], fields[1], kind=' calls override function ')
100  if fields[2] == ' static variable ':
101  G.add_edge(fields[1], fields[3], kind=' static variable ')
102  statics.add(fields[3])
103 fileinput.close()
104 
105 for n, nbrdict in G.adjacency():
106  for nbr, eattr in nbrdict.items():
107  if n in badfuncs or nbr in badfuncs:
108  if 'kind' in eattr and eattr['kind'] == ' overrides function ':
109  print("'"+n+"'"+eattr['kind']+"'"+nbr+"'")
110  virtfuncs.add(nbr)
111 print()
112 
113 for n, nbrdict in H.adjacency():
114  for nbr, eattr in nbrdict.items():
115  if n in badclasses and 'kind' in eattr and eattr['kind'] == ' base class ':
116  virtclasses.add(nbr)
117 
118 
119 for n, nbrdict in H.adjacency():
120  for nbr, eattr in nbrdict.items():
121  if nbr in dclasses and 'kind' in eattr and eattr['kind'] == ' base class ':
122  dclasses.add(n)
123 
124 print("flagged functions found by checker")
125 for dfunc in sorted(badfuncs):
126  print(dfunc)
127 print()
128 
129 print("flagged classes found by checker ")
130 for dclass in sorted(badclasses):
131  print(dclass)
132 print()
133 
134 print("flagged classes found by checker union get")
135 for dclass in sorted(dclasses.intersection(badclasses)):
136  print(dclass)
137 print()
138 
139 
140 print("classes inheriting from flagged classes")
141 for dclass in sorted(virtclasses):
142  print(dclass)
143 print()
144 
145 print("functions overridden by flagged functions")
146 for dfunc in sorted(virtfuncs):
147  print(dfunc)
148 print()
149 
150 
151 for badclass in sorted(badclasses):
152  print("Event setup data class '"+badclass+"' is flagged.")
153  flaggedclasses.add(badclass)
154 print()
155 
156 for virtclass in sorted(virtclasses):
157  print("Event setup data class '"+virtclass +
158  "' is flagged because inheriting class is flagged")
159  flaggedclasses.add(virtclass)
160 print()
161 
162 for badclass in sorted(badclasses):
163  for dataclass in sorted(dataclasses):
164  if H.has_node(badclass) and H.has_node(dataclass):
165  if nx.has_path(H, dataclass, badclass):
166  print("Event setup data class '" + dataclass +
167  "' contains or inherits from flagged class '" + badclass + "'.")
168  flaggedclasses.add(dataclass)
169 
170 print()
171 
172 
173 for dataclassfunc in sorted(dataclassfuncs):
174  for tfunc in sorted(toplevelfuncs):
175  if G.has_node(tfunc) and G.has_node(dataclassfunc) and nx.has_path(G, tfunc, dataclassfunc):
176  m = getfunc.match(dataclassfunc)
177  n = handle.match(m.group(1))
178  if n:
179  o = n.group(3)
180  else:
181  o = m.group(1)
182  p = re.sub("class ", "", o)
183  q = re.sub("struct ", "", p)
184  dataclass = re.sub(r"<.*> ", "", q)
185  for flaggedclass in sorted(flaggedclasses):
186  exact = r"^" + re.escape(flaggedclass) + r"$"
187  exactmatch = re.match(exact, dataclass)
188  if exactmatch:
189  print("Flagged event setup data class '"+dataclass +
190  "' is accessed in call stack '", end=' ')
191  path = nx.shortest_path(G, tfunc, dataclassfunc)
192  for p in path:
193  print(p+"; ", end=' ')
194  print("' ", end=' ')
195  for key in G[tfunc].keys():
196  if 'kind' in G[tfunc][key] and G[tfunc][key]['kind'] == ' overrides function ':
197  print("'"+tfunc+"'"+G[tfunc][key]
198  ['kind']+"'"+key+"'", end=' ')
199  print("")
200  print("In call stack '", end=' ')
201  path = nx.shortest_path(G, tfunc, dataclassfunc)
202  for p in path:
203  print(p+"; ", end=' ')
204  print("' flagged event setup data class '" +
205  dataclass+"' is accessed. ", end=' ')
206  for key in G[tfunc].keys():
207  if 'kind' in G[tfunc][key] and G[tfunc][key]['kind'] == ' overrides function ':
208  print("'"+tfunc+"'"+G[tfunc][key]
209  ['kind']+"'"+key+"'", end=' ')
210  print("")
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47