#!/usr/bin/env python3 # # SPDX-License-Identifier: BSD-3-Clause # SPDX-FileCopyrightText: Copyright TF-RMM Contributors. # SPDX-FileCopyrightText: Copyright Arm Limited and Contributors. # from argparse import ArgumentParser import codecs import os import re import sys import logging from os import access, R_OK from os.path import isfile INCLUDE_RE = re.compile(r"^\s*#\s*include\s\s*(?P<path>[\"<].+[\">])") # exit program with rc def print_error_and_exit(total_errors): if total_errors: print("total: " + str(total_errors) + " errors") sys.exit(1) else: sys.exit(0) def include_paths(lines): """List all include paths in a file. Ignore starting `+` in diff mode.""" pattern = INCLUDE_RE matches = (pattern.match(line) for line in lines) return [m.group("path") for m in matches if m] # check if 'file' is a regular file and it is readable def file_readable(file): if not isfile(file): print(file + ": WARNING: File not found") return 0 if not access(file, R_OK): print(file + ": WARNING: File not readable") return 0 return 1 def file_include_list(path): """Return a list of all include paths in a file or None on failure.""" try: with codecs.open(path, encoding="utf-8") as f: return include_paths(f) except Exception: logging.exception(path + ": ERROR while parsing.") return ([]) def check_includes(file): """Checks whether the order of includes in the file specified in the path is correct or not.""" print("Checking file: " + file) if not file_readable(file): return 0 inc_list = file_include_list(file) # If there are less than 2 includes there's no need to check. if len(inc_list) < 2: return 0 # remove leading and trailing <, > inc_list = [x[1:-1] for x in inc_list] if sorted(inc_list) != inc_list: print(file + ": ERROR: includes not in order. Include order should be " + ', '.join(sorted(inc_list))) return 1 else: return 0 if __name__ == "__main__": ap = ArgumentParser(description='Check #include orders') ap.add_argument('files', nargs='*', help='Check files.') args = ap.parse_args() total_errors = 0 for file in args.files: total_errors += check_includes(file) print_error_and_exit(total_errors)