<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">w00t, thanks!<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">      </span>- Doug</div><div><br><div><div>On Mar 20, 2013, at 2:53 AM, Daniel Jasper <<a href="mailto:djasper@google.com">djasper@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">Author: djasper<br>Date: Wed Mar 20 04:53:23 2013<br>New Revision: 177506<br><br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project?rev=177506&view=rev">http://llvm.org/viewvc/llvm-project?rev=177506&view=rev</a><br>Log:<br>Add clang-format binary to cfe.<br><br>Added:<br>   cfe/trunk/tools/clang-format/<br>   cfe/trunk/tools/clang-format/CMakeLists.txt<br>   cfe/trunk/tools/clang-format/ClangFormat.cpp<br>   cfe/trunk/tools/clang-format/Makefile<br>   cfe/trunk/tools/clang-format/clang-format-diff.py   (with props)<br>   cfe/trunk/tools/clang-format/clang-format.py<br>Modified:<br>   cfe/trunk/tools/CMakeLists.txt<br><br>Modified: cfe/trunk/tools/CMakeLists.txt<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CMakeLists.txt?rev=177506&r1=177505&r2=177506&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CMakeLists.txt?rev=177506&r1=177505&r2=177506&view=diff</a><br>==============================================================================<br>--- cfe/trunk/tools/CMakeLists.txt (original)<br>+++ cfe/trunk/tools/CMakeLists.txt Wed Mar 20 04:53:23 2013<br>@@ -5,6 +5,7 @@ add_subdirectory(c-arcmt-test)<br>add_subdirectory(diagtool)<br>add_subdirectory(driver)<br>add_subdirectory(clang-check)<br>+add_subdirectory(clang-format)<br><br># We support checking out the clang-tools-extra repository into the 'extra'<br># subdirectory. It contains tools developed as part of the Clang/LLVM project<br><br>Added: cfe/trunk/tools/clang-format/CMakeLists.txt<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/CMakeLists.txt?rev=177506&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/CMakeLists.txt?rev=177506&view=auto</a><br>==============================================================================<br>--- cfe/trunk/tools/clang-format/CMakeLists.txt (added)<br>+++ cfe/trunk/tools/clang-format/CMakeLists.txt Wed Mar 20 04:53:23 2013<br>@@ -0,0 +1,17 @@<br>+set(LLVM_LINK_COMPONENTS support)<br>+set(LLVM_USED_LIBS clangFormat clangTooling clangBasic clangAST)<br>+<br>+add_clang_executable(clang-format<br>+  ClangFormat.cpp<br>+  )<br>+<br>+target_link_libraries(clang-format<br>+  clangFormat<br>+  clangTooling<br>+  clangBasic<br>+  clangRewriteFrontend<br>+  )<br>+<br>+install(TARGETS clang-format<br>+  RUNTIME DESTINATION bin)<br>+<br><br>Added: cfe/trunk/tools/clang-format/ClangFormat.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/ClangFormat.cpp?rev=177506&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/ClangFormat.cpp?rev=177506&view=auto</a><br>==============================================================================<br>--- cfe/trunk/tools/clang-format/ClangFormat.cpp (added)<br>+++ cfe/trunk/tools/clang-format/ClangFormat.cpp Wed Mar 20 04:53:23 2013<br>@@ -0,0 +1,152 @@<br>+//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//<br>+//<br>+//                     The LLVM Compiler Infrastructure<br>+//<br>+// This file is distributed under the University of Illinois Open Source<br>+// License. See LICENSE.TXT for details.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+///<br>+/// \file<br>+/// \brief This file implements a clang-format tool that automatically formats<br>+/// (fragments of) C++ code.<br>+///<br>+//===----------------------------------------------------------------------===//<br>+<br>+#include "clang/Basic/Diagnostic.h"<br>+#include "clang/Basic/DiagnosticOptions.h"<br>+#include "clang/Basic/FileManager.h"<br>+#include "clang/Basic/SourceManager.h"<br>+#include "clang/Format/Format.h"<br>+#include "clang/Lex/Lexer.h"<br>+#include "clang/Rewrite/Core/Rewriter.h"<br>+#include "llvm/Support/FileSystem.h"<br>+#include "llvm/Support/Signals.h"<br>+<br>+using namespace llvm;<br>+<br>+static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);<br>+<br>+static cl::list<int> Offsets(<br>+    "offset", cl::desc("Format a range starting at this file offset."));<br>+static cl::list<int> Lengths(<br>+    "length", cl::desc("Format a range of this length, -1 for end of file."));<br>+static cl::opt<std::string> Style(<br>+    "style",<br>+    cl::desc("Coding style, currently supports: LLVM, Google, Chromium."),<br>+    cl::init("LLVM"));<br>+static cl::opt<bool> Inplace("i",<br>+                             cl::desc("Inplace edit <file>, if specified."));<br>+<br>+static cl::opt<bool> OutputXML(<br>+    "output-replacements-xml", cl::desc("Output replacements as XML."));<br>+<br>+static cl::opt<std::string> FileName(cl::Positional, cl::desc("[<file>]"),<br>+                                     cl::init("-"));<br>+<br>+namespace clang {<br>+namespace format {<br>+<br>+static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,<br>+                                 SourceManager &Sources, FileManager &Files) {<br>+  const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :<br>+                                                    FileName,<br>+                                                Source->getBufferSize(), 0);<br>+  Sources.overrideFileContents(Entry, Source, true);<br>+  return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);<br>+}<br>+<br>+static FormatStyle getStyle() {<br>+  FormatStyle TheStyle = getGoogleStyle();<br>+  if (Style == "LLVM")<br>+    TheStyle = getLLVMStyle();<br>+  if (Style == "Chromium")<br>+    TheStyle = getChromiumStyle();<br>+  return TheStyle;<br>+}<br>+<br>+static void format() {<br>+  FileManager Files((FileSystemOptions()));<br>+  DiagnosticsEngine Diagnostics(<br>+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),<br>+      new DiagnosticOptions);<br>+  SourceManager Sources(Diagnostics, Files);<br>+  OwningPtr<MemoryBuffer> Code;<br>+  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {<br>+    llvm::errs() << ec.message() << "\n";<br>+    return;<br>+  }<br>+  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);<br>+  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());<br>+  if (Offsets.empty())<br>+    Offsets.push_back(0);<br>+  if (Offsets.size() != Lengths.size() &&<br>+      !(Offsets.size() == 1 && Lengths.empty())) {<br>+    llvm::errs() << "Number of -offset and -length arguments must match.\n";<br>+    return;<br>+  }<br>+  std::vector<CharSourceRange> Ranges;<br>+  for (cl::list<int>::size_type i = 0, e = Offsets.size(); i != e; ++i) {<br>+    SourceLocation Start =<br>+        Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);<br>+    SourceLocation End;<br>+    if (i < Lengths.size()) {<br>+      End = Start.getLocWithOffset(Lengths[i]);<br>+    } else {<br>+      End = Sources.getLocForEndOfFile(ID);<br>+    }<br>+    Ranges.push_back(CharSourceRange::getCharRange(Start, End));<br>+  }<br>+  tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);<br>+  if (OutputXML) {<br>+    llvm::outs() << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";<br>+    for (tooling::Replacements::const_iterator I = Replaces.begin(),<br>+                                               E = Replaces.end();<br>+         I != E; ++I) {<br>+      llvm::outs() << "<replacement "<br>+                   << "offset='" << I->getOffset() << "' "<br>+                   << "length='" << I->getLength() << "'>"<br>+                   << I->getReplacementText() << "</replacement>\n";<br>+    }<br>+    llvm::outs() << "</replacements>\n";<br>+  } else {<br>+    Rewriter Rewrite(Sources, LangOptions());<br>+    tooling::applyAllReplacements(Replaces, Rewrite);<br>+    if (Inplace) {<br>+      if (Replaces.size() == 0)<br>+        return; // Nothing changed, don't touch the file.<br>+<br>+      std::string ErrorInfo;<br>+      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,<br>+                                      llvm::raw_fd_ostream::F_Binary);<br>+      if (!ErrorInfo.empty()) {<br>+        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";<br>+        return;<br>+      }<br>+      Rewrite.getEditBuffer(ID).write(FileStream);<br>+      FileStream.flush();<br>+    } else {<br>+      Rewrite.getEditBuffer(ID).write(outs());<br>+    }<br>+  }<br>+}<br>+<br>+}  // namespace format<br>+}  // namespace clang<br>+<br>+int main(int argc, const char **argv) {<br>+  llvm::sys::PrintStackTraceOnErrorSignal();<br>+  cl::ParseCommandLineOptions(<br>+      argc, argv,<br>+      "A tool to format C/C++/Obj-C code.\n\n"<br>+      "Currently supports LLVM and Google style guides.\n"<br>+      "If no arguments are specified, it formats the code from standard input\n"<br>+      "and writes the result to the standard output.\n"<br>+      "If <file> is given, it reformats the file. If -i is specified together\n"<br>+      "with <file>, the file is edited in-place. Otherwise, the result is\n"<br>+      "written to the standard output.\n");<br>+  if (Help)<br>+    cl::PrintHelpMessage();<br>+  clang::format::format();<br>+  return 0;<br>+}<br><br>Added: cfe/trunk/tools/clang-format/Makefile<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/Makefile?rev=177506&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/Makefile?rev=177506&view=auto</a><br>==============================================================================<br>--- cfe/trunk/tools/clang-format/Makefile (added)<br>+++ cfe/trunk/tools/clang-format/Makefile Wed Mar 20 04:53:23 2013<br>@@ -0,0 +1,24 @@<br>+##===- clang-format/Makefile -------------------------------*- Makefile -*-===##<br>+#<br>+#                     The LLVM Compiler Infrastructure<br>+#<br>+# This file is distributed under the University of Illinois Open Source<br>+# License. See LICENSE.TXT for details.<br>+#<br>+##===----------------------------------------------------------------------===##<br>+<br>+CLANG_LEVEL := ../..<br>+<br>+TOOLNAME = clang-format<br>+<br>+# No plugins, optimize startup time.<br>+TOOL_NO_EXPORTS = 1<br>+<br>+include $(CLANG_LEVEL)/../../Makefile.config<br>+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc<br>+USEDLIBS = clangFormat.a clangTooling.a clangFrontend.a clangSerialization.a \<br>+<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-converted-space"> </span>  clangDriver.a clangParse.a clangSema.a clangAnalysis.a \<br>+           clangRewriteFrontend.a clangRewriteCore.a clangEdit.a clangAST.a \<br>+           clangLex.a clangBasic.a<span class="Apple-converted-space"> </span><br>+<br>+include $(CLANG_LEVEL)/Makefile<br><br>Added: cfe/trunk/tools/clang-format/clang-format-diff.py<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/clang-format-diff.py?rev=177506&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/clang-format-diff.py?rev=177506&view=auto</a><br>==============================================================================<br>--- cfe/trunk/tools/clang-format/clang-format-diff.py (added)<br>+++ cfe/trunk/tools/clang-format/clang-format-diff.py Wed Mar 20 04:53:23 2013<br>@@ -0,0 +1,115 @@<br>+#!/usr/bin/python<br>+#<br>+#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#<br>+#<br>+#                     The LLVM Compiler Infrastructure<br>+#<br>+# This file is distributed under the University of Illinois Open Source<br>+# License. See LICENSE.TXT for details.<br>+#<br>+#===------------------------------------------------------------------------===#<br>+<br>+r"""<br>+ClangFormat Diff Reformatter<br>+============================<br>+<br>+This script reads input from a unified diff and reformats all the changed<br>+lines. This is useful to reformat all the lines touched by a specific patch.<br>+Example usage for git users:<br>+<br>+  git diff -U0 HEAD^ | clang-format-diff.py -p1<br>+<br>+"""<br>+<br>+import argparse<br>+import re<br>+import subprocess<br>+import sys<br>+<br>+<br>+# Change this to the full path if clang-format is not on the path.<br>+binary = 'clang-format'<br>+<br>+<br>+def getOffsetLength(filename, line_number, line_count):<br>+  """<br>+  Calculates the field offset and length based on line number and count.<br>+  """<br>+  offset = 0<br>+  length = 0<br>+  with open(filename, 'r') as f:<br>+    for line in f:<br>+      if line_number > 1:<br>+        offset += len(line)<br>+        line_number -= 1<br>+      elif line_count > 0:<br>+        length += len(line)<br>+        line_count -= 1<br>+      else:<br>+        break<br>+  return offset, length<br>+<br>+<br>+def formatRange(r, style):<br>+  """<br>+  Formats range 'r' according to style 'style'.<br>+  """<br>+  filename, line_number, line_count = r<br>+  # FIXME: Add other types containing C++/ObjC code.<br>+  if not (filename.endswith(".cpp") or filename.endswith(".cc") or<br>+          filename.endswith(".h")):<br>+    return<br>+<br>+  offset, length = getOffsetLength(filename, line_number, line_count)<br>+  with open(filename, 'r') as f:<br>+    text = f.read()<br>+  p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length),<br>+                        '-style', style],<br>+                       stdout=subprocess.PIPE, stderr=subprocess.PIPE,<br>+                       stdin=subprocess.PIPE)<br>+  stdout, stderr = p.communicate(input=text)<br>+  if stderr:<br>+    print stderr<br>+    return<br>+  if not stdout:<br>+    print 'Segfault occurred while formatting', filename<br>+    print 'Please report a bug on<span class="Apple-converted-space"> </span><a href="http://llvm.org/bugs.'">llvm.org/bugs.'</a><br>+    return<br>+  with open(filename, 'w') as f:<br>+    f.write(stdout)<br>+<br>+<br>+def main():<br>+  parser = argparse.ArgumentParser(description=<br>+                                   'Reformat changed lines in diff')<br>+  parser.add_argument('-p', default=1,<br>+                      help='strip the smallest prefix containing P slashes')<br>+  parser.add_argument('-style', default='LLVM',<br>+                      help='formatting style to apply (LLVM, Google)')<br>+  args = parser.parse_args()<br>+<br>+  filename = None<br>+  ranges = []<br>+<br>+  for line in sys.stdin:<br>+    match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)<br>+    if match:<br>+      filename = match.group(2)<br>+    if filename == None:<br>+      continue<br>+<br>+    match = re.search('^@@.*\+(\d+)(,(\d+))?', line)<br>+    if match:<br>+      line_count = 1<br>+      if match.group(3):<br>+        line_count = int(match.group(3))<br>+      ranges.append((filename, int(match.group(1)), line_count))<br>+<br>+  # Reverse the ranges so that the reformatting does not influence file offsets.<br>+  for r in reversed(ranges):<br>+    # Do the actual formatting.<br>+    formatRange(r, args.style)<br>+<br>+<br>+if __name__ == '__main__':<br>+  main()<br><br>Propchange: cfe/trunk/tools/clang-format/clang-format-diff.py<br>------------------------------------------------------------------------------<br>   svn:executable = *<br><br>Added: cfe/trunk/tools/clang-format/clang-format.py<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/clang-format.py?rev=177506&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/clang-format.py?rev=177506&view=auto</a><br>==============================================================================<br>--- cfe/trunk/tools/clang-format/clang-format.py (added)<br>+++ cfe/trunk/tools/clang-format/clang-format.py Wed Mar 20 04:53:23 2013<br>@@ -0,0 +1,60 @@<br>+# This file is a minimal clang-format vim-integration. To install:<br>+# - Change 'binary' if clang-format is not on the path (see below).<br>+# - Add to your .vimrc:<br>+#<br>+#   map <C-I> :pyf <path-to-this-file>/clang-format.py<CR><br>+#   imap <C-I> <ESC>:pyf <path-to-this-file>/clang-format.py<CR>i<br>+#<br>+# The first line enables clang-format for NORMAL and VISUAL mode, the second<br>+# line adds support for INSERT mode. Change "C-I" to another binding if you<br>+# need clang-format on a different key (C-I stands for Ctrl+i).<br>+#<br>+# With this integration you can press the bound key and clang-format will<br>+# format the current line in NORMAL and INSERT mode or the selected region in<br>+# VISUAL mode. The line or region is extended to the next bigger syntactic<br>+# entity.<br>+#<br>+# It operates on the current, potentially unsaved buffer and does not create<br>+# or save any files. To revert a formatting, just undo.<br>+<br>+import vim<br>+import subprocess<br>+<br>+# Change this to the full path if clang-format is not on the path.<br>+binary = 'clang-format'<br>+<br>+# Get the current text.<br>+buf = vim.current.buffer<br>+text = "\n".join(buf)<br>+<br>+# Determine range to format.<br>+offset = int(vim.eval('line2byte(' +<br>+                      str(vim.current.range.start + 1) + ')')) - 1<br>+length = int(vim.eval('line2byte(' +<br>+                      str(vim.current.range.end + 2) + ')')) - offset - 2<br>+<br>+# Call formatter.<br>+p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length)],<br>+                     stdout=subprocess.PIPE, stderr=subprocess.PIPE,<br>+                     stdin=subprocess.PIPE)<br>+stdout, stderr = p.communicate(input=text)<br>+<br>+# If successful, replace buffer contents.<br>+if stderr:<br>+  message = stderr.splitlines()[0]<br>+  parts = message.split(' ', 2)<br>+  if len(parts) > 2:<br>+    message = parts[2]<br>+  print 'Formatting failed: %s (total %d warnings, %d errors)' % (<br>+      message, stderr.count('warning:'), stderr.count('error:'))<br>+<br>+if not stdout:<br>+  print ('No output from clang-format (crashed?).\n' +<br>+      'Please report to<span class="Apple-converted-space"> </span><a href="http://bugs.llvm.org/">bugs.llvm.org</a>.')<br>+elif stdout != text:<br>+  lines = stdout.split('\n')<br>+  for i in range(min(len(buf), len(lines))):<br>+    buf[i] = lines[i]<br>+  for line in lines[len(buf):]:<br>+    buf.append(line)<br>+  del buf[len(lines):]<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a></div></blockquote></div><br></div></body></html>