File indexing completed on 2024-12-01 23:40:44
0001
0002 import fileinput
0003 import networkx as nx
0004 import re
0005 datacl = re.compile("^class ")
0006 bfunc = re.compile("^function ")
0007 mbcl = re.compile("(base|data) class")
0008 farg = re.compile(r"(.*)\(\w+\)")
0009 nsep = re.compile(r"\:\:")
0010 topfunc = re.compile(
0011 r"::(produce|analyze|filter|beginLuminosityBlock|beginRun|beginStream)\(")
0012 baseclass = re.compile(
0013 r"edm::(one::|stream::|global::)?ED(Producer|Filter|Analyzer)(Base)?")
0014 getfunc = re.compile(
0015 r"edm::eventsetup::EventSetupRecord::get\<.*\>\((.*)&\) const")
0016 handle = re.compile("(.*),?class edm::ES(.*)Handle<(.*)>")
0017 skip = re.compile(
0018 "edm::serviceregistry::ServicesManager::MakerHolder::add() const")
0019 statics = set()
0020 toplevelfuncs = set()
0021 onefuncs = set()
0022 dataclassfuncs = set()
0023 virtfuncs = set()
0024 virtclasses = set()
0025 badfuncs = set()
0026 badclasses = set()
0027 esdclasses = set()
0028 dclasses = set()
0029 dataclasses = set()
0030 flaggedclasses = set()
0031 G = nx.DiGraph()
0032 H = nx.DiGraph()
0033
0034 f = open('classes.txt.dumperft')
0035 for line in f:
0036 if datacl.search(line):
0037 classname = line.split("'")[1]
0038 dclasses.add(classname)
0039 f.close()
0040
0041 f = open('classes.txt.inherits')
0042 for line in f:
0043 if datacl.search(line):
0044 classname = line.split("'")[1]
0045 dataclasses.add(classname)
0046 f.close()
0047
0048
0049 f = open('class-checker.txt')
0050 for line in f:
0051 if mbcl.search(line):
0052 fields = line.split("'")
0053 classname = fields[1]
0054 funcname = fields[3]
0055 badclasses.add(classname)
0056 badfuncs.add(funcname)
0057 f.close()
0058
0059
0060 f = open('classes.txt.dumperall')
0061 for line in f:
0062 if mbcl.search(line):
0063 fields = line.split("'")
0064 if fields[2] == ' member data class ':
0065 H.add_edge(fields[1], fields[3], kind=fields[2])
0066 if fields[2] == ' templated member data class ':
0067 H.add_edge(fields[1], fields[3], kind=fields[2])
0068 if fields[2] == ' base class ':
0069 H.add_edge(fields[1], fields[3], kind=fields[2])
0070 f.close()
0071
0072
0073 for line in fileinput.input(files=('function-statics-db.txt', 'function-calls-db.txt')):
0074 if not bfunc.search(line):
0075 continue
0076 fields = line.split("'")
0077 if skip.search(fields[1]) or skip.search(fields[3]):
0078 continue
0079 if fields[2] == ' calls function ':
0080 G.add_edge(fields[1], fields[3], kind=' calls function ')
0081 if getfunc.search(fields[3]):
0082 dataclassfuncs.add(fields[3])
0083 m = getfunc.match(fields[3])
0084 n = handle.match(m.group(1))
0085 if n:
0086 o = n.group(3)
0087 else:
0088 o = m.group(1)
0089 p = re.sub("class ", "", o)
0090 dataclass = re.sub("struct ", "", p)
0091 dataclasses.add(dataclass)
0092 if fields[2] == ' overrides function ':
0093 if baseclass.search(fields[3]):
0094 G.add_edge(fields[1], fields[3], kind=' overrides function ')
0095 if topfunc.search(fields[3]):
0096 toplevelfuncs.add(fields[1])
0097 else:
0098 G.add_edge(fields[3], fields[1], kind=' calls override function ')
0099 if fields[2] == ' static variable ':
0100 G.add_edge(fields[1], fields[3], kind=' static variable ')
0101 statics.add(fields[3])
0102 fileinput.close()
0103
0104 for n, nbrdict in G.adjacency():
0105 for nbr, eattr in nbrdict.items():
0106 if n in badfuncs or nbr in badfuncs:
0107 if 'kind' in eattr and eattr['kind'] == ' overrides function ':
0108 print("'"+n+"'"+eattr['kind']+"'"+nbr+"'")
0109 virtfuncs.add(nbr)
0110 print()
0111
0112 for n, nbrdict in H.adjacency():
0113 for nbr, eattr in nbrdict.items():
0114 if n in badclasses and 'kind' in eattr and eattr['kind'] == ' base class ':
0115 virtclasses.add(nbr)
0116
0117
0118 for n, nbrdict in H.adjacency():
0119 for nbr, eattr in nbrdict.items():
0120 if nbr in dclasses and 'kind' in eattr and eattr['kind'] == ' base class ':
0121 dclasses.add(n)
0122
0123 print("flagged functions found by checker")
0124 for dfunc in sorted(badfuncs):
0125 print(dfunc)
0126 print()
0127
0128 print("flagged classes found by checker ")
0129 for dclass in sorted(badclasses):
0130 print(dclass)
0131 print()
0132
0133 print("flagged classes found by checker union get")
0134 for dclass in sorted(dclasses.intersection(badclasses)):
0135 print(dclass)
0136 print()
0137
0138
0139 print("classes inheriting from flagged classes")
0140 for dclass in sorted(virtclasses):
0141 print(dclass)
0142 print()
0143
0144 print("functions overridden by flagged functions")
0145 for dfunc in sorted(virtfuncs):
0146 print(dfunc)
0147 print()
0148
0149
0150 for badclass in sorted(badclasses):
0151 print("Event setup data class '"+badclass+"' is flagged.")
0152 flaggedclasses.add(badclass)
0153 print()
0154
0155 for virtclass in sorted(virtclasses):
0156 print("Event setup data class '"+virtclass +
0157 "' is flagged because inheriting class is flagged")
0158 flaggedclasses.add(virtclass)
0159 print()
0160
0161 for badclass in sorted(badclasses):
0162 for dataclass in sorted(dataclasses):
0163 if H.has_node(badclass) and H.has_node(dataclass):
0164 if nx.has_path(H, dataclass, badclass):
0165 print("Event setup data class '" + dataclass +
0166 "' contains or inherits from flagged class '" + badclass + "'.")
0167 flaggedclasses.add(dataclass)
0168
0169 print()
0170
0171
0172 for dataclassfunc in sorted(dataclassfuncs):
0173 for tfunc in sorted(toplevelfuncs):
0174 if G.has_node(tfunc) and G.has_node(dataclassfunc) and nx.has_path(G, tfunc, dataclassfunc):
0175 m = getfunc.match(dataclassfunc)
0176 n = handle.match(m.group(1))
0177 if n:
0178 o = n.group(3)
0179 else:
0180 o = m.group(1)
0181 p = re.sub("class ", "", o)
0182 q = re.sub("struct ", "", p)
0183 dataclass = re.sub(r"\<.*\> ", "", q)
0184 for flaggedclass in sorted(flaggedclasses):
0185 exact = r"^" + re.escape(flaggedclass) + r"$"
0186 exactmatch = re.match(exact, dataclass)
0187 if exactmatch:
0188 print("Flagged event setup data class '"+dataclass +
0189 "' is accessed in call stack '", end=' ')
0190 path = nx.shortest_path(G, tfunc, dataclassfunc)
0191 for p in path:
0192 print(p+"; ", end=' ')
0193 print("' ", end=' ')
0194 for key in G[tfunc].keys():
0195 if 'kind' in G[tfunc][key] and G[tfunc][key]['kind'] == ' overrides function ':
0196 print("'"+tfunc+"'"+G[tfunc][key]
0197 ['kind']+"'"+key+"'", end=' ')
0198 print("")
0199 print("In call stack '", end=' ')
0200 path = nx.shortest_path(G, tfunc, dataclassfunc)
0201 for p in path:
0202 print(p+"; ", end=' ')
0203 print("' flagged event setup data class '" +
0204 dataclass+"' is accessed. ", end=' ')
0205 for key in G[tfunc].keys():
0206 if 'kind' in G[tfunc][key] and G[tfunc][key]['kind'] == ' overrides function ':
0207 print("'"+tfunc+"'"+G[tfunc][key]
0208 ['kind']+"'"+key+"'", end=' ')
0209 print("")