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