diff options
author | Daniel Jasper <djasper@google.com> | 2013-03-20 09:53:23 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-03-20 09:53:23 +0000 |
commit | 7c4a9a04b4b2a44259b34078434e087987872095 (patch) | |
tree | a8f60cc98bef2e1ba8f1f8615a56316bd45ef9c2 /tools/clang-format/clang-format-diff.py | |
parent | 9322aaee900b872c98f8fc10b38a231cb1e9b57a (diff) | |
download | clang-7c4a9a04b4b2a44259b34078434e087987872095.tar.gz clang-7c4a9a04b4b2a44259b34078434e087987872095.tar.bz2 clang-7c4a9a04b4b2a44259b34078434e087987872095.tar.xz |
Add clang-format binary to cfe.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177506 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/clang-format/clang-format-diff.py')
-rwxr-xr-x | tools/clang-format/clang-format-diff.py | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py new file mode 100755 index 0000000000..ab5f1b1bc6 --- /dev/null +++ b/tools/clang-format/clang-format-diff.py @@ -0,0 +1,115 @@ +#!/usr/bin/python +# +#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# + +r""" +ClangFormat Diff Reformatter +============================ + +This script reads input from a unified diff and reformats all the changed +lines. This is useful to reformat all the lines touched by a specific patch. +Example usage for git users: + + git diff -U0 HEAD^ | clang-format-diff.py -p1 + +""" + +import argparse +import re +import subprocess +import sys + + +# Change this to the full path if clang-format is not on the path. +binary = 'clang-format' + + +def getOffsetLength(filename, line_number, line_count): + """ + Calculates the field offset and length based on line number and count. + """ + offset = 0 + length = 0 + with open(filename, 'r') as f: + for line in f: + if line_number > 1: + offset += len(line) + line_number -= 1 + elif line_count > 0: + length += len(line) + line_count -= 1 + else: + break + return offset, length + + +def formatRange(r, style): + """ + Formats range 'r' according to style 'style'. + """ + filename, line_number, line_count = r + # FIXME: Add other types containing C++/ObjC code. + if not (filename.endswith(".cpp") or filename.endswith(".cc") or + filename.endswith(".h")): + return + + offset, length = getOffsetLength(filename, line_number, line_count) + with open(filename, 'r') as f: + text = f.read() + p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length), + '-style', style], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + stdin=subprocess.PIPE) + stdout, stderr = p.communicate(input=text) + if stderr: + print stderr + return + if not stdout: + print 'Segfault occurred while formatting', filename + print 'Please report a bug on llvm.org/bugs.' + return + with open(filename, 'w') as f: + f.write(stdout) + + +def main(): + parser = argparse.ArgumentParser(description= + 'Reformat changed lines in diff') + parser.add_argument('-p', default=1, + help='strip the smallest prefix containing P slashes') + parser.add_argument('-style', default='LLVM', + help='formatting style to apply (LLVM, Google)') + args = parser.parse_args() + + filename = None + ranges = [] + + for line in sys.stdin: + match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) + if match: + filename = match.group(2) + if filename == None: + continue + + match = re.search('^@@.*\+(\d+)(,(\d+))?', line) + if match: + line_count = 1 + if match.group(3): + line_count = int(match.group(3)) + ranges.append((filename, int(match.group(1)), line_count)) + + # Reverse the ranges so that the reformatting does not influence file offsets. + for r in reversed(ranges): + # Do the actual formatting. + formatRange(r, args.style) + + +if __name__ == '__main__': + main() |