CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
duplicateReflexLibrarySearch.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 import optparse
4 import os
5 import commands
6 import re
7 import sys
8 import pprint
9 import commands
10 import subprocess
11 from XML2Python import xml2obj
12 
13 # These aren't all typedefs, but can sometimes make the output more
14 # readable
15 typedefsDict = \
16  {
17  # What we want <= What we have
18  'unsigned int' : ['unsignedint', 'UInt32_t', 'uint32_t'],
19  'unsigned long': ['unsignedlong'],
20  'int' : ['Int32_t'],
21  'float' : ['Float_t'],
22  'double' : ['Double_t'],
23  'char' : ['Char_t'],
24  '< ' : ['<', '&lt;'],
25  ' >' : ['>', '&gt;'],
26  ', ' : [','],
27  }
28 
29 
30 # Equivalent names for packages - lets script know that, for example,
31 # 'TrackReco' package should have objects 'reco::Track'.
32 #Ordered List to search for matched packages
33 equivDict = \
34  [
35  {'L1TCalorimeter' : ['l1t::CaloTower.*']},
36  {'GsfTracking' : ['reco::GsfTrack(Collection|).*(MomentumConstraint|VertexConstraint)', 'Trajectory.*reco::GsfTrack']},
37  {'ParallelAnalysis' : ['examples::TrackAnalysisAlgorithm']},
38  {'PatCandidates' : ['pat::PATObject','pat::Lepton']},
39  {'BTauReco' : ['reco::SoftLeptonProperties','reco::SecondaryVertexTagInfo','reco::IPTagInfo','reco::TemplatedSecondaryVertexTagInfo']},
40  {'CastorReco' : ['reco::CastorJet']},
41  {'JetMatching' : ['reco::JetFlavourInfo', 'reco::JetFlavour','reco::MatchedPartons']},
42  {'TrackingAnalysis' : ['TrackingParticle']},
43  {'Egamma' : ['reco::ElectronID']},
44  {'TopObjects' : ['reco::CATopJetProperties']},
45  {'TauReco' : ['reco::L2TauIsolationInfo','reco::RecoTauPiZero','reco::BaseTau']},
46  {'ValidationFormats' : ['PGlobalDigi::.+','PGlobalRecHit::.+']},
47  {'TrajectorySeed' : ['TrajectorySeed']},
48  {'TrackCandidate' : ['TrackCandidate']},
49  {'PatternTools' : ['MomentumConstraint','VertexConstraint','Trajectory']},
50  {'TrackerRecHit2D' : ['SiStrip(Matched|)RecHit[12]D','SiTrackerGSRecHit[12]D','SiPixelRecHit']},
51  {'MuonReco' : ['reco::Muon(Ref|)(Vector|)']},
52  {'MuonSeed' : ['L3MuonTrajectorySeed']},
53  {'HepMCCandidate' : ['reco::GenParticle.*']},
54  {'L1Trigger' : ['l1extra::L1.+Particle']},
55  {'TrackInfo' : ['reco::TrackingRecHitInfo']},
56  {'EgammaCandidates' : ['reco::GsfElectron.*','reco::Photon.*']},
57  {'HcalIsolatedTrack' : ['reco::IsolatedPixelTrackCandidate', 'reco::EcalIsolatedParticleCandidate']},
58  {'HcalRecHit' : ['HFRecHit','HORecHit','ZDCRecHit','HBHERecHit']},
59  {'PFRootEvent' : ['EventColin::']},
60  {'CaloTowers' : ['CaloTower.*']},
61  {'GsfTrackReco' : ['GsfTrack.*']},
62  {'METReco' : ['reco::(Calo|PF|Gen|)MET','reco::PFClusterMET']},
63  {'ParticleFlowReco' : ['reco::RecoPFClusterRefCandidateRef.*']},
64  {'ParticleFlowCandidate' : ['reco::PFCandidateRef','reco::PFCandidateFwdRef','reco::PFCandidate']},
65  {'PhysicsToolsObjects' : ['PhysicsTools::Calibration']},
66  {'RecoCandidate' : ['reco::Candidate']},
67  {'TrackReco' : ['reco::Track','reco::TrackRef']},
68  {'VertexReco' : ['reco::Vertex']},
69  {'TFWLiteSelectorTest' : ['tfwliteselectortest']},
70  {'PatCandidates' : ['reco::RecoCandidate','pat::[A-Za-z]+Ref(Vector|)']},
71  {'JetReco' : ['reco::.*Jet','reco::.*Jet(Collection|Ref)']},
72  ]
73 
74 ignoreEdmDP = {
75  'LCGReflex/__gnu_cxx::__normal_iterator<std::basic_string<char>*,std::vector<std::basic_string<char>%>%>' : 1,
76  '' : 1
77 }
78 
80  """ Searches through the requested directory looking at
81  'classes_def.xml' files looking for duplicate Reflex definitions."""
82  # compile necessary RE statements
83  classNameRE = re.compile (r'class\s+name\s*=\s*"([^"]*)"')
84  spacesRE = re.compile (r'\s+')
85  stdRE = re.compile (r'std::')
86  srcClassNameRE = re.compile (r'(\w+)/src/classes_def.xml')
87  ignoreSrcRE = re.compile (r'.*/FWCore/Skeletons/scripts/mkTemplates/.+')
88  braketRE = re.compile (r'<.+>')
89  print "Searching for 'classes_def.xml' in '%s'." % os.path.join(os.environ.get('CMSSW_BASE'),'src')
90  xmlFiles = []
91  for srcDir in [os.environ.get('CMSSW_BASE'),os.environ.get('CMSSW_RELEASE_BASE')]:
92  if not len(srcDir): continue
93  for xml in commands.getoutput ('cd '+os.path.join(srcDir,'src')+'; find . -name "*classes_def.xml" -follow -print').split ('\n'):
94  if xml and (not xml in xmlFiles):
95  xmlFiles.append(xml)
96  if options.showXMLs:
97  pprint.pprint (xmlFiles)
98  # try and figure out the names of the packages
99  xmlPackages = []
100  packagesREs = {}
101  equivREs = {}
102  explicitREs = []
103  for item in equivDict:
104  for pack in item:
105  for equiv in item[pack]:
106  explicitREs.append( (re.compile(r'\b' + equiv + r'\b'),pack))
107  if options.lostDefs:
108  for filename in xmlFiles:
109  if (not filename) or (ignoreSrcRE.match(filename)): continue
110  match = srcClassNameRE.search (filename)
111  if not match: continue
112  packageName = match.group(1)
113  xmlPackages.append (packageName)
114  matchString = r'\b' + packageName + r'\b'
115  packagesREs[packageName] = re.compile (matchString)
116  equivList = equivREs.setdefault (packageName, [])
117  for item in equivDict:
118  for equiv in item.get (packageName, []):
119  matchString = re.compile(r'\b' + equiv + r'\b')
120  equivList.append( (matchString, equiv) )
121  equivList.append( (packagesREs[packageName], packageName) )
122  classDict = {}
123  ncdict = {'class' : 'className'}
124  for filename in xmlFiles:
125  if (not filename) or (ignoreSrcRE.match(filename)): continue
126  dupProblems = ''
127  exceptName = ''
128  regexList = []
129  localObjects = []
130  simpleObjectREs = []
131  if options.lostDefs:
132  lostMatch = srcClassNameRE.search (filename)
133  if lostMatch:
134  exceptName = lostMatch.group (1)
135  regexList = equivREs[exceptName]
136  xcount = len(regexList)-1
137  if not regexList[xcount][0].search (exceptName):
138  print '%s not found in' % exceptName,
139  print regexList[xcount][0]
140  sys.exit()
141  else: continue
142  if options.verbose:
143  print "filename", filename
144  try:
145  filepath = os.path.join(os.environ.get('CMSSW_BASE'),'src',filename)
146  if not os.path.exists(filepath):
147  filepath = os.path.join(os.environ.get('CMSSW_RELEASE_BASE'),'src',filename)
148  xmlObj = xml2obj (filename = filepath,
149  filtering = True,
150  nameChangeDict = ncdict)
151  except Exception as detail:
152  print "File %s is malformed XML. Please fix." % filename
153  print " ", detail
154  continue
155  try:
156  classList = xmlObj.selection.className
157  except:
158  try:
159  classList = xmlObj.className
160  except:
161  # this isn't a real classes_def.xml file. Skip it
162  print "**** SKIPPING '%s' - Doesn't seem to have proper information." % filename
163  continue
164  for piece in classList:
165  try:
166  className = spacesRE.sub ('', piece.name)
167  except:
168  # must be one of these class pattern things. Skip it
169  #print " skipping %s" % filename, piece.__repr__()
170  continue
171  className = stdRE.sub ('', className)
172  # print " ", className
173  # Now get rid of any typedefs
174  for typedef, tdList in typedefsDict.iteritems():
175  for alias in tdList:
176  className = re.sub (alias, typedef, className)
177  classDict.setdefault (className, set()).add (filename)
178  # should we check for lost definitions?
179  if not options.lostDefs:
180  continue
181  localObjects.append (className)
182  if options.lazyLostDefs and not braketRE.search (className):
183  #print " ", className
184  matchString = r'\b' + className + r'\b'
185  simpleObjectREs.append( (re.compile (matchString), className ) )
186  for className in localObjects:
187  # if we see our name (or equivalent) here, then let's
188  # skip complaining about this
189  foundEquiv = False
190  for equivRE in regexList:
191  #print "searching %s for %s" % (equivRE[1], className)
192  if equivRE[0].search (className):
193  foundEquiv = True
194  break
195  for simpleRE in simpleObjectREs:
196  if simpleRE[0].search (className):
197  foundEquiv = True
198  if options.verbose and simpleRE[1] != className:
199  print " Using %s to ignore %s" \
200  % (simpleRE[1], className)
201  break
202  if foundEquiv: continue
203  for exRes in explicitREs:
204  if exRes[0].search(className):
205  dupProblems += " %s : %s\n" % (exRes[1], className)
206  foundEquiv = True
207  break
208  if foundEquiv: continue
209  for packageName in xmlPackages:
210  # don't bother looking for the name of this
211  # package in this package
212  if packagesREs[packageName].search (className):
213  dupProblems += " %s : %s\n" % (packageName, className)
214  break
215  # for piece
216  if dupProblems:
217  print '\n%s\n%s\n' % (filename, dupProblems)
218  # for filename
219  if options.dups:
220  for name, fileSet in sorted( classDict.iteritems() ):
221  if len (fileSet) < 2:
222  continue
223  print name
224  fileList = list (fileSet)
225  fileList.sort()
226  for filename in fileList:
227  print " ", filename
228  print
229  # for name, fileSet
230  # if not noDups
231  #pprint.pprint (classDict)
232 
233 
235  """ Searches the edmpluginFile to find any duplicate
236  plugins."""
237  edmpluginFile = ''
238  libenv = 'LD_LIBRARY_PATH'
239  if os.environ.get('SCRAM_ARCH').startswith('osx'): libenv = 'DYLD_FALLBACK_LIBRARY_PATH'
240  biglib = '/biglib/'+os.environ.get('SCRAM_ARCH')
241  for libdir in os.environ.get(libenv).split(':'):
242  if libdir.endswith(biglib): continue
243  if os.path.exists(libdir+'/.edmplugincache'): edmpluginFile = edmpluginFile + ' ' + libdir+'/.edmplugincache'
244  if edmpluginFile == '': edmpluginFile = os.path.join(os.environ.get('CMSSW_BASE'),'lib',os.environ.get('SCRAM_ARCH'),'.edmplugincache')
245  cmd = "cat %s | awk '{print $2\" \"$1}' | sort | uniq | awk '{print $1}' | sort | uniq -c | grep '2 ' | awk '{print $2}'" % edmpluginFile
246  output = commands.getoutput (cmd).split('\n')
247  for line in output:
248  if ignoreEdmDP.has_key(line): continue
249  line = line.replace("*","\*")
250  cmd = "cat %s | grep ' %s ' | awk '{print $1}' | sort | uniq " % (edmpluginFile,line)
251  out1 = commands.getoutput (cmd).split('\n')
252  print line
253  for plugin in out1:
254  if plugin:
255  print " **"+plugin+"**"
256  print
257 
258 if __name__ == "__main__":
259  # setup options parser
260  parser = optparse.OptionParser ("Usage: %prog [options]\n"\
261  "Searches classes_def.xml for wrong/duplicate "\
262  "definitions")
263  xmlGroup = optparse.OptionGroup (parser, "ClassDef XML options")
264  dumpGroup = optparse.OptionGroup (parser, "EdmPluginDump options")
265  xmlGroup.add_option ('--dups', dest='dups', action='store_true',
266  default=False,
267  help="Search for duplicate definitions")
268  xmlGroup.add_option ('--lostDefs', dest='lostDefs', action='store_true',
269  default=False,
270  help="Looks for definitions in the wrong libraries")
271  xmlGroup.add_option ('--lazyLostDefs', dest='lazyLostDefs',
272  action='store_true',
273  default=False,
274  help="Will try to ignore as many lost defs as reasonable")
275  xmlGroup.add_option ('--verbose', dest='verbose',
276  action='store_true',
277  default=False,
278  help="Prints out a lot of information")
279  xmlGroup.add_option ('--showXMLs', dest='showXMLs', action='store_true',
280  default=False,
281  help="Shows all 'classes_def.xml' files")
282  xmlGroup.add_option ('--dir', dest='srcdir', type='string', default='',
283  help="Obsolete")
284  dumpGroup.add_option ('--edmPD', dest='edmPD', action='store_true',
285  default=False,
286  help="Searches EDM Plugin Dump for duplicates")
287  dumpGroup.add_option ('--edmFile', dest='edmFile', type='string',
288  default='',
289  help="Obsolete")
290  parser.add_option_group (xmlGroup)
291  parser.add_option_group (dumpGroup)
292  (options, args) = parser.parse_args()
293 
294  # Let's go:
295  if options.lazyLostDefs:
296  options.lostDefs = True
297  if options.showXMLs or options.lostDefs or options.dups:
298  searchClassDefXml ()
299  if options.edmPD:
300  searchDuplicatePlugins ()
double split
Definition: MVATrainer.cc:139
std::vector< T >::const_iterator search(const cond::Time_t &val, const std::vector< T > &container)
Definition: IOVProxy.cc:252