Masahiro Yamada | 074075a | 2021-02-02 15:06:04 +0900 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Nathan Huckleberry | 6ad7cbc | 2020-08-22 23:56:18 +0900 | [diff] [blame] | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | # |
| 4 | # Copyright (C) Google LLC, 2020 |
| 5 | # |
| 6 | # Author: Nathan Huckleberry <nhuck@google.com> |
| 7 | # |
| 8 | """A helper routine run clang-tidy and the clang static-analyzer on |
| 9 | compile_commands.json. |
| 10 | """ |
| 11 | |
| 12 | import argparse |
| 13 | import json |
| 14 | import multiprocessing |
| 15 | import os |
| 16 | import subprocess |
| 17 | import sys |
| 18 | |
| 19 | |
| 20 | def parse_arguments(): |
| 21 | """Set up and parses command-line arguments. |
| 22 | Returns: |
| 23 | args: Dict of parsed args |
| 24 | Has keys: [path, type] |
| 25 | """ |
| 26 | usage = """Run clang-tidy or the clang static-analyzer on a |
| 27 | compilation database.""" |
| 28 | parser = argparse.ArgumentParser(description=usage) |
| 29 | |
| 30 | type_help = "Type of analysis to be performed" |
| 31 | parser.add_argument("type", |
| 32 | choices=["clang-tidy", "clang-analyzer"], |
| 33 | help=type_help) |
| 34 | path_help = "Path to the compilation database to parse" |
| 35 | parser.add_argument("path", type=str, help=path_help) |
| 36 | |
| 37 | return parser.parse_args() |
| 38 | |
| 39 | |
| 40 | def init(l, a): |
| 41 | global lock |
| 42 | global args |
| 43 | lock = l |
| 44 | args = a |
| 45 | |
| 46 | |
| 47 | def run_analysis(entry): |
| 48 | # Disable all checks, then re-enable the ones we want |
| 49 | checks = "-checks=-*," |
| 50 | if args.type == "clang-tidy": |
| 51 | checks += "linuxkernel-*" |
| 52 | else: |
| 53 | checks += "clang-analyzer-*" |
| 54 | p = subprocess.run(["clang-tidy", "-p", args.path, checks, entry["file"]], |
| 55 | stdout=subprocess.PIPE, |
| 56 | stderr=subprocess.STDOUT, |
| 57 | cwd=entry["directory"]) |
| 58 | with lock: |
| 59 | sys.stderr.buffer.write(p.stdout) |
| 60 | |
| 61 | |
| 62 | def main(): |
| 63 | args = parse_arguments() |
| 64 | |
| 65 | lock = multiprocessing.Lock() |
| 66 | pool = multiprocessing.Pool(initializer=init, initargs=(lock, args)) |
| 67 | # Read JSON data into the datastore variable |
| 68 | with open(args.path, "r") as f: |
| 69 | datastore = json.load(f) |
| 70 | pool.map(run_analysis, datastore) |
| 71 | |
| 72 | |
| 73 | if __name__ == "__main__": |
| 74 | main() |