1# 2# Copyright 2009, Alexandre Deckner, alex@zappotek.com 3# Distributed under the terms of the MIT License. 4# 5import re, sys, os 6from utils import * 7 8 9def processMatches(matches, name, text, highlights): 10 for match in matches: 11 printMatch(name, match, text) 12 highlights.append((match.start(), match.end(), name)) 13 14 15def run(fileSet, rules, outputFileName): 16 openHtml(fileSet, outputFileName) 17 18 for fileName in fileSet: 19 print "\nChecking " + fileName + ":" 20 file = open(fileName, 'r') 21 text = file.read() 22 23 highlights = [] 24 25 for name, regexp in rules.items(): 26 processMatches(regexp.finditer(text), name, text, highlights) 27 28 highlights.sort() 29 highlights = checkHighlights(highlights) 30 31 file.close() 32 33 renderHtml(text, highlights, fileName, outputFileName) 34 35 closeHtml(outputFileName) 36 37 38def visit(result, dir, names): 39 extensions = [".cpp", ".h"] 40 names.remove(".svn") 41 for name in names: 42 path = os.path.join(dir, name) 43 if os.path.isfile(path) and os.path.splitext(name)[1] in extensions: 44 print "adding", path 45 result.append(path) 46 47 48cppRules = {} 49cppRules["Line over 80 char"] = re.compile('[^\n]{81,}') 50cppRules["Spaces instead of tabs"] = re.compile(' ') 51cppRules["Missing space after control statement"] \ 52 = re.compile('(for|if|while|switch)\(') 53cppRules["Missing space at comment start"] = re.compile('//\w') 54cppRules["Missing space after operator"] \ 55 = re.compile('\w(==|[,=>/+\-*;\|])\w') 56cppRules["Operator at line end"] = re.compile('([*=/+\-\|\&\?]|\&&|\|\|)(?=\n)') 57cppRules["Missing space"] = re.compile('\){') 58cppRules["Mixed tabs/spaces"] = re.compile('( \t]|\t )+') 59cppRules["Malformed else"] = re.compile('}[ \t]*\n[ \t]*else') 60cppRules["Lines between functions > 2"] \ 61 = re.compile('(?<=\n})([ \t]*\n){3,}(?=\n)') 62cppRules["Lines between functions < 2"] \ 63 = re.compile('(?<=\n})([ \t]*\n){0,2}(?=.)') 64cppRules["Windows Line Ending"] = re.compile('\r') 65cppRules["Bad pointer/reference style"] \ 66 = re.compile('(?<=\w) [*&](?=(\w|[,\)]))') 67 68# TODO: ignore some rules in comments 69#cppRules["-Comment 1"] = re.compile('[^/]/\*(.|[\r\n])*?\*/') 70#cppRules["-Comment 2"] = re.compile('(//)[^\n]*') 71 72 73if len(sys.argv) >= 2 and sys.argv[1] != "--help": 74 files = [] 75 for arg in sys.argv[1:]: 76 if os.path.isfile(arg): 77 files.append(arg) 78 else: 79 os.path.walk(arg, visit, files) 80 run(files, cppRules, "styleviolations.html") 81else: 82 print "Usage: python checkstyle.py file.cpp [file2.cpp] [directory]\n" 83 print "Checks c++ source files against the Haiku Coding Guidelines." 84 print "Outputs an html report in the styleviolations.html file.\n" 85