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