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)