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