1998-03-20 15:23:04 -04:00
|
|
|
#! /usr/bin/env python
|
|
|
|
|
|
|
|
"""The Tab Police watches for possibly inconsistent indentation."""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import getopt
|
|
|
|
import tokenize
|
|
|
|
|
|
|
|
verbose = 0
|
1998-03-26 15:23:43 -04:00
|
|
|
quiet = 0
|
1998-03-20 15:23:04 -04:00
|
|
|
|
|
|
|
def main():
|
1998-03-26 15:23:43 -04:00
|
|
|
global verbose, quiet
|
1998-03-20 15:23:04 -04:00
|
|
|
try:
|
1998-03-26 15:23:43 -04:00
|
|
|
opts, args = getopt.getopt(sys.argv[1:], "qv")
|
1998-03-20 15:23:04 -04:00
|
|
|
except getopt.error, msg:
|
|
|
|
print msg
|
1998-04-06 11:45:26 -03:00
|
|
|
return
|
1998-03-20 15:23:04 -04:00
|
|
|
for o, a in opts:
|
|
|
|
if o == '-v':
|
|
|
|
verbose = verbose + 1
|
1998-03-26 15:23:43 -04:00
|
|
|
quiet = 0
|
|
|
|
if o == '-q':
|
|
|
|
quiet = 1
|
|
|
|
verbose = 0
|
1998-04-06 11:45:26 -03:00
|
|
|
if not args:
|
|
|
|
print "Usage:", sys.argv[0], "file_or_directory ..."
|
|
|
|
return
|
1998-03-20 15:23:04 -04:00
|
|
|
for arg in args:
|
|
|
|
check(arg)
|
|
|
|
|
|
|
|
def check(file):
|
|
|
|
if os.path.isdir(file) and not os.path.islink(file):
|
|
|
|
if verbose:
|
|
|
|
print "%s: listing directory" % `file`
|
|
|
|
names = os.listdir(file)
|
|
|
|
for name in names:
|
|
|
|
fullname = os.path.join(file, name)
|
|
|
|
if (os.path.isdir(fullname) and
|
|
|
|
not os.path.islink(fullname) or
|
|
|
|
os.path.normcase(name[-3:]) == ".py"):
|
|
|
|
check(fullname)
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
f = open(file)
|
|
|
|
except IOError, msg:
|
|
|
|
print "%s: I/O Error: %s" % (`file`, str(msg))
|
|
|
|
return
|
|
|
|
|
|
|
|
if verbose > 1:
|
|
|
|
print "checking", `file`, "with tabsize 8..."
|
|
|
|
tokens = []
|
|
|
|
tokenize.tabsize = 8
|
|
|
|
try:
|
|
|
|
tokenize.tokenize(f.readline, tokens.append)
|
|
|
|
except tokenize.TokenError, msg:
|
|
|
|
print "%s: Token Error: %s" % (`file`, str(msg))
|
|
|
|
|
|
|
|
if verbose > 1:
|
1998-03-24 00:58:04 -04:00
|
|
|
print "checking", `file`, "with tabsize 1..."
|
1998-03-20 15:23:04 -04:00
|
|
|
f.seek(0)
|
|
|
|
alttokens = []
|
1998-03-24 00:58:04 -04:00
|
|
|
tokenize.tabsize = 1
|
1998-03-20 15:23:04 -04:00
|
|
|
try:
|
|
|
|
tokenize.tokenize(f.readline, alttokens.append)
|
|
|
|
except tokenize.TokenError, msg:
|
|
|
|
print "%s: Token Error: %s" % (`file`, str(msg))
|
|
|
|
f.close()
|
|
|
|
|
1998-03-26 15:23:43 -04:00
|
|
|
if tokens == alttokens:
|
|
|
|
if verbose:
|
|
|
|
print "%s: Clean bill of health." % `file`
|
|
|
|
elif quiet:
|
|
|
|
print file
|
|
|
|
else:
|
1998-03-24 00:58:04 -04:00
|
|
|
badline = 0
|
|
|
|
n, altn = len(tokens), len(alttokens)
|
|
|
|
for i in range(max(n, altn)):
|
|
|
|
if i >= n:
|
|
|
|
x = None
|
|
|
|
else:
|
|
|
|
x = tokens[i]
|
|
|
|
if i >= altn:
|
|
|
|
y = None
|
|
|
|
else:
|
|
|
|
y = alttokens[i]
|
|
|
|
if x != y:
|
|
|
|
if x:
|
|
|
|
kind, token, start, end, line = x
|
|
|
|
else:
|
|
|
|
kind, token, start, end, line = y
|
|
|
|
badline = start[0]
|
|
|
|
break
|
1998-03-20 15:23:04 -04:00
|
|
|
if verbose:
|
1998-03-24 00:58:04 -04:00
|
|
|
print "%s: *** Line %d: trouble in tab city! ***" % (
|
|
|
|
`file`, badline)
|
|
|
|
print "offending line:", `line`
|
1998-03-20 15:23:04 -04:00
|
|
|
else:
|
1998-03-24 00:58:04 -04:00
|
|
|
print file, badline, `line`
|
1998-03-20 15:23:04 -04:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|