brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · d30efd0 Raw
110 lines · python
1#!/usr/bin/env python2 3"""Script to sort the top-most block of #include lines.4 5Assumes the LLVM coding conventions.6 7Currently, this script only bothers sorting the llvm/... headers. Patches8welcome for more functionality, and sorting other header groups.9"""10 11import argparse12import os13 14 15def sort_includes(f):16    """Sort the #include lines of a specific file."""17 18    # Skip files which are under INPUTS trees or test trees.19    if "INPUTS/" in f.name or "test/" in f.name:20        return21 22    ext = os.path.splitext(f.name)[1]23    if ext not in [".cpp", ".c", ".h", ".inc", ".def"]:24        return25 26    lines = f.readlines()27    look_for_api_header = ext in [".cpp", ".c"]28    found_headers = False29    headers_begin = 030    headers_end = 031    api_headers = []32    local_headers = []33    subproject_headers = []34    llvm_headers = []35    system_headers = []36    for (i, l) in enumerate(lines):37        if l.strip() == "":38            continue39        if l.startswith("#include"):40            if not found_headers:41                headers_begin = i42                found_headers = True43            headers_end = i44            header = l[len("#include") :].lstrip()45            if look_for_api_header and header.startswith('"'):46                api_headers.append(header)47                look_for_api_header = False48                continue49            if (50                header.startswith("<")51                or header.startswith('"gtest/')52                or header.startswith('"isl/')53                or header.startswith('"json/')54            ):55                system_headers.append(header)56                continue57            if (58                header.startswith('"clang/')59                or header.startswith('"clang-c/')60                or header.startswith('"polly/')61            ):62                subproject_headers.append(header)63                continue64            if header.startswith('"llvm/') or header.startswith('"llvm-c/'):65                llvm_headers.append(header)66                continue67            local_headers.append(header)68            continue69 70        # Only allow comments and #defines prior to any includes. If either are71        # mixed with includes, the order might be sensitive.72        if found_headers:73            break74        if l.startswith("//") or l.startswith("#define") or l.startswith("#ifndef"):75            continue76        break77    if not found_headers:78        return79 80    local_headers = sorted(set(local_headers))81    subproject_headers = sorted(set(subproject_headers))82    llvm_headers = sorted(set(llvm_headers))83    system_headers = sorted(set(system_headers))84    headers = (85        api_headers + local_headers + subproject_headers + llvm_headers + system_headers86    )87    header_lines = ["#include " + h for h in headers]88    lines = lines[:headers_begin] + header_lines + lines[headers_end + 1 :]89 90    f.seek(0)91    f.truncate()92    f.writelines(lines)93 94 95def main():96    parser = argparse.ArgumentParser(description=__doc__)97    parser.add_argument(98        "files",99        nargs="+",100        type=argparse.FileType("r+"),101        help="the source files to sort includes within",102    )103    args = parser.parse_args()104    for f in args.files:105        sort_includes(f)106 107 108if __name__ == "__main__":109    main()110