summaryrefslogtreecommitdiff
path: root/debian/patches/scan-build-py-default.diff
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2017-10-15 15:41:01 +0300
committerIgor Pashev <pashev.igor@gmail.com>2017-10-15 15:41:01 +0300
commit7a2b43796a4c38cf98fe05e8e4ec985318b2721b (patch)
treeb0f5611276e10646b654f7d5ed12c6e6060353be /debian/patches/scan-build-py-default.diff
downloadllvm-toolchain-5.0-debian.tar.gz
Imported llvm-toolchain-5.0 (1:5.0-4)debian/5.0-4debian
Diffstat (limited to 'debian/patches/scan-build-py-default.diff')
-rw-r--r--debian/patches/scan-build-py-default.diff518
1 files changed, 518 insertions, 0 deletions
diff --git a/debian/patches/scan-build-py-default.diff b/debian/patches/scan-build-py-default.diff
new file mode 100644
index 0000000..431bffb
--- /dev/null
+++ b/debian/patches/scan-build-py-default.diff
@@ -0,0 +1,518 @@
+Index: llvm-toolchain-snapshot_3.9-svn269220/home/sylvestre/dev/debian/pkg-llvm/llvm-toolchain-branches/llvm-toolchain-snapshot_3.9-svn269220/clang/tools/scan-build-py/libscanbuild/analyze.py
+===================================================================
+--- llvm-toolchain-snapshot_3.9-svn269220.orig/home/sylvestre/dev/debian/pkg-llvm/llvm-toolchain-branches/llvm-toolchain-snapshot_3.9-svn269220/clang/tools/scan-build-py/libscanbuild/analyze.py
++++ /dev/null
+@@ -1,513 +0,0 @@
+-# -*- coding: utf-8 -*-
+-# The LLVM Compiler Infrastructure
+-#
+-# This file is distributed under the University of Illinois Open Source
+-# License. See LICENSE.TXT for details.
+-""" This module implements the 'scan-build' command API.
+-
+-To run the static analyzer against a build is done in multiple steps:
+-
+- -- Intercept: capture the compilation command during the build,
+- -- Analyze: run the analyzer against the captured commands,
+- -- Report: create a cover report from the analyzer outputs. """
+-
+-import sys
+-import re
+-import os
+-import os.path
+-import json
+-import argparse
+-import logging
+-import subprocess
+-import multiprocessing
+-from libscanbuild import initialize_logging, tempdir, command_entry_point
+-from libscanbuild.runner import run
+-from libscanbuild.intercept import capture
+-from libscanbuild.report import report_directory, document
+-from libscanbuild.clang import get_checkers
+-from libscanbuild.compilation import split_command
+-
+-__all__ = ['analyze_build_main', 'analyze_build_wrapper']
+-
+-COMPILER_WRAPPER_CC = 'analyze-cc'
+-COMPILER_WRAPPER_CXX = 'analyze-c++'
+-
+-
+-@command_entry_point
+-def analyze_build_main(bin_dir, from_build_command):
+- """ Entry point for 'analyze-build' and 'scan-build'. """
+-
+- parser = create_parser(from_build_command)
+- args = parser.parse_args()
+- validate(parser, args, from_build_command)
+-
+- # setup logging
+- initialize_logging(args.verbose)
+- logging.debug('Parsed arguments: %s', args)
+-
+- with report_directory(args.output, args.keep_empty) as target_dir:
+- if not from_build_command:
+- # run analyzer only and generate cover report
+- run_analyzer(args, target_dir)
+- number_of_bugs = document(args, target_dir, True)
+- return number_of_bugs if args.status_bugs else 0
+- elif args.intercept_first:
+- # run build command and capture compiler executions
+- exit_code = capture(args, bin_dir)
+- # next step to run the analyzer against the captured commands
+- if need_analyzer(args.build):
+- run_analyzer(args, target_dir)
+- # cover report generation and bug counting
+- number_of_bugs = document(args, target_dir, True)
+- # remove the compilation database when it was not requested
+- if os.path.exists(args.cdb):
+- os.unlink(args.cdb)
+- # set exit status as it was requested
+- return number_of_bugs if args.status_bugs else exit_code
+- else:
+- return exit_code
+- else:
+- # run the build command with compiler wrappers which
+- # execute the analyzer too. (interposition)
+- environment = setup_environment(args, target_dir, bin_dir)
+- logging.debug('run build in environment: %s', environment)
+- exit_code = subprocess.call(args.build, env=environment)
+- logging.debug('build finished with exit code: %d', exit_code)
+- # cover report generation and bug counting
+- number_of_bugs = document(args, target_dir, False)
+- # set exit status as it was requested
+- return number_of_bugs if args.status_bugs else exit_code
+-
+-
+-def need_analyzer(args):
+- """ Check the intent of the build command.
+-
+- When static analyzer run against project configure step, it should be
+- silent and no need to run the analyzer or generate report.
+-
+- To run `scan-build` against the configure step might be neccessary,
+- when compiler wrappers are used. That's the moment when build setup
+- check the compiler and capture the location for the build process. """
+-
+- return len(args) and not re.search('configure|autogen', args[0])
+-
+-
+-def run_analyzer(args, output_dir):
+- """ Runs the analyzer against the given compilation database. """
+-
+- def exclude(filename):
+- """ Return true when any excluded directory prefix the filename. """
+- return any(re.match(r'^' + directory, filename)
+- for directory in args.excludes)
+-
+- consts = {
+- 'clang': args.clang,
+- 'output_dir': output_dir,
+- 'output_format': args.output_format,
+- 'output_failures': args.output_failures,
+- 'direct_args': analyzer_params(args),
+- 'force_debug': args.force_debug
+- }
+-
+- logging.debug('run analyzer against compilation database')
+- with open(args.cdb, 'r') as handle:
+- generator = (dict(cmd, **consts)
+- for cmd in json.load(handle) if not exclude(cmd['file']))
+- # when verbose output requested execute sequentially
+- pool = multiprocessing.Pool(1 if args.verbose > 2 else None)
+- for current in pool.imap_unordered(run, generator):
+- if current is not None:
+- # display error message from the static analyzer
+- for line in current['error_output']:
+- logging.info(line.rstrip())
+- pool.close()
+- pool.join()
+-
+-
+-def setup_environment(args, destination, bin_dir):
+- """ Set up environment for build command to interpose compiler wrapper. """
+-
+- environment = dict(os.environ)
+- environment.update({
+- 'CC': os.path.join(bin_dir, COMPILER_WRAPPER_CC),
+- 'CXX': os.path.join(bin_dir, COMPILER_WRAPPER_CXX),
+- 'ANALYZE_BUILD_CC': args.cc,
+- 'ANALYZE_BUILD_CXX': args.cxx,
+- 'ANALYZE_BUILD_CLANG': args.clang if need_analyzer(args.build) else '',
+- 'ANALYZE_BUILD_VERBOSE': 'DEBUG',
+- 'ANALYZE_BUILD_REPORT_DIR': destination,
+- 'ANALYZE_BUILD_REPORT_FORMAT': args.output_format,
+- 'ANALYZE_BUILD_REPORT_FAILURES': 'yes' if args.output_failures else '',
+- 'ANALYZE_BUILD_PARAMETERS': ' '.join(analyzer_params(args)),
+- 'ANALYZE_BUILD_FORCE_DEBUG': 'yes' if args.force_debug else ''
+- })
+- return environment
+-
+-
+-def analyze_build_wrapper(cplusplus):
+- """ Entry point for `analyze-cc` and `analyze-c++` compiler wrappers. """
+-
+- # initialize wrapper logging
+- logging.basicConfig(format='analyze: %(levelname)s: %(message)s',
+- level=os.getenv('ANALYZE_BUILD_VERBOSE', 'INFO'))
+- # execute with real compiler
+- compiler = os.getenv('ANALYZE_BUILD_CXX', 'c++') if cplusplus \
+- else os.getenv('ANALYZE_BUILD_CC', 'cc')
+- compilation = [compiler] + sys.argv[1:]
+- logging.info('execute compiler: %s', compilation)
+- result = subprocess.call(compilation)
+- # exit when it fails, ...
+- if result or not os.getenv('ANALYZE_BUILD_CLANG'):
+- return result
+- # ... and run the analyzer if all went well.
+- try:
+- # check is it a compilation
+- compilation = split_command(sys.argv)
+- if compilation is None:
+- return result
+- # collect the needed parameters from environment, crash when missing
+- parameters = {
+- 'clang': os.getenv('ANALYZE_BUILD_CLANG'),
+- 'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
+- 'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
+- 'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
+- 'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
+- '').split(' '),
+- 'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
+- 'directory': os.getcwd(),
+- 'command': [sys.argv[0], '-c'] + compilation.flags
+- }
+- # call static analyzer against the compilation
+- for source in compilation.files:
+- parameters.update({'file': source})
+- logging.debug('analyzer parameters %s', parameters)
+- current = run(parameters)
+- # display error message from the static analyzer
+- if current is not None:
+- for line in current['error_output']:
+- logging.info(line.rstrip())
+- except Exception:
+- logging.exception("run analyzer inside compiler wrapper failed.")
+- return result
+-
+-
+-def analyzer_params(args):
+- """ A group of command line arguments can mapped to command
+- line arguments of the analyzer. This method generates those. """
+-
+- def prefix_with(constant, pieces):
+- """ From a sequence create another sequence where every second element
+- is from the original sequence and the odd elements are the prefix.
+-
+- eg.: prefix_with(0, [1,2,3]) creates [0, 1, 0, 2, 0, 3] """
+-
+- return [elem for piece in pieces for elem in [constant, piece]]
+-
+- result = []
+-
+- if args.store_model:
+- result.append('-analyzer-store={0}'.format(args.store_model))
+- if args.constraints_model:
+- result.append('-analyzer-constraints={0}'.format(
+- args.constraints_model))
+- if args.internal_stats:
+- result.append('-analyzer-stats')
+- if args.analyze_headers:
+- result.append('-analyzer-opt-analyze-headers')
+- if args.stats:
+- result.append('-analyzer-checker=debug.Stats')
+- if args.maxloop:
+- result.extend(['-analyzer-max-loop', str(args.maxloop)])
+- if args.output_format:
+- result.append('-analyzer-output={0}'.format(args.output_format))
+- if args.analyzer_config:
+- result.append(args.analyzer_config)
+- if args.verbose >= 4:
+- result.append('-analyzer-display-progress')
+- if args.plugins:
+- result.extend(prefix_with('-load', args.plugins))
+- if args.enable_checker:
+- checkers = ','.join(args.enable_checker)
+- result.extend(['-analyzer-checker', checkers])
+- if args.disable_checker:
+- checkers = ','.join(args.disable_checker)
+- result.extend(['-analyzer-disable-checker', checkers])
+- if os.getenv('UBIVIZ'):
+- result.append('-analyzer-viz-egraph-ubigraph')
+-
+- return prefix_with('-Xclang', result)
+-
+-
+-def print_active_checkers(checkers):
+- """ Print active checkers to stdout. """
+-
+- for name in sorted(name for name, (_, active) in checkers.items()
+- if active):
+- print(name)
+-
+-
+-def print_checkers(checkers):
+- """ Print verbose checker help to stdout. """
+-
+- print('')
+- print('available checkers:')
+- print('')
+- for name in sorted(checkers.keys()):
+- description, active = checkers[name]
+- prefix = '+' if active else ' '
+- if len(name) > 30:
+- print(' {0} {1}'.format(prefix, name))
+- print(' ' * 35 + description)
+- else:
+- print(' {0} {1: <30} {2}'.format(prefix, name, description))
+- print('')
+- print('NOTE: "+" indicates that an analysis is enabled by default.')
+- print('')
+-
+-
+-def validate(parser, args, from_build_command):
+- """ Validation done by the parser itself, but semantic check still
+- needs to be done. This method is doing that. """
+-
+- if args.help_checkers_verbose:
+- print_checkers(get_checkers(args.clang, args.plugins))
+- parser.exit()
+- elif args.help_checkers:
+- print_active_checkers(get_checkers(args.clang, args.plugins))
+- parser.exit()
+-
+- if from_build_command and not args.build:
+- parser.error('missing build command')
+-
+-
+-def create_parser(from_build_command):
+- """ Command line argument parser factory method. """
+-
+- parser = argparse.ArgumentParser(
+- formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+-
+- parser.add_argument(
+- '--verbose', '-v',
+- action='count',
+- default=0,
+- help="""Enable verbose output from '%(prog)s'. A second and third
+- flag increases verbosity.""")
+- parser.add_argument(
+- '--override-compiler',
+- action='store_true',
+- help="""Always resort to the compiler wrapper even when better
+- interposition methods are available.""")
+- parser.add_argument(
+- '--intercept-first',
+- action='store_true',
+- help="""Run the build commands only, build a compilation database,
+- then run the static analyzer afterwards.
+- Generally speaking it has better coverage on build commands.
+- With '--override-compiler' it use compiler wrapper, but does
+- not run the analyzer till the build is finished. """)
+- parser.add_argument(
+- '--cdb',
+- metavar='<file>',
+- default="compile_commands.json",
+- help="""The JSON compilation database.""")
+-
+- parser.add_argument(
+- '--output', '-o',
+- metavar='<path>',
+- default=tempdir(),
+- help="""Specifies the output directory for analyzer reports.
+- Subdirectory will be created if default directory is targeted.
+- """)
+- parser.add_argument(
+- '--status-bugs',
+- action='store_true',
+- help="""By default, the exit status of '%(prog)s' is the same as the
+- executed build command. Specifying this option causes the exit
+- status of '%(prog)s' to be non zero if it found potential bugs
+- and zero otherwise.""")
+- parser.add_argument(
+- '--html-title',
+- metavar='<title>',
+- help="""Specify the title used on generated HTML pages.
+- If not specified, a default title will be used.""")
+- parser.add_argument(
+- '--analyze-headers',
+- action='store_true',
+- help="""Also analyze functions in #included files. By default, such
+- functions are skipped unless they are called by functions
+- within the main source file.""")
+- format_group = parser.add_mutually_exclusive_group()
+- format_group.add_argument(
+- '--plist', '-plist',
+- dest='output_format',
+- const='plist',
+- default='html',
+- action='store_const',
+- help="""This option outputs the results as a set of .plist files.""")
+- format_group.add_argument(
+- '--plist-html', '-plist-html',
+- dest='output_format',
+- const='plist-html',
+- default='html',
+- action='store_const',
+- help="""This option outputs the results as a set of .html and .plist
+- files.""")
+- # TODO: implement '-view '
+-
+- advanced = parser.add_argument_group('advanced options')
+- advanced.add_argument(
+- '--keep-empty',
+- action='store_true',
+- help="""Don't remove the build results directory even if no issues
+- were reported.""")
+- advanced.add_argument(
+- '--no-failure-reports', '-no-failure-reports',
+- dest='output_failures',
+- action='store_false',
+- help="""Do not create a 'failures' subdirectory that includes analyzer
+- crash reports and preprocessed source files.""")
+- advanced.add_argument(
+- '--stats', '-stats',
+- action='store_true',
+- help="""Generates visitation statistics for the project being analyzed.
+- """)
+- advanced.add_argument(
+- '--internal-stats',
+- action='store_true',
+- help="""Generate internal analyzer statistics.""")
+- advanced.add_argument(
+- '--maxloop', '-maxloop',
+- metavar='<loop count>',
+- type=int,
+- help="""Specifiy the number of times a block can be visited before
+- giving up. Increase for more comprehensive coverage at a cost
+- of speed.""")
+- advanced.add_argument(
+- '--store', '-store',
+- metavar='<model>',
+- dest='store_model',
+- choices=['region', 'basic'],
+- help="""Specify the store model used by the analyzer.
+- 'region' specifies a field- sensitive store model.
+- 'basic' which is far less precise but can more quickly
+- analyze code. 'basic' was the default store model for
+- checker-0.221 and earlier.""")
+- advanced.add_argument(
+- '--constraints', '-constraints',
+- metavar='<model>',
+- dest='constraints_model',
+- choices=['range', 'basic'],
+- help="""Specify the contraint engine used by the analyzer. Specifying
+- 'basic' uses a simpler, less powerful constraint model used by
+- checker-0.160 and earlier.""")
+- advanced.add_argument(
+- '--use-analyzer',
+- metavar='<path>',
+- dest='clang',
+- default='clang',
+- help="""'%(prog)s' uses the 'clang' executable relative to itself for
+- static analysis. One can override this behavior with this
+- option by using the 'clang' packaged with Xcode (on OS X) or
+- from the PATH.""")
+- advanced.add_argument(
+- '--use-cc',
+- metavar='<path>',
+- dest='cc',
+- default='cc',
+- help="""When '%(prog)s' analyzes a project by interposing a "fake
+- compiler", which executes a real compiler for compilation and
+- do other tasks (to run the static analyzer or just record the
+- compiler invocation). Because of this interposing, '%(prog)s'
+- does not know what compiler your project normally uses.
+- Instead, it simply overrides the CC environment variable, and
+- guesses your default compiler.
+-
+- If you need '%(prog)s' to use a specific compiler for
+- *compilation* then you can use this option to specify a path
+- to that compiler.""")
+- advanced.add_argument(
+- '--use-c++',
+- metavar='<path>',
+- dest='cxx',
+- default='c++',
+- help="""This is the same as "--use-cc" but for C++ code.""")
+- advanced.add_argument(
+- '--analyzer-config', '-analyzer-config',
+- metavar='<options>',
+- help="""Provide options to pass through to the analyzer's
+- -analyzer-config flag. Several options are separated with
+- comma: 'key1=val1,key2=val2'
+-
+- Available options:
+- stable-report-filename=true or false (default)
+-
+- Switch the page naming to:
+- report-<filename>-<function/method name>-<id>.html
+- instead of report-XXXXXX.html""")
+- advanced.add_argument(
+- '--exclude',
+- metavar='<directory>',
+- dest='excludes',
+- action='append',
+- default=[],
+- help="""Do not run static analyzer against files found in this
+- directory. (You can specify this option multiple times.)
+- Could be usefull when project contains 3rd party libraries.
+- The directory path shall be absolute path as file names in
+- the compilation database.""")
+- advanced.add_argument(
+- '--force-analyze-debug-code',
+- dest='force_debug',
+- action='store_true',
+- help="""Tells analyzer to enable assertions in code even if they were
+- disabled during compilation, enabling more precise results.""")
+-
+- plugins = parser.add_argument_group('checker options')
+- plugins.add_argument(
+- '--load-plugin', '-load-plugin',
+- metavar='<plugin library>',
+- dest='plugins',
+- action='append',
+- help="""Loading external checkers using the clang plugin interface.""")
+- plugins.add_argument(
+- '--enable-checker', '-enable-checker',
+- metavar='<checker name>',
+- action=AppendCommaSeparated,
+- help="""Enable specific checker.""")
+- plugins.add_argument(
+- '--disable-checker', '-disable-checker',
+- metavar='<checker name>',
+- action=AppendCommaSeparated,
+- help="""Disable specific checker.""")
+- plugins.add_argument(
+- '--help-checkers',
+- action='store_true',
+- help="""A default group of checkers is run unless explicitly disabled.
+- Exactly which checkers constitute the default group is a
+- function of the operating system in use. These can be printed
+- with this flag.""")
+- plugins.add_argument(
+- '--help-checkers-verbose',
+- action='store_true',
+- help="""Print all available checkers and mark the enabled ones.""")
+-
+- if from_build_command:
+- parser.add_argument(
+- dest='build',
+- nargs=argparse.REMAINDER,
+- help="""Command to run.""")
+-
+- return parser
+-
+-
+-class AppendCommaSeparated(argparse.Action):
+- """ argparse Action class to support multiple comma separated lists. """
+-
+- def __call__(self, __parser, namespace, values, __option_string):
+- # getattr(obj, attr, default) does not really returns default but none
+- if getattr(namespace, self.dest, None) is None:
+- setattr(namespace, self.dest, [])
+- # once it's fixed we can use as expected
+- actual = getattr(namespace, self.dest)
+- actual.extend(values.split(','))
+- setattr(namespace, self.dest, actual)