Skip to content

Commit fa4f4b6

Browse files
author
MarcoFalke
committed
Add clang-format-diff.py from the LLVM svn
------------------------------------------------------------------------ r249567 | djasper | 2015-10-07 19:00:20 +0200 (Wed, 07 Oct 2015) | 2 lines clang-format: Add include sorting capabilities to sublime, emacs and clang-format-diff.py. ------------------------------------------------------------------------ r231926 | djasper | 2015-03-11 15:58:38 +0100 (Wed, 11 Mar 2015) | 3 lines clang-format: Recognize the .ts (TypeScript) extension as JavaScript. Patch by Martin Probst. Thank you. ------------------------------------------------------------------------ r223685 | djasper | 2014-12-08 20:39:03 +0100 (Mon, 08 Dec 2014) | 1 line clang-format: Make clang-format-diff.py format java files. ------------------------------------------------------------------------ r221990 | djasper | 2014-11-14 14:27:28 +0100 (Fri, 14 Nov 2014) | 4 lines clang-format: Give clang-format-diff.py a -v option. With it, it prints the file being formatted. Apparently people are formatting thousands of files and some progress indication is helpful. ------------------------------------------------------------------------ r216945 | ed | 2014-09-02 22:59:13 +0200 (Tue, 02 Sep 2014) | 6 lines Use /usr/bin/env python instead of /usr/bin/python. On operating systems like the BSDs, it is typically the case that /usr/bin/python does not exist. We should therefore use /usr/bin/env instead. This is also done in various other scripts in tools/. ------------------------------------------------------------------------ r208766 | djasper | 2014-05-14 11:36:11 +0200 (Wed, 14 May 2014) | 1 line clang-format: Add clang-format-diff usage examples for SVN. ------------------------------------------------------------------------ r199750 | djasper | 2014-01-21 16:40:01 +0100 (Tue, 21 Jan 2014) | 3 lines clang-format: Enable formatting for .proto and .protodevel files. Support for protocol buffer files seems complete enough. ------------------------------------------------------------------------ r197668 | djasper | 2013-12-19 11:21:37 +0100 (Thu, 19 Dec 2013) | 1 line Fix usage description of clang-format-diff.py. ------------------------------------------------------------------------ r197608 | alp | 2013-12-18 22:34:07 +0100 (Wed, 18 Dec 2013) | 7 lines clang-format-diff.py: fix -regex/-iregex matching While debating the finer points of file extension matching, we somehow missed the bigger problem that the current code will match anything starting with the default or user-specified pattern (e.g. lit.site.cfg.in). Fix this by doing what find(1) does, implicitly wrapping the pattern with ^$. ------------------------------------------------------------------------ r197542 | alp | 2013-12-18 01:58:58 +0100 (Wed, 18 Dec 2013) | 3 lines clang-format-diff.py: add the OpenCL file extension It's handled correctly as a C-family language. ------------------------------------------------------------------------ r197378 | alexfh | 2013-12-16 11:57:30 +0100 (Mon, 16 Dec 2013) | 14 lines Added -iregex for case-insensitive regex to filter file names. Summary: -regex and -iregex both mimic options of the find utility. Made the default list of extensions case-insensitive, so that it's not only C and CPP extensions are accepted in upper case. Reviewers: djasper Reviewed By: djasper CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D2415 ------------------------------------------------------------------------ r196917 | alp | 2013-12-10 14:51:53 +0100 (Tue, 10 Dec 2013) | 10 lines clang-format-diff.py: Support -regex filter and more filename extensions Add support for more filename extensions based on the list in the clang plus JavaScript. Also adds a -regex option so users can override defaults if they have unusual file extensions or want to format everything in the diff. Keeping with tradition the flag is modelled on Unix conventions, this time matching the semantics of find(1). ------------------------------------------------------------------------ r196484 | alp | 2013-12-05 09:14:54 +0100 (Thu, 05 Dec 2013) | 4 lines clang-format-diff.py: pass through errors to stderr, not stdout Also use write() for unified diff output to avoid further processing by the print function (e.g. trailing newline). ------------------------------------------------------------------------ r196336 | alp | 2013-12-04 01:48:22 +0100 (Wed, 04 Dec 2013) | 3 lines clang-format-diff.py: Fix 'beintroduced' in help output Also update docs to reflect recently changed -i inplace edit behaviour. ------------------------------------------------------------------------ r192505 | alexfh | 2013-10-11 23:32:01 +0200 (Fri, 11 Oct 2013) | 17 lines Changed clang-format-diff.py to output diff by default. Added -i option to apply changes to files instead. Summary: "svn diff|clang-format-diff.py" will just output the diff. Now it's possible to use: svn diff|clang-format-diff.py|patch -p0 as an equivalent to: svn diff|clang-format-diff.py -i ;) Reviewers: djasper Reviewed By: djasper CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1840 ------------------------------------------------------------------------ r192184 | djasper | 2013-10-08 17:54:36 +0200 (Tue, 08 Oct 2013) | 7 lines clang-format: Don't exit with failure on empty files. Also let clang-format-diff.py detect errors based on clang-format's return code. Otherwise messages like "Can't find usable .clang-format, falling back to LLVM style" can make it fail, which might be undesired. Patch by Alp Toker. Thank you! ------------------------------------------------------------------------ r191820 | djasper | 2013-10-02 15:59:03 +0200 (Wed, 02 Oct 2013) | 18 lines clang-format: Fix clang-format-diff.py according to diff specification. 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!) ------------------------------------------------------------------------ r191137 | djasper | 2013-09-21 12:05:02 +0200 (Sat, 21 Sep 2013) | 3 lines Fix clang-format-diff.py to accept -style again. Copy and paste error in r190935.. ------------------------------------------------------------------------ r190935 | djasper | 2013-09-18 14:14:09 +0200 (Wed, 18 Sep 2013) | 3 lines Simplify clang-format-diff.py using new clang-format options. clang-format's -lines parameter makes this significantly easier. ------------------------------------------------------------------------ r189765 | alexfh | 2013-09-02 18:39:23 +0200 (Mon, 02 Sep 2013) | 2 lines Added WebKit style to the BasedOnStyle handling and to the relevant help messages. ------------------------------------------------------------------------ r182923 | djasper | 2013-05-30 13:50:20 +0200 (Thu, 30 May 2013) | 4 lines Fix default value of clang-format-diff's -p option. This way, it has the same default as 'patch' and also the example in the code makes more sense as it is explicitly setting -p 1. ------------------------------------------------------------------------ r179676 | djasper | 2013-04-17 09:55:02 +0200 (Wed, 17 Apr 2013) | 2 lines Small improvements to clang-format documentation and integration scripts. ------------------------------------------------------------------------ r179377 | djasper | 2013-04-12 15:42:36 +0200 (Fri, 12 Apr 2013) | 1 line Fix clang-format-diff.py script. ------------------------------------------------------------------------ r179098 | djasper | 2013-04-09 17:23:04 +0200 (Tue, 09 Apr 2013) | 5 lines Improvements to clang-format integrations. This adds an emacs editor integration (thanks to Ami Fischman). Also pulls out the style into a variable for the vi integration and just uses clang-formats defaults style in clang-format-diff.py. ------------------------------------------------------------------------ r177506 | djasper | 2013-03-20 10:53:23 +0100 (Wed, 20 Mar 2013) | 1 line Add clang-format binary to cfe. ------------------------------------------------------------------------ s
1 parent 605c178 commit fa4f4b6

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python
2+
#
3+
#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
4+
#
5+
# The LLVM Compiler Infrastructure
6+
#
7+
# This file is distributed under the University of Illinois Open Source
8+
# License. See LICENSE.TXT for details.
9+
#
10+
#===------------------------------------------------------------------------===#
11+
12+
r"""
13+
ClangFormat Diff Reformatter
14+
============================
15+
16+
This script reads input from a unified diff and reformats all the changed
17+
lines. This is useful to reformat all the lines touched by a specific patch.
18+
Example usage for git/svn users:
19+
20+
git diff -U0 HEAD^ | clang-format-diff.py -p1 -i
21+
svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
22+
23+
"""
24+
25+
import argparse
26+
import difflib
27+
import re
28+
import string
29+
import subprocess
30+
import StringIO
31+
import sys
32+
33+
34+
# Change this to the full path if clang-format is not on the path.
35+
binary = 'clang-format'
36+
37+
38+
def main():
39+
parser = argparse.ArgumentParser(description=
40+
'Reformat changed lines in diff. Without -i '
41+
'option just output the diff that would be '
42+
'introduced.')
43+
parser.add_argument('-i', action='store_true', default=False,
44+
help='apply edits to files instead of displaying a diff')
45+
parser.add_argument('-p', metavar='NUM', default=0,
46+
help='strip the smallest prefix containing P slashes')
47+
parser.add_argument('-regex', metavar='PATTERN', default=None,
48+
help='custom pattern selecting file paths to reformat '
49+
'(case sensitive, overrides -iregex)')
50+
parser.add_argument('-iregex', metavar='PATTERN', default=
51+
r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|ts|proto'
52+
r'|protodevel|java)',
53+
help='custom pattern selecting file paths to reformat '
54+
'(case insensitive, overridden by -regex)')
55+
parser.add_argument('-sort-includes', action='store_true', default=False,
56+
help='let clang-format sort include blocks')
57+
parser.add_argument('-v', '--verbose', action='store_true',
58+
help='be more verbose, ineffective without -i')
59+
parser.add_argument(
60+
'-style',
61+
help=
62+
'formatting style to apply (LLVM, Google, Chromium, Mozilla, WebKit)')
63+
args = parser.parse_args()
64+
65+
# Extract changed lines for each file.
66+
filename = None
67+
lines_by_file = {}
68+
for line in sys.stdin:
69+
match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
70+
if match:
71+
filename = match.group(2)
72+
if filename == None:
73+
continue
74+
75+
if args.regex is not None:
76+
if not re.match('^%s$' % args.regex, filename):
77+
continue
78+
else:
79+
if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
80+
continue
81+
82+
match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
83+
if match:
84+
start_line = int(match.group(1))
85+
line_count = 1
86+
if match.group(3):
87+
line_count = int(match.group(3))
88+
if line_count == 0:
89+
continue
90+
end_line = start_line + line_count - 1;
91+
lines_by_file.setdefault(filename, []).extend(
92+
['-lines', str(start_line) + ':' + str(end_line)])
93+
94+
# Reformat files containing changes in place.
95+
for filename, lines in lines_by_file.iteritems():
96+
if args.i and args.verbose:
97+
print 'Formatting', filename
98+
command = [binary, filename]
99+
if args.i:
100+
command.append('-i')
101+
if args.sort_includes:
102+
command.append('-sort-includes')
103+
command.extend(lines)
104+
if args.style:
105+
command.extend(['-style', args.style])
106+
p = subprocess.Popen(command, stdout=subprocess.PIPE,
107+
stderr=None, stdin=subprocess.PIPE)
108+
stdout, stderr = p.communicate()
109+
if p.returncode != 0:
110+
sys.exit(p.returncode);
111+
112+
if not args.i:
113+
with open(filename) as f:
114+
code = f.readlines()
115+
formatted_code = StringIO.StringIO(stdout).readlines()
116+
diff = difflib.unified_diff(code, formatted_code,
117+
filename, filename,
118+
'(before formatting)', '(after formatting)')
119+
diff_string = string.join(diff, '')
120+
if len(diff_string) > 0:
121+
sys.stdout.write(diff_string)
122+
123+
if __name__ == '__main__':
124+
main()

0 commit comments

Comments
 (0)