diff options
Diffstat (limited to 'elpa/irony-20220110.849/server/build-aux/run-clang-tidy')
3 files changed, 291 insertions, 0 deletions
diff --git a/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/LICENSE.TXT b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/LICENSE.TXT new file mode 100644 index 0000000..a7f579f --- /dev/null +++ b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/LICENSE.TXT @@ -0,0 +1,43 @@ +============================================================================== +LLVM Release License +============================================================================== +University of Illinois/NCSA +Open Source License + +Copyright (c) 2007-2016 University of Illinois at Urbana-Champaign. +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. diff --git a/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/README b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/README new file mode 100644 index 0000000..ed43509 --- /dev/null +++ b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/README @@ -0,0 +1,12 @@ +Origin: +- http://llvm.org/svn/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/run-clang-tidy.py?p=294607 +- https://github.com/llvm-mirror/clang-tools-extra/blob/c2e903ec98385b82e35bdb303e411854a2e8c032/clang-tidy/tool/run-clang-tidy.py + +Modifications: +- the python version has been frozen to python2, + as the script is not python3-compatible +- added -warnings-as-errors option +- the run-clang-tidy.py script has been modified + to return a sensible exit code when running on Travis CI, + i.e. it honors exit code of the underlying processes + causing build failures on pull requests diff --git a/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/run-clang-tidy.py b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/run-clang-tidy.py new file mode 100755 index 0000000..17db708 --- /dev/null +++ b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/run-clang-tidy.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python2 +# +#===- run-clang-tidy.py - Parallel clang-tidy runner ---------*- python -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# FIXME: Integrate with clang-tidy-diff.py + +""" +Parallel clang-tidy runner +========================== + +Runs clang-tidy over all files in a compilation database. Requires clang-tidy +and clang-apply-replacements in $PATH. + +Example invocations. +- Run clang-tidy on all files in the current working directory with a default + set of checks and show warnings in the cpp files and all project headers. + run-clang-tidy.py $PWD + +- Fix all header guards. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard + +- Fix all header guards included from clang-tidy and header guards + for clang-tidy headers. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \ + -header-filter=extra/clang-tidy + +Compilation database setup: +http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +""" + +import argparse +import json +import multiprocessing +import os +import Queue +import re +import shutil +import subprocess +import sys +import tempfile +import threading + + +def find_compilation_database(path): + """Adjusts the directory until a compilation database is found.""" + result = './' + while not os.path.isfile(os.path.join(result, path)): + if os.path.realpath(result) == '/': + print 'Error: could not find compilation database.' + sys.exit(1) + result += '../' + return os.path.realpath(result) + + +def get_tidy_invocation(f, clang_tidy_binary, checks, tmpdir, build_path, + header_filter, extra_arg, extra_arg_before, quiet, + warnings_as_errors): + """Gets a command line for clang-tidy.""" + start = [clang_tidy_binary] + if header_filter is not None: + start.append('-header-filter=' + header_filter) + else: + # Show warnings in all in-project headers by default. + start.append('-header-filter=^' + build_path + '/.*') + if checks: + start.append('-checks=' + checks) + if tmpdir is not None: + start.append('-export-fixes') + # Get a temporary file. We immediately close the handle so clang-tidy can + # overwrite it. + (handle, name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir) + os.close(handle) + start.append(name) + for arg in extra_arg: + start.append('-extra-arg=%s' % arg) + for arg in extra_arg_before: + start.append('-extra-arg-before=%s' % arg) + start.append('-p=' + build_path) + if quiet: + start.append('-quiet') + if warnings_as_errors is not None: + start.append('-warnings-as-errors=%s' % warnings_as_errors) + start.append(f) + return start + + +def apply_fixes(args, tmpdir): + """Calls clang-apply-fixes on a given directory. Deletes the dir when done.""" + invocation = [args.clang_apply_replacements_binary] + if args.format: + invocation.append('-format') + invocation.append(tmpdir) + ret = subprocess.call(invocation) + shutil.rmtree(tmpdir) + return ret + + +def run_tidy(args, tmpdir, build_path, queue, results, i): + """Takes filenames out of queue and runs clang-tidy on them.""" + results[i] = 0 + while True: + name = queue.get() + invocation = get_tidy_invocation(name, args.clang_tidy_binary, args.checks, + tmpdir, build_path, args.header_filter, + args.extra_arg, args.extra_arg_before, + args.quiet, args.warnings_as_errors) + sys.stdout.write(' '.join(invocation) + '\n') + if subprocess.call(invocation) != 0: + results[i] = 1 + queue.task_done() + + +def main(): + parser = argparse.ArgumentParser(description='Runs clang-tidy over all files ' + 'in a compilation database. Requires ' + 'clang-tidy and clang-apply-replacements in ' + '$PATH.') + parser.add_argument('-clang-tidy-binary', metavar='PATH', + default='clang-tidy', + help='path to clang-tidy binary') + parser.add_argument('-clang-apply-replacements-binary', metavar='PATH', + default='clang-apply-replacements', + help='path to clang-apply-replacements binary') + parser.add_argument('-checks', default=None, + help='checks filter, when not specified, use clang-tidy ' + 'default') + parser.add_argument('-header-filter', default=None, + help='regular expression matching the names of the ' + 'headers to output diagnostics from. Diagnostics from ' + 'the main file of each translation unit are always ' + 'displayed.') + parser.add_argument('-warnings-as-errors', default=None, metavar='STRING', + help='Upgrades warnings to errors. ' + 'Same format as "-checks".' + "This option's value is appended to the value of " + "the 'WarningsAsErrors' option in .clang-tidy " + "file, if any.'") + parser.add_argument('-j', type=int, default=0, + help='number of tidy instances to be run in parallel.') + parser.add_argument('files', nargs='*', default=['.*'], + help='files to be processed (regex on path)') + parser.add_argument('-fix', action='store_true', help='apply fix-its') + parser.add_argument('-format', action='store_true', help='Reformat code ' + 'after applying fixes') + parser.add_argument('-p', dest='build_path', + help='Path used to read a compile command database.') + parser.add_argument('-extra-arg', dest='extra_arg', + action='append', default=[], + help='Additional argument to append to the compiler ' + 'command line.') + parser.add_argument('-extra-arg-before', dest='extra_arg_before', + action='append', default=[], + help='Additional argument to prepend to the compiler ' + 'command line.') + parser.add_argument('-quiet', action='store_true', + help='Run clang-tidy in quiet mode') + args = parser.parse_args() + + db_path = 'compile_commands.json' + + if args.build_path is not None: + build_path = args.build_path + else: + # Find our database + build_path = find_compilation_database(db_path) + + try: + invocation = [args.clang_tidy_binary, '-list-checks'] + invocation.append('-p=' + build_path) + if args.checks: + invocation.append('-checks=' + args.checks) + invocation.append('-') + print subprocess.check_output(invocation) + except: + print >>sys.stderr, "Unable to run clang-tidy." + sys.exit(1) + + # Load the database and extract all files. + database = json.load(open(os.path.join(build_path, db_path))) + files = [entry['file'] for entry in database] + + max_task = args.j + if max_task == 0: + max_task = multiprocessing.cpu_count() + + tmpdir = None + if args.fix: + tmpdir = tempfile.mkdtemp() + + # Build up a big regexy filter from all command line arguments. + file_name_re = re.compile('(' + ')|('.join(args.files) + ')') + + try: + # Spin up a bunch of tidy-launching threads. + results = [None] * max_task + queue = Queue.Queue(max_task) + for i in range(max_task): + t = threading.Thread(target=run_tidy, + args=(args, tmpdir, build_path, queue, results, i)) + t.daemon = True + t.start() + + # Fill the queue with files. + for name in files: + if file_name_re.search(name): + queue.put(name) + + # Wait for all threads to be done. + queue.join() + + except KeyboardInterrupt: + # This is a sad hack. Unfortunately subprocess goes + # bonkers with ctrl-c and we start forking merrily. + print '\nCtrl-C detected, goodbye.' + if args.fix: + shutil.rmtree(tmpdir) + os.kill(0, 9) + + for ret in results: + if ret != 0: + sys.exit(ret) + + if args.fix: + print 'Applying fixes ...' + ret = apply_fixes(args, tmpdir) + if ret != 0: + sys.exit(ret) + +if __name__ == '__main__': + main() |