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