Back to home page

Project CMSSW displayed by LXR

 
 

    


Warning, /HLTrigger/Configuration/scripts/edmPluginCoverage is written in an unsupported language. File is not indexed.

0001 #! /usr/bin/env python
0002 # -*- coding: iso-8859-15 -*-
0003 
0004 # Author: Andrea 'fwyzard' Bocci <andrea.bocci@cern.ch>, Università di Pisa
0005 
0006 from __future__ import print_function
0007 import os, sys
0008 import re
0009 
0010 import os.path
0011 if 'relpath' in dir(os.path):
0012   relpath = os.path.relpath
0013 else:
0014   # this is missing in python before 2.6
0015   def relpath(path, start = os.path.curdir):
0016     """Return a relative version of a path"""
0017 
0018     if not path:
0019         raise ValueError("no path specified")
0020     
0021     start_list = os.path.abspath(start).split(os.sep)
0022     path_list = os.path.abspath(path).split(os.sep)
0023     
0024     # Work out how much of the filepath is shared by start and path.
0025     i = len(os.path.commonprefix([start_list, path_list]))
0026 
0027     rel_list = [os.pardir] * (len(start_list)-i) + path_list[i:]
0028     return os.sep.join(rel_list)
0029 
0030 # program verbosity level
0031 verbosity = 1
0032 
0033 # 0: silent
0034 # 1: errors only
0035 # 2: errors and warnings
0036 # 3: errors, wanring, infos
0037 
0038 def print_verbose_message(level, type, buildfile, message, log = ''):
0039   if level > verbosity:
0040     return
0041   sys.stderr.write('%s: in %s: %s\n' % (type, buildfile, message))
0042   if log:
0043     sys.stderr.write('\t--------------------------------------------------------------------------------\n')
0044     for line in log.splitlines():
0045       sys.stderr.write('\t%s\n' % line)
0046     sys.stderr.write('\t--------------------------------------------------------------------------------\n')
0047 
0048 def print_error(buildfile, message, log = ''):
0049   print_verbose_message(1, 'Error', buildfile, message, log)
0050 
0051 def print_warning(buildfile, message, log = ''):
0052   print_verbose_message(2, 'Warning', buildfile, message, log)
0053 
0054 def print_info(buildfile, message, log = ''):
0055   print_verbose_message(3, 'Info', buildfile, message, log)
0056 
0057 
0058 def_comment = re.compile(r'\s*#.*?$', re.M)
0059 def_export  = re.compile(r'<\s*export\s*>.*?<\s*/export\s*>', re.S | re.I)
0060 def_library = re.compile(r'<\s*library\s+.*?>.*?<\s*/library\s*>', re.S | re.I)
0061 def_binary  = re.compile(r'<\s*bin\s+.*?>.*?<\s*/bin\s*>', re.S | re.I)
0062 def_remove  = re.compile(r'\s*(%s|%s|%s)\s*$' % (def_export.pattern, def_library.pattern, def_binary.pattern), re.S | re.M | re.I)
0063 def_plugin  = re.compile(r'<\s*flags\s+EDM_PLUGIN\s*=\s*(1|"1")\s*>', re.I)
0064 
0065 has_export_data  = re.compile(r'<\s*export\s*>(?P<data>.*?)<\s*/export\s*>', re.S | re.I)
0066 has_export_name  = re.compile(r'<\s*lib\s+name\s*=\s*"?(?P<name>[\w/]+)"?\s*>', re.I)
0067 has_library_name = re.compile(r'<library(\s+file\s*=\s*"?[\w\s/.,*]*"?)?\s+name\s*=\s*"?(?P<name>[\w]+)"?(\s+file\s*=\s*"?[\w\s/.,*]*"?)?\s*>', re.I)
0068 has_library_file = re.compile(r'<library\s+file\s*=\s*"?(?P<file>[\w.]+?)\.(cc|cxx|cpp|C)"?\s*>', re.I)
0069 has_binary_name  = re.compile(r'<bin(\s+file\s*=\s*"?[\w\s/.,*]*"?)?\s+name\s*=\s*"?(?P<name>\w+)"?(\s+file\s*=\s*"?[\w\s/.,*]*"?)?\s*>', re.I)
0070 has_binary_file  = re.compile(r'<bin\s+file\s*=\s*"?(?P<file>[\w.]+?)\.(cc|cxx|cpp|C)"?\s*>', re.I)
0071 
0072 def what_defines(topdir, buildfile):
0073   """Return a 3-tuple of lists of libraries, plugins and binaries defined in the given BuildFile[.xml]"""
0074   file = open(os.path.join(topdir, buildfile), 'r')
0075   lines = file.read()
0076   file.close()
0077 
0078   tokens = buildfile.split(os.sep)
0079   level = len(tokens) - 1
0080   implicit = '%s%s' % tuple(tokens[:2])
0081 
0082   # strip comments
0083   lines = re.sub(def_comment, '', lines)
0084 
0085   # extract <library>, <export> and <bin> blocks
0086   libraries = re.findall(def_library, lines)
0087   exports   = re.findall(def_export,  lines)
0088   binaries  = re.findall(def_binary,  lines)
0089   lines = re.sub(def_remove, '', lines)
0090 
0091   # check if the global entries in the BuildFile specifies a plugin
0092   is_plugin = bool( re.search(def_plugin, lines) )
0093 
0094   libs    = []
0095   plugins = []
0096   bins    = []
0097 
0098   # extract the names of all libraries and plugins
0099   for block in libraries:
0100     has_name = re.search(has_library_name, block)
0101     has_file = re.search(has_library_file, block)
0102     if has_name:
0103       name = has_name.group('name')
0104     elif has_file:
0105       name = has_file.group('file')
0106     else:
0107       print_error(buildfile, 'found a <library> definition without any name or file parameters', block)
0108       continue
0109     if is_plugin or re.search(def_plugin, block):
0110       plugins.append(name)
0111     else:
0112       libs.append(name)
0113 
0114   # when defining a plugin, the export blocks are meaningless 
0115   if exports and is_plugin:
0116     print_warning(buildfile, 'skipping <export> blocks due to global EDM_PLUGIN definition')
0117     exports = []
0118  
0119   for block in exports:
0120     has_data = re.search(has_export_data, block).group('data')
0121     if not has_data.split():
0122       print_info(buildfile, 'skipping empty export block')
0123       continue
0124     has_name = re.search(has_export_name, block)
0125     if has_name:
0126       name = has_name.group('name')
0127       # some modules use <lib name=1> to define the library name automatically
0128       if name == '1':
0129         print_info(buildfile, 'implicit declaration of module name, using to "%s"' % implicit)
0130         name = implicit
0131       elif '/' in name:
0132         print_warning(buildfile, 'invalid module name "%s", falling back to the implicit default "%s"' % (name, implicit))
0133         name = implicit
0134     elif level == 2:
0135       print_warning(buildfile, 'missing declaration of module name, falling back to implicit default "%s"' % implicit)
0136       name = implicit
0137     else:
0138       print_error(buildfile, 'found an <export> definition without any name parameter', block)
0139       continue
0140     if re.search(def_plugin, block):
0141       print_warning(buildfile, 'ignoring EDM_PLUGIN declaration in <export> block')
0142     libs.append(name)
0143 
0144   # extract the names of all binaries
0145   for block in binaries:
0146     has_name = re.search(has_binary_name, block)
0147     has_file = re.search(has_binary_file, block)
0148     if has_name:
0149       name = has_name.group('name')
0150     elif has_file:
0151       name = has_file.group('file')
0152     else:
0153       print_error(buildfile, 'found a <bin> definition without any name or file parameters', block)
0154       continue
0155     bins.append(name)
0156 
0157   # a plugin is implicitly defined for package top level BuildFiles, if there is a <flags EDM_PLUGIN="1"> statement
0158   if not libraries and not exports and not binaries:
0159     if level == 2 and is_plugin:
0160       print_info(buildfile, 'implicit declaration of plugin, using "%s"' % implicit)
0161       plugins.append(implicit)
0162     else:
0163       print_warning(buildfile, 'found no module definitions')
0164     
0165   return (libs, plugins, bins)
0166 
0167 
0168 def fill_map(topdir):
0169   """return a map that associates to each libray and plugin (lib*.so and plugin*.so) the package where it is defined"""
0170   map = dict()
0171   for (dir, subs, files) in os.walk(topdir):
0172     # skip all data, doc and python directories
0173     for sub in ('data', 'doc', 'python', 'xml', 'bin'):
0174       if sub in subs:
0175         subs.remove(sub)
0176 
0177     # look for a BuildFile or BuildFile.xml
0178     buildfile = ''
0179     if 'BuildFile.xml' in files:
0180       buildfile = os.sep.join((dir, 'BuildFile.xml'))
0181     elif 'BuildFile' in files:
0182       buildfile = os.sep.join((dir, 'BuildFile'))
0183     else:
0184       continue
0185     # keep the relative path for the BuildFile and the package
0186     buildfile = relpath(buildfile, topdir)
0187     package   = os.sep.join( relpath(dir, topdir).split(os.sep)[:2] )
0188 
0189     # find out which libraries, plugins and binaries are defined in the BuildFile 
0190     (libraries, plugins, binaries) = what_defines(topdir, buildfile)
0191     modules = libraries + plugins
0192 
0193     for module in modules:
0194       if module in map:
0195         print_error(buildfile, 'duplicate definition of module "%s", overriding original definition in "%s"' % (module, map[module][1]))
0196       map[module] = (package, buildfile)
0197 
0198   return map
0199 
0200 
0201 
0202 # look for plugins and libraries definitions under $CMSSW_RELEASE_BASE/src
0203 packagemap = fill_map(os.sep.join((os.environ['CMSSW_RELEASE_BASE'], 'src')))
0204 
0205 # remove the leading "plugin" or "lib" and the trailing ".so"
0206 clean = re.compile(r'^(lib|plugin)(?P<lib>\w+?)(Capabilities)?\.so$')
0207 
0208 libs = dict([ (clean.match(line.strip()).group('lib'),line.strip()) for line in sys.stdin ])
0209 index = libs.keys()
0210 index.sort()
0211 
0212 for lib in index:
0213   if lib in packagemap:
0214     print("%-80s\t%s" % (libs[lib], packagemap[lib][0]))
0215   else:
0216     print("%-80s\t*** not found ***" % libs[lib])
0217