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

Nico Weber thakis at chromium.org
Wed Jan 9 16:15:22 PST 2013


On Wed, Jan 9, 2013 at 4:04 PM, Matt Beaumont-Gay <matthewbg at google.com> wrote:
> On Wed, Jan 9, 2013 at 12:20 PM, Daniel Jasper <djasper at google.com> wrote:
>> 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
>
> Maybe define a namedtuple (collections.namedtuple) for this?
>
>> +  # FIXME: Add other types containing C++/ObjC code.
>> +  if not (filename.endswith(".cpp") or filename.endswith(".cc") or
>> +          filename.endswith(".h")):
>
> if os.path.splitext(filename)[1] not in ('cc', 'cpp', '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
>
> print >>sys.stderr, stderr

These days, probably `from __future__ import print_function` at the
top and then `print(stderr, file=sys.stderr)` :-)

>
> Or just hook up the subprocess's stderr to our 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)
>
> I like to have a comment with an example along with nontrivial regular
> expressions.
>
> Also, here and below, you can use re.match instead of anchoring the
> regex with '^'.
>
>> +    if match:
>> +      filename = match.group(2)
>> +    if filename == None:
>
> if filename is 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 = *
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
> On Wed, Jan 9, 2013 at 12:20 PM, Daniel Jasper <djasper at google.com> wrote:
>> 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 = *
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list