diff options
Diffstat (limited to 'tools/sort-headers.py')
-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() |