diff options
author | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 00:23:26 +0000 |
---|---|---|
committer | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 00:23:26 +0000 |
commit | 50e5a3dbf067d3c0bdfce8ab8df62a2130bc0e4b (patch) | |
tree | 8af465317172de1f21b3e26ff23813cafd5b5531 | |
parent | 37858e5c2f58f4b46117c65df2ab3da8a7b2e6e2 (diff) | |
download | chromium_src-50e5a3dbf067d3c0bdfce8ab8df62a2130bc0e4b.zip chromium_src-50e5a3dbf067d3c0bdfce8ab8df62a2130bc0e4b.tar.gz chromium_src-50e5a3dbf067d3c0bdfce8ab8df62a2130bc0e4b.tar.bz2 |
Check in a quick tool for sorting the #includes in a file.
This is especially useful when you do a mass-rename of a header
and now need to fix every user of it.
Special thanks to pamg for fixing my Python style!
Review URL: http://codereview.chromium.org/3149032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57435 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-x | tools/sort-headers.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/tools/sort-headers.py b/tools/sort-headers.py new file mode 100755 index 0000000..b18ac6c --- /dev/null +++ b/tools/sort-headers.py @@ -0,0 +1,94 @@ +#!/usr/bin/python + +"""Given a filename as an argument, sort the #include/#imports in that file. + +Shows a diff and prompts for confirmation before doing the deed. +""" + +import optparse +import os +import sys +import termios +import tty + +def YesNo(prompt): + """Prompts with a yes/no question, returns True if yes.""" + print prompt, + sys.stdout.flush() + # http://code.activestate.com/recipes/134892/ + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + ch = 'n' + try: + tty.setraw(sys.stdin.fileno()) + ch = sys.stdin.read(1) + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + print ch + return ch in ('Y', 'y') + + +def IncludeCompareKey(line): + """Sorting comparator key used for comparing two #include lines. + Returns the filename without the #include/#import prefix. + """ + for prefix in ('#include ', '#import '): + if line.startswith(prefix): + return line[len(prefix):] + return line + + +def IsInclude(line): + """Returns True if the line is an #include/#import line.""" + return line.startswith('#include ') or line.startswith('#import ') + + +def SortHeader(infile, outfile): + """Sorts the headers in infile, writing the sorted file to outfile.""" + for line in infile: + if IsInclude(line): + headerblock = [] + while IsInclude(line): + headerblock.append(line) + line = infile.next() + for header in sorted(headerblock, key=IncludeCompareKey): + outfile.write(header) + # Intentionally fall through, to write the line that caused + # the above while loop to exit. + outfile.write(line) + + +def main(): + parser = optparse.OptionParser(usage='%prog filename1 filename2 ...') + opts, args = parser.parse_args() + + if len(args) < 1: + parser.print_help() + sys.exit(1) + + for filename in args: + fixfilename = filename + '.new' + infile = open(filename, 'r') + outfile = open(fixfilename, 'w') + SortHeader(infile, outfile) + infile.close() + outfile.close() # Important so the below diff gets the updated contents. + + try: + diff = os.system('diff -u %s %s' % (filename, fixfilename)) + if diff >> 8 == 0: # Check exit code. + print '%s: no change' % filename + continue + + if YesNo('Use new file (y/N)?'): + os.rename(fixfilename, filename) + finally: + try: + os.remove(fixfilename) + except OSError: + # If the file isn't there, we don't care. + pass + + +if __name__ == '__main__': + main() |