xref: /llvm-project/llvm/utils/lint/cpp_lint.py (revision a250160ec7c43aecceca492a620165e239a72e1c)
1#!/usr/bin/python
2#
3# Checks C++ files to make sure they conform to LLVM standards, as specified in
4# http://llvm.org/docs/CodingStandards.html .
5#
6# TODO: add unittests for the verifier functions:
7# http://docs.python.org/library/unittest.html .
8
9import common_lint
10import re
11import sys
12
13def VerifyIncludes(filename, lines):
14  """Makes sure the #includes are in proper order and no disallows files are
15  #included.
16
17  Args:
18    filename: the file under consideration as string
19    lines: contents of the file as string array
20  """
21  include_gtest_re = re.compile(r'^#include "gtest/(.*)"')
22  include_llvm_re = re.compile(r'^#include "llvm/(.*)"')
23  include_support_re = re.compile(r'^#include "(Support/.*)"')
24  include_config_re = re.compile(r'^#include "(Config/.*)"')
25  include_system_re = re.compile(r'^#include <(.*)>')
26
27  DISALLOWED_SYSTEM_HEADERS = ['iostream']
28
29  line_num = 1
30  prev_config_header = None
31  prev_system_header = None
32  for line in lines:
33    # TODO: implement private headers
34    # TODO: implement gtest headers
35    # TODO: implement top-level llvm/* headers
36    # TODO: implement llvm/Support/* headers
37
38    # Process Config/* headers
39    config_header = include_config_re.match(line)
40    if config_header:
41      curr_config_header = config_header.group(1)
42      if prev_config_header:
43        if prev_config_header > curr_config_header:
44          print '%s:%d:Config headers not in order: "%s" before "%s" ' % (
45              filename, line_num, prev_config_header, curr_config_header)
46
47    # Process system headers
48    system_header = include_system_re.match(line)
49    if system_header:
50      curr_system_header = system_header.group(1)
51
52      # Is it blacklisted?
53      if curr_system_header in DISALLOWED_SYSTEM_HEADERS:
54        print '%s:%d:Disallowed system header: <%s>' % (
55            filename, line_num, curr_system_header)
56      elif prev_system_header:
57        # Make sure system headers are alphabetized amongst themselves
58        if prev_system_header > curr_system_header:
59          print '%s:%d:System headers not in order: <%s> before <%s>' % (
60              filename, line_num, prev_system_header, curr_system_header)
61
62      prev_system_header = curr_system_header
63
64    line_num += 1
65
66
67class CppLint(common_lint.BaseLint):
68  MAX_LINE_LENGTH = 80
69
70  def RunOnFile(self, filename, lines):
71    VerifyIncludes(filename, lines)
72    common_lint.VerifyLineLength(filename, lines, CppLint.MAX_LINE_LENGTH)
73    common_lint.VerifyTrailingWhitespace(filename, lines)
74
75
76def CppLintMain(filenames):
77  common_lint.RunLintOverAllFiles(CppLint(), filenames)
78  return 0
79
80
81if __name__ == '__main__':
82  sys.exit(CppLintMain(sys.argv[1:]))
83