cpp_lint.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. from __future__ import print_function
  9. import common_lint
  10. import re
  11. import sys
  12. def VerifyIncludes(filename, lines):
  13. """Makes sure the #includes are in proper order and no disallows files are
  14. #included.
  15. Args:
  16. filename: the file under consideration as string
  17. lines: contents of the file as string array
  18. """
  19. lint = []
  20. include_gtest_re = re.compile(r'^#include "gtest/(.*)"')
  21. include_llvm_re = re.compile(r'^#include "llvm/(.*)"')
  22. include_support_re = re.compile(r'^#include "(Support/.*)"')
  23. include_config_re = re.compile(r'^#include "(Config/.*)"')
  24. include_system_re = re.compile(r'^#include <(.*)>')
  25. DISALLOWED_SYSTEM_HEADERS = ['iostream']
  26. line_num = 1
  27. prev_config_header = None
  28. prev_system_header = None
  29. for line in lines:
  30. # TODO: implement private headers
  31. # TODO: implement gtest headers
  32. # TODO: implement top-level llvm/* headers
  33. # TODO: implement llvm/Support/* headers
  34. # Process Config/* headers
  35. config_header = include_config_re.match(line)
  36. if config_header:
  37. curr_config_header = config_header.group(1)
  38. if prev_config_header:
  39. if prev_config_header > curr_config_header:
  40. lint.append((filename, line_num,
  41. 'Config headers not in order: "%s" before "%s"' % (
  42. prev_config_header, curr_config_header)))
  43. # Process system headers
  44. system_header = include_system_re.match(line)
  45. if system_header:
  46. curr_system_header = system_header.group(1)
  47. # Is it blacklisted?
  48. if curr_system_header in DISALLOWED_SYSTEM_HEADERS:
  49. lint.append((filename, line_num,
  50. 'Disallowed system header: <%s>' % curr_system_header))
  51. elif prev_system_header:
  52. # Make sure system headers are alphabetized amongst themselves
  53. if prev_system_header > curr_system_header:
  54. lint.append((filename, line_num,
  55. 'System headers not in order: <%s> before <%s>' % (
  56. prev_system_header, curr_system_header)))
  57. prev_system_header = curr_system_header
  58. line_num += 1
  59. return lint
  60. class CppLint(common_lint.BaseLint):
  61. MAX_LINE_LENGTH = 80
  62. def RunOnFile(self, filename, lines):
  63. lint = []
  64. lint.extend(VerifyIncludes(filename, lines))
  65. lint.extend(common_lint.VerifyLineLength(filename, lines,
  66. CppLint.MAX_LINE_LENGTH))
  67. lint.extend(common_lint.VerifyTabs(filename, lines))
  68. lint.extend(common_lint.VerifyTrailingWhitespace(filename, lines))
  69. return lint
  70. def CppLintMain(filenames):
  71. all_lint = common_lint.RunLintOverAllFiles(CppLint(), filenames)
  72. for lint in all_lint:
  73. print('%s:%d:%s' % (lint[0], lint[1], lint[2]))
  74. return 0
  75. if __name__ == '__main__':
  76. sys.exit(CppLintMain(sys.argv[1:]))