John, Wrote extendable nit hunting framework ;-) (attached) Fill free to add/change rules.
This script doesn't change a source file but complains about found formatting errors. It should save a bit of time during code review. -Dmitry On 2012-03-03 23:55, John Rose wrote: > Lest Kelly have all the fun, I'll jump in. > > On Mar 3, 2012, at 3:36 AM, David Holmes wrote: > >> So the question is: what does the script think a TAB represents? > > The same thing that /usr/bin/expand does, as noted earlier. Or read the > perl code. > > When was the last time anybody on the hotspot team used '\t' (the source > file octet, not the keyboard key) to mean anything else than > /usr/bin/expand? This stuff about 2 and 4 width indents is irrelevant, > except to people who accidentally use anti-social IDE settings, and they > get socialized quickly. > > On Mar 3, 2012, at 8:39 AM, Jonathan Gibbons wrote: > >> Kelly, >> >> Is there a reason you don't use "expand"? >> >> For a while now I've been using the following simple script to fix the >> whitespace in my files before I commit a change set. > > The perl script does what your script does, probably to 95% > compatibility. (File list generation logic and last-line behavior may > perhaps vary on corner cases.) Your script uses perl plus other shell > commands, while the standard script uses perl only; your script uses > expand instead of an obscure couple of perl lines which do the same > thing. It seems a matter of taste not greatly worth discussing. There > are 10 different ways to code this operation; 9 of those ways will not > get used, but (IMO) it's not very interesting to ask why not. > > — John -- Dmitry Samersoff Java Hotspot development team, SPB04 * There will come soft rains ...
#!/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)