CMS 3D CMS Logo

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