llvm-mirror/utils/sort_includes.py
Tobias Grosser 051452f517 Add polly support to sort_includes.py
Changes:
 -  Add "isl/" as a system library prefix. Even though isl is regularly
    imported into polly, it is still used like an external library.
 -  Add "json/" as a system library prefix. Polly uses json-cpp as external
    library.
 -  Distinguish between llvm and subproject libraries. Always sort subprojects
    before LLVM. This was already the case with clang, as 'clang' comes before
    'llvm', but we also want 'polly' to be sorted before 'llvm'.

The sorting of headers that are not part of Polly or isl remains unchanged.

llvm-svn: 236929
2015-05-09 09:08:56 +00:00

94 lines
2.8 KiB
Python
Executable File

#!/usr/bin/env python
"""Script to sort the top-most block of #include lines.
Assumes the LLVM coding conventions.
Currently, this script only bothers sorting the llvm/... headers. Patches
welcome for more functionality, and sorting other header groups.
"""
import argparse
import os
def sort_includes(f):
"""Sort the #include lines of a specific file."""
# Skip files which are under INPUTS trees or test trees.
if 'INPUTS/' in f.name or 'test/' in f.name:
return
ext = os.path.splitext(f.name)[1]
if ext not in ['.cpp', '.c', '.h', '.inc', '.def']:
return
lines = f.readlines()
look_for_api_header = ext in ['.cpp', '.c']
found_headers = False
headers_begin = 0
headers_end = 0
api_headers = []
local_headers = []
subproject_headers = []
llvm_headers = []
system_headers = []
for (i, l) in enumerate(lines):
if l.strip() == '':
continue
if l.startswith('#include'):
if not found_headers:
headers_begin = i
found_headers = True
headers_end = i
header = l[len('#include'):].lstrip()
if look_for_api_header and header.startswith('"'):
api_headers.append(header)
look_for_api_header = False
continue
if (header.startswith('<') or header.startswith('"gtest/') or
header.startswith('"isl/') or header.startswith('"json/')):
system_headers.append(header)
continue
if (header.startswith('"clang/') or header.startswith('"clang-c/') or
header.startswith('"polly/')):
subproject_headers.append(header)
continue
if (header.startswith('"llvm/') or header.startswith('"llvm-c/')):
llvm_headers.append(header)
continue
local_headers.append(header)
continue
# Only allow comments and #defines prior to any includes. If either are
# mixed with includes, the order might be sensitive.
if found_headers:
break
if l.startswith('//') or l.startswith('#define') or l.startswith('#ifndef'):
continue
break
if not found_headers:
return
local_headers = sorted(set(local_headers))
subproject_headers = sorted(set(subproject_headers))
llvm_headers = sorted(set(llvm_headers))
system_headers = sorted(set(system_headers))
headers = api_headers + local_headers + subproject_headers + llvm_headers + system_headers
header_lines = ['#include ' + h for h in headers]
lines = lines[:headers_begin] + header_lines + lines[headers_end + 1:]
f.seek(0)
f.truncate()
f.writelines(lines)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('files', nargs='+', type=argparse.FileType('r+'),
help='the source files to sort includes within')
args = parser.parse_args()
for f in args.files:
sort_includes(f)
if __name__ == '__main__':
main()