Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:31:49

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