1#!/usr/bin/env python3 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 9compile_commands.json. 10""" 11 12import argparse 13import json 14import multiprocessing 15import os 16import subprocess 17import sys 18 19 20def 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 40def init(l, a): 41 global lock 42 global args 43 lock = l 44 args = a 45 46 47def 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 checks += ",-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling" 55 p = subprocess.run(["clang-tidy", "-p", args.path, checks, entry["file"]], 56 stdout=subprocess.PIPE, 57 stderr=subprocess.STDOUT, 58 cwd=entry["directory"]) 59 with lock: 60 sys.stderr.buffer.write(p.stdout) 61 62 63def main(): 64 args = parse_arguments() 65 66 lock = multiprocessing.Lock() 67 pool = multiprocessing.Pool(initializer=init, initargs=(lock, args)) 68 # Read JSON data into the datastore variable 69 with open(args.path, "r") as f: 70 datastore = json.load(f) 71 pool.map(run_analysis, datastore) 72 73 74if __name__ == "__main__": 75 main() 76