[cfe-commits] [clang-tools-extra] r171994 - /clang-tools-extra/trunk/clang-format/clang-format-diff.py

Daniel Jasper djasper at google.com
Wed Jan 9 12:20:11 PST 2013


Author: djasper
Date: Wed Jan  9 14:20:11 2013
New Revision: 171994

URL: http://llvm.org/viewvc/llvm-project?rev=171994&view=rev
Log:
Initial version of diff/patch-reformat tool.

Use at your own risk :-).

Added:
    clang-tools-extra/trunk/clang-format/clang-format-diff.py   (with props)

Added: clang-tools-extra/trunk/clang-format/clang-format-diff.py
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-format/clang-format-diff.py?rev=171994&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-format/clang-format-diff.py (added)
+++ clang-tools-extra/trunk/clang-format/clang-format-diff.py Wed Jan  9 14:20:11 2013
@@ -0,0 +1,117 @@
+#!/usr/bin/python
+#
+#===- cindex.py - Python Indexing Library Bindings -----------*- 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.
+  ranges.reverse()
+
+  # Do the actual formatting.
+  for r in ranges:
+    formatRange(r, args.style)
+
+
+if __name__ == '__main__':
+  main()

Propchange: clang-tools-extra/trunk/clang-format/clang-format-diff.py
------------------------------------------------------------------------------
    svn:executable = *





More information about the cfe-commits mailing list