diff --git a/clang/utils/analyzer/SATestBuild.py b/clang/utils/analyzer/SATestBuild.py --- a/clang/utils/analyzer/SATestBuild.py +++ b/clang/utils/analyzer/SATestBuild.py @@ -60,8 +60,8 @@ from queue import Queue from subprocess import CalledProcessError, check_call -from typing import (cast, Dict, Iterable, IO, List, NamedTuple, Tuple, - TYPE_CHECKING) +from typing import (cast, Dict, Iterable, IO, List, NamedTuple, Optional, + Tuple, TYPE_CHECKING) ############################################################################### @@ -93,13 +93,15 @@ # Find Clang for static analysis. if 'CC' in os.environ: - CLANG = os.environ['CC'] + cc_candidate: Optional[str] = os.environ['CC'] else: - CLANG = SATestUtils.which("clang", os.environ['PATH']) -if not CLANG: + cc_candidate = SATestUtils.which("clang", os.environ['PATH']) +if not cc_candidate: stderr("Error: cannot find 'clang' in PATH") sys.exit(1) +CLANG = cc_candidate + # Number of jobs. MAX_JOBS = int(math.ceil(multiprocessing.cpu_count() * 0.75)) @@ -204,8 +206,9 @@ cwd = os.path.join(directory, PATCHED_SOURCE_DIR_NAME) script_path = os.path.join(directory, CLEANUP_SCRIPT) - SATestUtils.runScript(script_path, build_log_file, cwd, - Stdout=LOCAL.stdout, Stderr=LOCAL.stderr) + SATestUtils.run_script(script_path, build_log_file, cwd, + out=LOCAL.stdout, err=LOCAL.stderr, + verbose=VERBOSE) def download_and_patch(directory: str, build_log_file: IO): @@ -238,8 +241,9 @@ Run the script to download the project, if it exists. """ script_path = os.path.join(directory, DOWNLOAD_SCRIPT) - SATestUtils.runScript(script_path, build_log_file, directory, - Stdout=LOCAL.stdout, Stderr=LOCAL.stderr) + SATestUtils.run_script(script_path, build_log_file, directory, + out=LOCAL.stdout, err=LOCAL.stderr, + verbose=VERBOSE) def apply_patch(directory: str, build_log_file: IO): @@ -557,9 +561,9 @@ failed = False # Only run the analyzes on supported files. - if SATestUtils.hasNoExtension(file_name): + if SATestUtils.has_no_extension(file_name): continue - if not SATestUtils.isValidSingleInputFile(file_name): + if not SATestUtils.is_valid_single_input_file(file_name): stderr(f"Error: Invalid single input file {full_file_name}.\n") raise Exception() @@ -859,7 +863,7 @@ map_file.seek(0) # TODO: csv format is not very readable, change it to JSON for project_info in csv.reader(map_file): - if (SATestUtils.isCommentCSVLine(project_info)): + if SATestUtils.is_comment_csv_line(project_info): continue # suppress mypy error yield cast(Tuple[str, str], project_info) diff --git a/clang/utils/analyzer/SATestUtils.py b/clang/utils/analyzer/SATestUtils.py --- a/clang/utils/analyzer/SATestUtils.py +++ b/clang/utils/analyzer/SATestUtils.py @@ -1,12 +1,11 @@ import os -from subprocess import check_call import sys +from subprocess import CalledProcessError, check_call +from typing import List, IO, Optional -Verbose = 1 - -def which(command, paths=None): +def which(command: str, paths: Optional[str] = None) -> Optional[str]: """which(command, [paths]) - Look up the given command in the paths string (or the PATH environment variable, if unspecified).""" @@ -38,41 +37,44 @@ return None -def hasNoExtension(FileName): - (Root, Ext) = os.path.splitext(FileName) - return (Ext == "") +def has_no_extension(file_name: str) -> bool: + root, ext = os.path.splitext(file_name) + return ext == "" -def isValidSingleInputFile(FileName): - (Root, Ext) = os.path.splitext(FileName) - return Ext in (".i", ".ii", ".c", ".cpp", ".m", "") +def is_valid_single_input_file(file_name: str) -> bool: + root, ext = os.path.splitext(file_name) + return ext in (".i", ".ii", ".c", ".cpp", ".m", "") -def runScript(ScriptPath, PBuildLogFile, Cwd, Stdout=sys.stdout, - Stderr=sys.stderr): +def run_script(script_path: str, build_log_file: IO, cwd: str, + out=sys.stdout, err=sys.stderr, verbose: int = 0): """ Run the provided script if it exists. """ - if os.path.exists(ScriptPath): + if os.path.exists(script_path): try: - if Verbose == 1: - Stdout.write(" Executing: %s\n" % (ScriptPath,)) - check_call("chmod +x '%s'" % ScriptPath, cwd=Cwd, - stderr=PBuildLogFile, - stdout=PBuildLogFile, + if verbose == 1: + out.write(f" Executing: {script_path}\n") + + check_call(f"chmod +x '{script_path}'", cwd=cwd, + stderr=build_log_file, + stdout=build_log_file, shell=True) - check_call("'%s'" % ScriptPath, cwd=Cwd, - stderr=PBuildLogFile, - stdout=PBuildLogFile, + + check_call(f"'{script_path}'", cwd=cwd, + stderr=build_log_file, + stdout=build_log_file, shell=True) - except: - Stderr.write("Error: Running %s failed. See %s for details.\n" % ( - ScriptPath, PBuildLogFile.name)) + + except CalledProcessError: + err.write(f"Error: Running {script_path} failed. " + f"See {build_log_file.name} for details.\n") sys.exit(-1) -def isCommentCSVLine(Entries): +def is_comment_csv_line(entries: List[str]) -> bool: """ Treat CSV lines starting with a '#' as a comment. """ - return len(Entries) > 0 and Entries[0].startswith("#") + return len(entries) > 0 and entries[0].startswith("#")