Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-01 23:40:44

0001 #! /usr/bin/env python3
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("")