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