From 7c4a9a04b4b2a44259b34078434e087987872095 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Wed, 20 Mar 2013 09:53:23 +0000 Subject: Add clang-format binary to cfe. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177506 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/clang-format/clang-format-diff.py | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100755 tools/clang-format/clang-format-diff.py (limited to 'tools/clang-format/clang-format-diff.py') 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() -- cgit v1.2.3-70-g09d2 From 63911838bf7891445ff39fdc7f81d1469d54f5c1 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Tue, 9 Apr 2013 15:23:04 +0000 Subject: 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179098 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/clang-format/clang-format-diff.py | 10 +++---- tools/clang-format/clang-format.el | 47 +++++++++++++++++++++++++++++++++ tools/clang-format/clang-format.py | 7 ++++- 3 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 tools/clang-format/clang-format.el (limited to 'tools/clang-format/clang-format-diff.py') diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py index ab5f1b1bc6..16c6ad2159 100755 --- a/tools/clang-format/clang-format-diff.py +++ b/tools/clang-format/clang-format-diff.py @@ -63,9 +63,10 @@ def formatRange(r, style): 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, + command = [binary, '-offset', str(offset), '-length', str(length)] + if style: + command.append('-style', style) + p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate(input=text) if stderr: @@ -84,8 +85,7 @@ def main(): '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)') + parser.add_argument('-style', help='formatting style to apply (LLVM, Google)') args = parser.parse_args() filename = None diff --git a/tools/clang-format/clang-format.el b/tools/clang-format/clang-format.el new file mode 100644 index 0000000000..c63c62ee55 --- /dev/null +++ b/tools/clang-format/clang-format.el @@ -0,0 +1,47 @@ +;;; Clang-format emacs integration for use with C/Objective-C/C++. + +;; This defines a function clang-format-region that you can bind to a key. +;; A minimal .emacs would contain: +;; +;; (load "/tools/clang/clang-format/clang-format.el") +;; (global-set-key [C-M-tab] 'clang-format-region) +;; +;; Depending on your configuration and coding style, you might need to modify +;; 'style' and 'binary' below. +(defun clang-format-region () + (interactive) + (let ((orig-file buffer-file-name) + (orig-point (point)) + (orig-mark (mark t)) + (orig-mark-active mark-active) + (binary "clang-format") + (style "LLVM") + replacement-text replaced beg end) + (basic-save-buffer) + (save-restriction + (widen) + (if mark-active + (setq beg (1- (region-beginning)) + end (1- (region-end))) + (setq beg (1- (line-beginning-position)) + end (1- (line-end-position)))) + (with-temp-buffer + (call-process + binary orig-file '(t nil) t + "-offset" (number-to-string beg) + "-length" (number-to-string (- end beg)) + "-style" style) + (setq replacement-text + (buffer-substring-no-properties (point-min) (point-max)))) + (unless (string= replacement-text + (buffer-substring-no-properties (point-min) (point-max))) + (delete-region (point-min) (point-max)) + (insert replacement-text) + (setq replaced t))) + (ignore-errors + (when orig-mark + (push-mark orig-mark) + (when orig-mark-active + (activate-mark) + (setq deactivate-mark nil))) + (goto-char orig-point)))) diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py index de92257407..d90c62a5bf 100644 --- a/tools/clang-format/clang-format.py +++ b/tools/clang-format/clang-format.py @@ -23,6 +23,10 @@ import subprocess # Change this to the full path if clang-format is not on the path. binary = 'clang-format' +# Change this to format according to other formatting styles (see +# clang-format -help) +style = 'LLVM' + # Get the current text. buf = vim.current.buffer text = "\n".join(buf) @@ -34,7 +38,8 @@ length = int(vim.eval('line2byte(' + str(vim.current.range.end + 2) + ')')) - offset - 2 # Call formatter. -p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length)], +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) -- cgit v1.2.3-70-g09d2 From 7a9ed44173f9291534d935c5e4b11ddd24c01f29 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Fri, 12 Apr 2013 13:42:36 +0000 Subject: Fix clang-format-diff.py script. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179377 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/clang-format/clang-format-diff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/clang-format/clang-format-diff.py') diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py index 16c6ad2159..afed40fc92 100755 --- a/tools/clang-format/clang-format-diff.py +++ b/tools/clang-format/clang-format-diff.py @@ -65,7 +65,7 @@ def formatRange(r, style): text = f.read() command = [binary, '-offset', str(offset), '-length', str(length)] if style: - command.append('-style', style) + command.extend(['-style', style]) p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate(input=text) -- cgit v1.2.3-70-g09d2 From a50b57862b99bdd7d056014f429a809647257c8b Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Wed, 17 Apr 2013 07:55:02 +0000 Subject: Small improvements to clang-format documentation and integration scripts. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179676 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/ClangFormat.rst | 19 +++++++++++++++++-- tools/clang-format/clang-format-diff.py | 3 ++- tools/clang-format/clang-format.el | 14 +++++++------- 3 files changed, 26 insertions(+), 10 deletions(-) (limited to 'tools/clang-format/clang-format-diff.py') diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst index 92d7fc319e..1b65c2542b 100644 --- a/docs/ClangFormat.rst +++ b/docs/ClangFormat.rst @@ -18,7 +18,6 @@ to format C/C++/Obj-C code. $ clang-format --help OVERVIEW: A tool to format C/C++/Obj-C code. - Currently supports LLVM and Google style guides. If no arguments are specified, it formats the code from standard input and writes the result to the standard output. If is given, it reformats the file. If -i is specified together @@ -66,6 +65,22 @@ It operates on the current, potentially unsaved buffer and does not create or save any files. To revert a formatting, just undo. +Emacs Integration +================= + +Similar to the integration for :program:`vim`, there is an integration for +:program:`emacs`. It can be found at `clang/tools/clang-format/clang-format.el` +and used by adding this to your `.emacs`: + +.. code-block:: common-lisp + + (load "/tools/clang-format/clang-format.el") + (global-set-key [C-M-tab] 'clang-format-region) + +This binds the function `clang-format-region` to C-M-tab, which then formats the +current line or selected region. + + Script for patch reformatting ============================= @@ -81,7 +96,7 @@ a unified diff and reformats all contained lines with :program:`clang-format`. optional arguments: -h, --help show this help message and exit -p P strip the smallest prefix containing P slashes - -style STYLE formatting style to apply (LLVM, Google) + -style STYLE formatting style to apply (LLVM, Google, Chromium) So to reformat all the lines in the latest :program:`git` commit, just do: diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py index afed40fc92..68b5113d92 100755 --- a/tools/clang-format/clang-format-diff.py +++ b/tools/clang-format/clang-format-diff.py @@ -85,7 +85,8 @@ def main(): 'Reformat changed lines in diff') parser.add_argument('-p', default=1, help='strip the smallest prefix containing P slashes') - parser.add_argument('-style', help='formatting style to apply (LLVM, Google)') + parser.add_argument('-style', + help='formatting style to apply (LLVM, Google, Chromium)') args = parser.parse_args() filename = None diff --git a/tools/clang-format/clang-format.el b/tools/clang-format/clang-format.el index 1277885996..d58e40358b 100644 --- a/tools/clang-format/clang-format.el +++ b/tools/clang-format/clang-format.el @@ -3,7 +3,7 @@ ;; This defines a function clang-format-region that you can bind to a key. ;; A minimal .emacs would contain: ;; -;; (load "/tools/clang/clang-format/clang-format.el") +;; (load "/tools/clang-format/clang-format.el") ;; (global-set-key [C-M-tab] 'clang-format-region) ;; ;; Depending on your configuration and coding style, you might need to modify @@ -15,12 +15,12 @@ (binary "clang-format") (style "LLVM")) (if mark-active - (setq beg (1- (region-beginning)) - end (1- (region-end))) - (setq beg (1- (line-beginning-position)) - end (1- (line-end-position)))) - (call-process-region (point-min) (point-max) "clang-format" t t nil - "-offset" (number-to-string beg) + (setq beg (region-beginning) + end (region-end)) + (setq beg (line-beginning-position) + end (line-end-position))) + (call-process-region (point-min) (point-max) binary t t nil + "-offset" (number-to-string (1- beg)) "-length" (number-to-string (- end beg)) "-style" style) (goto-char orig-point) -- cgit v1.2.3-70-g09d2