cpp_lint.py 3.0 KB

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