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