mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-25 22:38:56 -04:00

Patch by Alp Toker. Many thanks! Original descriptions: clang-format-diff incorrectly modifies unchanged lines due to an error in diff parsing. The unified diff format has a default line change count of 1, and 0 may be specified to indicate that no lines have been added. This patch updates the parser to accurately reflect the diff specification. This also has the benefit of stabilising the operation so it will produce the same output when run multiple times on the same changeset, which was previously not the case. No tests added because this script is not currently tested (though we should look into that!) llvm-svn: 191820
89 lines
2.5 KiB
Python
Executable File
89 lines
2.5 KiB
Python
Executable File
#!/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 main():
|
|
parser = argparse.ArgumentParser(description=
|
|
'Reformat changed lines in diff.')
|
|
parser.add_argument('-p', default=0,
|
|
help='strip the smallest prefix containing P slashes')
|
|
parser.add_argument(
|
|
'-style',
|
|
help=
|
|
'formatting style to apply (LLVM, Google, Chromium, Mozilla, WebKit)')
|
|
args = parser.parse_args()
|
|
|
|
# Extract changed lines for each file.
|
|
filename = None
|
|
lines_by_file = {}
|
|
for line in sys.stdin:
|
|
match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
|
|
if match:
|
|
filename = match.group(2)
|
|
if filename == None:
|
|
continue
|
|
|
|
# FIXME: Add other types containing C++/ObjC code.
|
|
if not (filename.endswith(".cpp") or filename.endswith(".cc") or
|
|
filename.endswith(".h")):
|
|
continue
|
|
|
|
match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
|
|
if match:
|
|
start_line = int(match.group(1))
|
|
line_count = 1
|
|
if match.group(3):
|
|
line_count = int(match.group(3))
|
|
if line_count == 0:
|
|
continue
|
|
end_line = start_line + line_count - 1;
|
|
lines_by_file.setdefault(filename, []).extend(
|
|
['-lines', str(start_line) + ':' + str(end_line)])
|
|
|
|
# Reformat files containing changes in place.
|
|
for filename, lines in lines_by_file.iteritems():
|
|
command = [binary, '-i', filename]
|
|
command.extend(lines)
|
|
if args.style:
|
|
command.extend(['-style', args.style])
|
|
p = subprocess.Popen(command, stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
stdin=subprocess.PIPE)
|
|
stdout, stderr = p.communicate()
|
|
if stderr:
|
|
print stderr
|
|
return
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|