1#!/usr/bin/env python 2# 3# Common lint functions applicable to multiple types of files. 4 5from __future__ import print_function 6import re 7 8 9def VerifyLineLength(filename, lines, max_length): 10 """Checks to make sure the file has no lines with lines exceeding the length 11 limit. 12 13 Args: 14 filename: the file under consideration as string 15 lines: contents of the file as string array 16 max_length: maximum acceptable line length as number 17 18 Returns: 19 A list of tuples with format [(filename, line number, msg), ...] with any 20 violations found. 21 """ 22 lint = [] 23 line_num = 1 24 for line in lines: 25 length = len(line.rstrip("\n")) 26 if length > max_length: 27 lint.append( 28 ( 29 filename, 30 line_num, 31 "Line exceeds %d chars (%d)" % (max_length, length), 32 ) 33 ) 34 line_num += 1 35 return lint 36 37 38def VerifyTabs(filename, lines): 39 """Checks to make sure the file has no tab characters. 40 41 Args: 42 filename: the file under consideration as string 43 lines: contents of the file as string array 44 45 Returns: 46 A list of tuples with format [(line_number, msg), ...] with any violations 47 found. 48 """ 49 lint = [] 50 tab_re = re.compile(r"\t") 51 line_num = 1 52 for line in lines: 53 if tab_re.match(line.rstrip("\n")): 54 lint.append((filename, line_num, "Tab found instead of whitespace")) 55 line_num += 1 56 return lint 57 58 59def VerifyTrailingWhitespace(filename, lines): 60 """Checks to make sure the file has no lines with trailing whitespace. 61 62 Args: 63 filename: the file under consideration as string 64 lines: contents of the file as string array 65 66 Returns: 67 A list of tuples with format [(filename, line number, msg), ...] with any 68 violations found. 69 """ 70 lint = [] 71 trailing_whitespace_re = re.compile(r"\s+$") 72 line_num = 1 73 for line in lines: 74 if trailing_whitespace_re.match(line.rstrip("\n")): 75 lint.append((filename, line_num, "Trailing whitespace")) 76 line_num += 1 77 return lint 78 79 80class BaseLint: 81 def RunOnFile(filename, lines): 82 raise Exception("RunOnFile() unimplemented") 83 84 85def RunLintOverAllFiles(linter, filenames): 86 """Runs linter over the contents of all files. 87 88 Args: 89 lint: subclass of BaseLint, implementing RunOnFile() 90 filenames: list of all files whose contents will be linted 91 92 Returns: 93 A list of tuples with format [(filename, line number, msg), ...] with any 94 violations found. 95 """ 96 lint = [] 97 for filename in filenames: 98 file = open(filename, "r") 99 if not file: 100 print("Could not open %s" % filename) 101 continue 102 lines = file.readlines() 103 lint.extend(linter.RunOnFile(filename, lines)) 104 105 return lint 106