diff options
Diffstat (limited to 'Tools/scripts/reindent.py')
-rwxr-xr-x | Tools/scripts/reindent.py | 148 |
1 files changed, 74 insertions, 74 deletions
diff --git a/Tools/scripts/reindent.py b/Tools/scripts/reindent.py index f6dadaa..540901b 100755 --- a/Tools/scripts/reindent.py +++ b/Tools/scripts/reindent.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#! /usr/bin/env python # Released to the public domain, by Tim Peters, 03 October 2000. @@ -8,8 +8,6 @@ -r (--recurse) Recurse. Search for all .py files in subdirectories too. -n (--nobackup) No backup. Does not make a ".bak" file before reindenting. -v (--verbose) Verbose. Print informative msgs; else no output. - (--newline) Newline. Specify the newline character to use (CRLF, LF). - Default is the same as the original file. -h (--help) Help. Print this usage information and exit. Change Python (.py) files to use 4-space indents and no hard tab characters. @@ -44,51 +42,45 @@ you'd prefer. You can always use the --nobackup option to prevent this. __version__ = "1" import tokenize -import os -import shutil +import os, shutil import sys +import io -verbose = False -recurse = False -dryrun = False +verbose = 0 +recurse = 0 +dryrun = 0 makebackup = True -# A specified newline to be used in the output (set by --newline option) -spec_newline = None - def usage(msg=None): - if msg is None: - msg = __doc__ - print(msg, file=sys.stderr) - + if msg is not None: + print >> sys.stderr, msg + print >> sys.stderr, __doc__ def errprint(*args): - sys.stderr.write(" ".join(str(arg) for arg in args)) + sep = "" + for arg in args: + sys.stderr.write(sep + str(arg)) + sep = " " sys.stderr.write("\n") def main(): import getopt - global verbose, recurse, dryrun, makebackup, spec_newline + global verbose, recurse, dryrun, makebackup try: opts, args = getopt.getopt(sys.argv[1:], "drnvh", - ["dryrun", "recurse", "nobackup", "verbose", "newline=", "help"]) - except getopt.error as msg: + ["dryrun", "recurse", "nobackup", "verbose", "help"]) + except getopt.error, msg: usage(msg) return for o, a in opts: if o in ('-d', '--dryrun'): - dryrun = True + dryrun += 1 elif o in ('-r', '--recurse'): - recurse = True + recurse += 1 elif o in ('-n', '--nobackup'): makebackup = False elif o in ('-v', '--verbose'): - verbose = True - elif o in ('--newline',): - if not a.upper() in ('CRLF', 'LF'): - usage() - return - spec_newline = dict(CRLF='\r\n', LF='\n')[a.upper()] + verbose += 1 elif o in ('-h', '--help'): usage() return @@ -100,11 +92,10 @@ def main(): for arg in args: check(arg) - def check(file): if os.path.isdir(file) and not os.path.islink(file): if verbose: - print("listing directory", file) + print "listing directory", file names = os.listdir(file) for name in names: fullname = os.path.join(file, name) @@ -116,48 +107,58 @@ def check(file): return if verbose: - print("checking", file, "...", end=' ') - with open(file, 'rb') as f: - try: - encoding, _ = tokenize.detect_encoding(f.readline) - except SyntaxError as se: - errprint("%s: SyntaxError: %s" % (file, str(se))) - return + print "checking", file, "...", try: - with open(file, encoding=encoding) as f: - r = Reindenter(f) - except IOError as msg: + f = open(file, "rb") + except IOError, msg: errprint("%s: I/O Error: %s" % (file, str(msg))) return - newline = spec_newline if spec_newline else r.newlines + r = Reindenter(f) + f.close() + + newline = r.newlines if isinstance(newline, tuple): - errprint("%s: mixed newlines detected; cannot continue without --newline" % file) + errprint("%s: mixed newlines detected; cannot process file" % file) return if r.run(): if verbose: - print("changed.") + print "changed." if dryrun: - print("But this is a dry run, so leaving it alone.") + print "But this is a dry run, so leaving it alone." if not dryrun: bak = file + ".bak" if makebackup: shutil.copyfile(file, bak) if verbose: - print("backed up", file, "to", bak) - with open(file, "w", encoding=encoding, newline=newline) as f: - r.write(f) + print "backed up", file, "to", bak + f = open(file, "wb") + r.write(f) + f.close() if verbose: - print("wrote new", file) + print "wrote new", file return True else: if verbose: - print("unchanged.") + print "unchanged." return False - -def _rstrip(line, JUNK='\n \t'): +def _detect_newlines(lines): + newlines = {'\r\n' if line[-2:] == '\r\n' else + '\n' if line[-1:] == '\n' else + '\r' if line[-1:] == '\r' else + '' + for line in lines} + newlines.discard('') + newlines = tuple(sorted(newlines)) + if not newlines: + return '\n' + if len(newlines) == 1: + return newlines[0] + return newlines + +def _rstrip(line, JUNK='\r\n \t'): """Return line stripped of trailing spaces, tabs, newlines. Note that line.rstrip() instead also strips sundry control characters, @@ -166,11 +167,10 @@ def _rstrip(line, JUNK='\n \t'): """ i = len(line) - while i > 0 and line[i - 1] in JUNK: + while i > 0 and line[i-1] in JUNK: i -= 1 return line[:i] - class Reindenter: def __init__(self, f): @@ -180,10 +180,18 @@ class Reindenter: # Raw file lines. self.raw = f.readlines() + # Save the newlines found in the file so they can be used to + # create output without mutating the newlines. + self.newlines = _detect_newlines(self.raw) + if isinstance(self.newlines, tuple): + self.newline = self.newlines[0] + else: + self.newline = self.newlines + # File lines, rstripped & tab-expanded. Dummy at start is so # that we can use tokenize's 1-based line numbering easily. - # Note that a line is all-blank iff it's "\n". - self.lines = [_rstrip(line).expandtabs() + "\n" + # Note that a line is all-blank iff it's newline. + self.lines = [_rstrip(line).expandtabs() + self.newline for line in self.raw] self.lines.insert(0, None) self.index = 1 # index into self.lines of next line @@ -194,17 +202,11 @@ class Reindenter: # indeed, they're our headache! self.stats = [] - # Save the newlines found in the file so they can be used to - # create output without mutating the newlines. - self.newlines = f.newlines - def run(self): - tokens = tokenize.generate_tokens(self.getline) - for _token in tokens: - self.tokeneater(*_token) + tokenize.tokenize(self.getline, self.tokeneater) # Remove trailing empty lines. lines = self.lines - while lines and lines[-1] == "\n": + while lines and lines[-1] == self.newline: lines.pop() # Sentinel. stats = self.stats @@ -217,9 +219,9 @@ class Reindenter: # we see a line with *something* on it. i = stats[0][0] after.extend(lines[1:i]) - for i in range(len(stats) - 1): + for i in range(len(stats)-1): thisstmt, thislevel = stats[i] - nextstmt = stats[i + 1][0] + nextstmt = stats[i+1][0] have = getlspace(lines[thisstmt]) want = thislevel * 4 if want < 0: @@ -231,7 +233,7 @@ class Reindenter: want = have2want.get(have, -1) if want < 0: # Then it probably belongs to the next real stmt. - for j in range(i + 1, len(stats) - 1): + for j in xrange(i+1, len(stats)-1): jline, jlevel = stats[j] if jlevel >= 0: if have == getlspace(lines[jline]): @@ -241,11 +243,11 @@ class Reindenter: # comment like this one, # in which case we should shift it like its base # line got shifted. - for j in range(i - 1, -1, -1): + for j in xrange(i-1, -1, -1): jline, jlevel = stats[j] if jlevel >= 0: - want = have + (getlspace(after[jline - 1]) - - getlspace(lines[jline])) + want = have + getlspace(after[jline-1]) - \ + getlspace(lines[jline]) break if want < 0: # Still no luck -- leave it alone. @@ -260,7 +262,7 @@ class Reindenter: else: for line in lines[thisstmt:nextstmt]: if diff > 0: - if line == "\n": + if line == self.newline: after.append(line) else: after.append(" " * diff + line) @@ -282,7 +284,7 @@ class Reindenter: return line # Line-eater for tokenize. - def tokeneater(self, type, token, slinecol, end, line, + def tokeneater(self, type, token, (sline, scol), end, line, INDENT=tokenize.INDENT, DEDENT=tokenize.DEDENT, NEWLINE=tokenize.NEWLINE, @@ -305,7 +307,7 @@ class Reindenter: elif type == COMMENT: if self.find_stmt: - self.stats.append((slinecol[0], -1)) + self.stats.append((sline, -1)) # but we're still looking for a new stmt, so leave # find_stmt alone @@ -318,8 +320,7 @@ class Reindenter: # ENDMARKER. self.find_stmt = 0 if line: # not endmarker - self.stats.append((slinecol[0], self.level)) - + self.stats.append((sline, self.level)) # Count number of leading blanks. def getlspace(line): @@ -328,6 +329,5 @@ def getlspace(line): i += 1 return i - if __name__ == '__main__': main() |