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