From 653222fc997be323af28d05b98e26daa0b98f477 Mon Sep 17 00:00:00 2001 From: Misha Brukman Date: Fri, 2 Jan 2009 21:15:30 +0000 Subject: [PATCH] Added some basic lint tools for C++ and generic lint tool applicable to all types of files (TableGen, LLVM assembly, HTML files, etc.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61592 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/lint/common_lint.py | 58 +++++++++++++++++ utils/lint/cpp_lint.py | 80 ++++++++++++++++++++++++ utils/lint/generic_lint.py | 24 +++++++ utils/lint/remove_trailing_whitespace.sh | 6 ++ 4 files changed, 168 insertions(+) create mode 100644 utils/lint/common_lint.py create mode 100755 utils/lint/cpp_lint.py create mode 100755 utils/lint/generic_lint.py create mode 100755 utils/lint/remove_trailing_whitespace.sh diff --git a/utils/lint/common_lint.py b/utils/lint/common_lint.py new file mode 100644 index 00000000000..95670316654 --- /dev/null +++ b/utils/lint/common_lint.py @@ -0,0 +1,58 @@ +#!/usr/bin/python +# +# Common lint functions applicable to multiple types of files. + +import re + +def VerifyLineLength(filename, lines, max_length): + """Checkes to make sure the file has no lines with lines exceeding the length + limit. + + Args: + filename: the file under consideration as string + lines: contents of the file as string array + max_length: maximum acceptable line length as number + """ + line_num = 1 + for line in lines: + length = len(line.rstrip()) # strip off EOL char(s) + if length > max_length: + print '%s:%d:Line exceeds %d chars (%d)' % (filename, line_num, + max_length, length) + line_num += 1 + + +def VerifyTrailingWhitespace(filename, lines): + """Checkes to make sure the file has no lines with trailing whitespace. + + Args: + filename: the file under consideration as string + lines: contents of the file as string array + """ + trailing_whitespace_re = re.compile(r'\s+$') + line_num = 1 + for line in lines: + if trailing_whitespace_re.match(line): + print '%s:%d:Trailing whitespace' % (filename, line_num) + line_num += 1 + + +class BaseLint: + def RunOnFile(filename, lines): + raise Exception('RunOnFile() unimplemented') + + +def RunLintOverAllFiles(lint, filenames): + """Runs linter over the contents of all files. + + Args: + lint: subclass of BaseLint, implementing RunOnFile() + filenames: list of all files whose contents will be linted + """ + for filename in filenames: + file = open(filename, 'r') + if not file: + print 'Cound not open %s' % filename + continue + lines = file.readlines() + lint.RunOnFile(filename, lines) diff --git a/utils/lint/cpp_lint.py b/utils/lint/cpp_lint.py new file mode 100755 index 00000000000..e26fb707c96 --- /dev/null +++ b/utils/lint/cpp_lint.py @@ -0,0 +1,80 @@ +#!/usr/bin/python +# +# Checks C++ files to make sure they conform to LLVM standards, as specified in +# http://llvm.org/docs/CodingStandards.html . +# +# TODO: add unittests for the verifier functions: +# http://docs.python.org/library/unittest.html . + +import common_lint +import re +import sys + +def VerifyIncludes(filename, lines): + """Makes sure the #includes are in proper order and no disallows files are + #included. + + Args: + filename: the file under consideration as string + lines: contents of the file as string array + """ + include_gtest_re = re.compile(r'^#include "gtest/(.*)"') + include_llvm_re = re.compile(r'^#include "llvm/(.*)"') + include_support_re = re.compile(r'^#include "(Support/.*)"') + include_config_re = re.compile(r'^#include "(Config/.*)"') + include_system_re = re.compile(r'^#include <(.*)>') + + DISALLOWED_SYSTEM_HEADERS = ['iostream'] + + line_num = 1 + prev_config_header = None + prev_system_header = None + for line in lines: + # TODO: implement private headers + # TODO: implement gtest headers + # TODO: implement top-level llvm/* headers + # TODO: implement llvm/Support/* headers + + # Process Config/* headers + config_header = include_config_re.match(line) + if config_header: + curr_config_header = config_header.group(1) + if prev_config_header: + if prev_config_header > curr_config_header: + print '%s:%d:Config headers not in order: "%s" before "%s" ' % ( + filename, line_num, prev_config_header, curr_config_header) + + # Process system headers + system_header = include_system_re.match(line) + if system_header: + curr_system_header = system_header.group(1) + + # Is it blacklisted? + if curr_system_header in DISALLOWED_SYSTEM_HEADERS: + print '%s:%d:Disallowed system header: <%s>' % ( + filename, line_num, curr_system_header) + elif prev_system_header: + # Make sure system headers are alphabetized amongst themselves + if prev_system_header > curr_system_header: + print '%s:%d:System headers not in order: <%s> before <%s>' % ( + filename, line_num, prev_system_header, curr_system_header) + + prev_system_header = curr_system_header + + line_num += 1 + + +class CppLint(common_lint.BaseLint): + def RunOnFile(self, filename, lines): + VerifyIncludes(filename, lines) + common_lint.VerifyLineLength(filename, lines) + common_lint.VerifyTrailingWhitespace(filename, lines) + + +def CppLintMain(filenames): + common_lint.RunLintOverAllFiles(CppLint(), filenames) + return 0 + + +if __name__ == '__main__': + sys.exit(CppLintMain(sys.argv[1:])) diff --git a/utils/lint/generic_lint.py b/utils/lint/generic_lint.py new file mode 100755 index 00000000000..c8f4835bb6a --- /dev/null +++ b/utils/lint/generic_lint.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +# +# Checks files to make sure they conform to LLVM standards which can be applied +# to any programming language: at present, line length and trailing whitespace. + +import common_lint +import sys + +class GenericCodeLint(common_lint.BaseLint): + MAX_LINE_LENGTH = 80 + + def RunOnFile(self, filename, lines): + common_lint.VerifyLineLength(filename, lines, + GenericCodeLint.MAX_LINE_LENGTH) + common_lint.VerifyTrailingWhitespace(filename, lines) + + +def GenericCodeLintMain(filenames): + common_lint.RunLintOverAllFiles(GenericCodeLint(), filenames) + return 0 + + +if __name__ == '__main__': + sys.exit(GenericCodeLintMain(sys.argv[1:])) diff --git a/utils/lint/remove_trailing_whitespace.sh b/utils/lint/remove_trailing_whitespace.sh new file mode 100755 index 00000000000..de58dbab7fc --- /dev/null +++ b/utils/lint/remove_trailing_whitespace.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Deletes trailing whitespace in-place in the passed-in files. +# Sample syntax: +# $0 *.cpp + +perl -pi -e "s/\s+\$//" $*