Author: aldeck Date: 2009-11-05 04:23:50 +0100 (Thu, 05 Nov 2009) New Revision: 33889 Changeset: http://dev.haiku-os.org/changeset/33889/haiku Modified: haiku/trunk/src/tools/checkstyle/checkstyle.py haiku/trunk/src/tools/checkstyle/utils.py Log: * Add multi file/directory support * Refined some rules to not include the new-line * Added 'windows line ending' rule * Enhanced the html output, not an expert there though Modified: haiku/trunk/src/tools/checkstyle/checkstyle.py =================================================================== --- haiku/trunk/src/tools/checkstyle/checkstyle.py 2009-11-05 00:47:27 UTC (rev 33888) +++ haiku/trunk/src/tools/checkstyle/checkstyle.py 2009-11-05 03:23:50 UTC (rev 33889) @@ -2,7 +2,7 @@ # Copyright 2009, Alexandre Deckner, alex@xxxxxxxxxxxx # Distributed under the terms of the MIT License. # -import re, sys +import re, sys, os from utils import * @@ -12,44 +12,73 @@ highlights.append((match.start(), match.end(), name)) -def run(sourceFile, rules): - file = open(sourceFile, 'r') - text = file.read() +def run(fileSet, rules, outputFileName): + openHtml(fileSet, outputFileName) - highlights = [] + for fileName in fileSet: + print "\nChecking " + fileName + ":" + file = open(fileName, 'r') + text = file.read() - for name, regexp in rules.items(): - processMatches(regexp.finditer(text), name, text, highlights) + highlights = [] - highlights.sort() - highlights = checkHighlights(highlights) + for name, regexp in rules.items(): + processMatches(regexp.finditer(text), name, text, highlights) - file.close() - renderHtml(text, highlights, sourceFile, "styleviolations.html") + highlights.sort() + highlights = checkHighlights(highlights) + file.close() + renderHtml(text, highlights, fileName, outputFileName) + + closeHtml(outputFileName) + + +# make a flat list of files recursively from the arg list +def makeFileSet(args): + files = [] + extensions = [".cpp", ".h"] + for arg in args: + if os.path.isfile(arg) and os.path.splitext(arg)[1] in extensions: + files.append(arg) + elif os.path.isdir(arg): + for content in os.listdir(arg): + path = os.path.join(arg, content) + if os.path.isfile(path) \ + and os.path.splitext(path)[1] in extensions: + files.append(path) + elif os.path.isdir(path) and os.path.basename(path) != ".svn": + files.extend(makeFileSet([path])) + return files + + cppRules = {} cppRules["Line over 80 char"] = re.compile('[^\n]{81,}') cppRules["Spaces instead of tabs"] = re.compile(' ') -cppRules["Missing space after for/if/select/while"] = re.compile('(for|if|select|while)\(') +cppRules["Missing space after for/if/select/while"] \ + = re.compile('(for|if|select|while)\(') cppRules["Missing space at comment start"] = re.compile('//[a-zA-Z0-9]') cppRules["Missing space after operator"] \ = re.compile('[a-zA-Z0-9](==|[,=>/+\-*;\|])[a-zA-Z0-9]') -cppRules["Operator at line end"] = re.compile('([*=/+\-\|\&\?]|\&&|\|\|)\n') +cppRules["Operator at line end"] = re.compile('([*=/+\-\|\&\?]|\&&|\|\|)(?=\n)') cppRules["Missing space"] = re.compile('\){') cppRules["Mixed tabs/spaces"] = re.compile('( \t]|\t )+') cppRules["Malformed else"] = re.compile('}[ \t]*\n[ \t]*else') -cppRules["Lines between functions > 2"] = re.compile('\n}([ \t]*\n){4,}') -cppRules["Lines between functions < 2"] = re.compile('\n}([ \t]*\n){0,2}.') +cppRules["Lines between functions > 2"] \ + = re.compile('(?<=\n})([ \t]*\n){3,}(?=\n)') +cppRules["Lines between functions < 2"] \ + = re.compile('(?<=\n})([ \t]*\n){0,2}(?=.)') +cppRules["Windows Line Ending"] = re.compile('\r') # TODO: ignore some rules in comments #cppRules["-Comment 1"] = re.compile('[^/]/\*(.|[\r\n])*?\*/') #cppRules["-Comment 2"] = re.compile('(//)[^\n]*') -if len(sys.argv) == 2 and sys.argv[1] != "--help": - run(sys.argv[1], cppRules) +if len(sys.argv) >= 2 and sys.argv[1] != "--help": + run(makeFileSet(sys.argv[1:]), cppRules, "styleviolations.html") else: - print "Usage: python checkstyle.py file.cpp\n" - print "Checks a c++ source file against the Haiku Coding Guidelines." - print "Outputs an highlighted html report in the styleviolations.html file.\n" + print "Usage: python checkstyle.py file.cpp [file2.cpp] [directory]\n" + print "Checks c++ source files against the Haiku Coding Guidelines." + print "Outputs an html report in the styleviolations.html file.\n" Modified: haiku/trunk/src/tools/checkstyle/utils.py =================================================================== --- haiku/trunk/src/tools/checkstyle/utils.py 2009-11-05 00:47:27 UTC (rev 33888) +++ haiku/trunk/src/tools/checkstyle/utils.py 2009-11-05 03:23:50 UTC (rev 33889) @@ -15,29 +15,43 @@ + "): '" + match.group().replace('\n','\\n') + "'" -# render in html, the file style.css is embedded -def renderHtml(text, highlights, sourceFileName, outputFileName): - splittedText = highlightSplit(text, highlights) - - #styleFile = open("style.css") - #style = styleFile.read() - #styleFile.close() - +def openHtml(fileList, outputFileName): file = open(outputFileName, 'w') file.write(""" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";> <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en"> <head> - <title>Style violations in """ + sourceFileName.split('/')[-1] \ - + """</title> + <title>Style violations</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css">""" + cssStyle() + """</style> </head> <body> - <p>""" + sourceFileName + """</p> - <pre class="code">""") + <p><b>File list:</b><br>""") + for fileName in fileList: + file.write(fileName + "<br>") + file.write("</p>") + file.close() + +def closeHtml(outputFileName): + file = open(outputFileName, 'a') + file.write(""" + </pre> + </body> + </html>""") + + file.close() + + +# render in html +def renderHtml(text, highlights, sourceFileName, outputFileName): + splittedText = highlightSplit(text, highlights) + + file = open(outputFileName, 'a') + file.write("<hr/><p><b>" + sourceFileName + "</b></p>") + + # insert highlight tags in a temp buffer temp = "" count = 0 for slice in splittedText: @@ -50,16 +64,20 @@ temp += "</span>" # close the superfluous last highlight + file.write('<table><tr><td><pre class="code"><span class="linenumber">') count = 1 for line in temp.split('\n'): - file.write(str(count).rjust(4) + ' |' + line + '<br>') + file.write(str(count).rjust(4)+"<br>") count += 1 - file.write(""" - </pre> - </body> - </html>""") + file.write('</span></pre></td><td><pre class="code">') + for line in temp.split('\n'): + file.write('<span class="linehead"> </span>' + line.replace('\r', ' ') \ + + '<br>') + + file.write("</pre></td></tr></table>") + file.close() @@ -130,12 +148,36 @@ def cssStyle(): - return """ + return """ .highlight { background: #ffff00; color: #000000; } + .linehead { + background: #ddd; + font-size: 1px; + } + + .highlight .linehead { + background: #ffff00;; + color: #999; + text-align: right; + font-size: 8px; + } + + .linenumber { + background: #eee; + color: #999; + text-align: right; + } + + td { + border-spacing: 0px; + border-width: 0px; + padding: 0px + } + div.code pre { font-family: monospace; }