#!/usr/bin/python # # Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). # # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. # # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. # import sys import glob import getopt import datetime # Check source file for formatting nits # Fill free to add your own rules class NitHunter(object): """Base class, contains controller""" def __init__(self,p_exlist = []): """It's possible to blacklist some rules""" self.exlist = p_exlist self.nits = 0 def execute(self,fileName): """Controller. Enumerate all hunt_* methods, check whether it is blacklisted, execute it and print warning if necessary """ f = file(fileName,"r") lineCount = 0 self.nits = 0 for line in f : lineCount+=1 for name in dir(self) : if name.startswith("hunt_") and not name in self.exlist : item = getattr(self, name) (shouldWarn,message) = item(line) if shouldWarn == True : print "%s:%-4d [%s] %s" % (fileName, lineCount, name, message) self.nits+=1 f.close() if self.nits == 0 : print "+ %s is OK" % fileName else: print "! %s contains %d nits" % (fileName,self.nits) # # Rulesets # class NitHunterGeneric(NitHunter): """Common rules""" def hunt_tab(self,line): """Check for presence of tab cahracter""" return (line.find('\t') != -1, "Line contains tab character") def hunt_trailing_space(self,line): """Check for trailing whitespace""" return (len(line) > 1 and line[-2]==' ',"Line contains trailing space") def hunt_if(self,line): """Control should be as (nnnn = mmm) {""" message = "Line contains: " shouldWarn = False if line.find("( ") != -1 : message += "space after (; " shouldWarn = True if line.find(" )") != -1 : message += "space before ); " shouldWarn = True n = line.find("{") if n > 0 and line[n-1] != ' ': message += "no space before {;" shouldWarn = True return (shouldWarn, message) def hunt_copyright(self,line): """Copyright year should mach current year""" now = datetime.datetime.now() year = now.year shouldWarn = line.find("Copyright") != -1 and line.find("%s" % year) == -1 return (shouldWarn, "Copyright doesn't contain current year (%s)" % year) """ Tools """ def check_indent(self,line,boundary): shouldWarn = False i = 0 while(line[i] == ' ' and i < len(line)-1 ) : i+=1 if i % boundary != 0 : if line[i] != '*' and line[i] != '"': # Assume it's a block comments or string. Don't complain about indent shouldWarn = True return (shouldWarn ,"Line contains wrong indent %d" % i) class NitHunterHotspot(NitHunterGeneric) : """Hotspot private ruleset""" def hunt_indent(self,line): """Check that first non-space character is on 2 boundary""" return self.check_indent(line,2) class NitHunterJDK(NitHunterGeneric) : """JDK private ruleset""" def hunt_indent(self,line): """Check that first non-space character is on 4 boundary""" return self.check_indent(line,4) def usage(): print "Usage: nithunter.py [--exclude=rules1,rules2...] [--hunter=hotspot|jdk] filepattern" sys.exit(2) # ----------- MAIN ------------------- if __name__ == '__main__': try: opts, args = getopt.getopt(sys.argv[1:], "he:u:", ["help", "exclude=", "hunter="]) except getopt.GetoptError, err: print str(err) usage() exclude = [] nhName = "hotspot" for o, a in opts: if o in ("-h", "--help"): usage() elif o in ("-e", "--exclude"): exclude = a.split(',') elif o in ("-u", "--hunter"): nhName = a else: assert False, "unhandled option" if nhName == "hotspot" : nh = NitHunterHotspot(exclude) elif name == "jdk" : nh = NitHunterJDK(exclude) else: print "Invalid hunter name " + nhName usage() for pat in args : for fileName in glob.iglob(pat) : nh.execute(fileName)