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