xref: /llvm-project/libcxx/test/libcxx/lint/lint_headers.sh.py (revision 6fd27d5b0321f65c8a09624e456e33874ae3730b)
1# RUN: %{python} %s
2
3# Verify that each run of consecutive #include directives
4# in each libcxx/include/ header is maintained in alphabetical order.
5
6import glob
7import os
8import re
9
10
11def exclude_from_consideration(path):
12    return (
13        path.endswith(".txt")
14        or path.endswith(".modulemap")
15        or os.path.basename(path) == "__config"
16        or os.path.basename(path) == "__config_site.in"
17        or os.path.basename(path) == "libcxx.imp"
18        or os.path.basename(path).startswith("__pstl")
19        or not os.path.isfile(path)  # TODO: Remove once PSTL integration is finished
20    )
21
22
23def check_for_pragma_GCC_system_header(pretty_fname, lines):
24    if pretty_fname not in ["__undef_macros"]:
25        for line in lines:
26            if re.match("# *pragma GCC system_header\n", line):
27                return True
28        print(
29            "FAILED TO FIND #  pragma GCC system_header in libcxx/include/%s"
30            % pretty_fname
31        )
32        return False
33    return True
34
35
36if __name__ == "__main__":
37    libcxx_test_libcxx_lint = os.path.dirname(os.path.abspath(__file__))
38    libcxx_include = os.path.abspath(
39        os.path.join(libcxx_test_libcxx_lint, "../../../include")
40    )
41    assert os.path.isdir(libcxx_include)
42
43    def pretty(path):
44        return path[len(libcxx_include) + 1 :]
45
46    all_headers = [
47        p
48        for p in (
49            glob.glob(os.path.join(libcxx_include, "*"))
50            + glob.glob(os.path.join(libcxx_include, "__*/*.h"))
51        )
52        if not exclude_from_consideration(p)
53    ]
54
55    okay = True
56    for fname in all_headers:
57        pretty_fname = pretty(fname)
58        with open(fname, "r") as f:
59            lines = f.readlines()
60
61        okay = check_for_pragma_GCC_system_header(pretty_fname, lines) and okay
62
63    assert okay
64