r186625 - Added -lines X:Y option to specify line range to process. This is a more human-friendly alternative to -offset and -length.

Alexander Kornienko alexfh at google.com
Thu Jul 18 15:54:56 PDT 2013


Author: alexfh
Date: Thu Jul 18 17:54:56 2013
New Revision: 186625

URL: http://llvm.org/viewvc/llvm-project?rev=186625&view=rev
Log:
Added -lines X:Y option to specify line range to process. This is a more human-friendly alternative to -offset and -length.

Differential Revision: http://llvm-reviews.chandlerc.com/D1160

Added:
    cfe/trunk/test/Format/line-ranges.cpp
Modified:
    cfe/trunk/test/Format/multiple-inputs-error.cpp
    cfe/trunk/tools/clang-format/ClangFormat.cpp

Added: cfe/trunk/test/Format/line-ranges.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Format/line-ranges.cpp?rev=186625&view=auto
==============================================================================
--- cfe/trunk/test/Format/line-ranges.cpp (added)
+++ cfe/trunk/test/Format/line-ranges.cpp Thu Jul 18 17:54:56 2013
@@ -0,0 +1,11 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-format -style=LLVM -lines=1:1 -lines=5:5 -i %t.cpp
+// RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s
+// CHECK: {{^int\ \*i;$}}
+  int*i;
+
+// CHECK: {{^\ \ int\ \ \*\ \ i;$}}
+  int  *  i; 
+
+// CHECK: {{^\ \ int\ \*i;$}}
+  int   *   i;

Modified: cfe/trunk/test/Format/multiple-inputs-error.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Format/multiple-inputs-error.cpp?rev=186625&r1=186624&r2=186625&view=diff
==============================================================================
--- cfe/trunk/test/Format/multiple-inputs-error.cpp (original)
+++ cfe/trunk/test/Format/multiple-inputs-error.cpp Thu Jul 18 17:54:56 2013
@@ -1,6 +1,8 @@
 // RUN: cp %s %t-1.cpp
 // RUN: cp %s %t-2.cpp
 // RUN: not clang-format 2>&1 >/dev/null -offset=1 -length=0 %t-1.cpp %t-2.cpp |FileCheck %s
-// CHECK: error: "-offset" and "-length" can only be used for single file.
+// RUN: not clang-format 2>&1 >/dev/null -lines=1:1 %t-1.cpp %t-2.cpp |FileCheck %s -check-prefix=CHECK-LINE
+// CHECK: error: -offset, -length and -lines can only be used for single file.
+// CHECK-LINE: error: -offset, -length and -lines can only be used for single file.
 
 int i ;

Modified: cfe/trunk/tools/clang-format/ClangFormat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/ClangFormat.cpp?rev=186625&r1=186624&r2=186625&view=diff
==============================================================================
--- cfe/trunk/tools/clang-format/ClangFormat.cpp (original)
+++ cfe/trunk/tools/clang-format/ClangFormat.cpp Thu Jul 18 17:54:56 2013
@@ -53,6 +53,14 @@ static cl::list<unsigned>
                      "of the file.\n"
                      "Can only be used with one input file."),
             cl::cat(ClangFormatCategory));
+static cl::list<std::string>
+LineRanges("lines", cl::desc("<start line>:<end line> - format a range of\n"
+                             "lines (both 1-based).\n"
+                             "Multiple ranges can be formatted by specifying\n"
+                             "several -lines arguments.\n"
+                             "Can't be used with -offset and -length.\n"
+                             "Can only be used with one input file."),
+           cl::cat(ClangFormatCategory));
 static cl::opt<std::string>
     Style("style",
           cl::desc("Coding style, currently supports:\n"
@@ -150,21 +158,43 @@ FormatStyle getStyle(StringRef StyleName
   return Style;
 }
 
+// Parses <start line>:<end line> input to a pair of line numbers.
 // Returns true on error.
-static bool format(std::string FileName) {
-  FileManager Files((FileSystemOptions()));
-  DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-      new DiagnosticOptions);
-  SourceManager Sources(Diagnostics, Files);
-  OwningPtr<MemoryBuffer> Code;
-  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
-    llvm::errs() << ec.message() << "\n";
-    return true;
+static bool parseLineRange(StringRef Input, unsigned &FromLine,
+                           unsigned &ToLine) {
+  std::pair<StringRef, StringRef> LineRange = Input.split(':');
+  return LineRange.first.getAsInteger(0, FromLine) ||
+         LineRange.second.getAsInteger(0, ToLine);
+}
+
+static bool fillRanges(SourceManager &Sources, FileID ID,
+                       const MemoryBuffer *Code,
+                       std::vector<CharSourceRange> &Ranges) {
+  if (!LineRanges.empty()) {
+    if (!Offsets.empty() || !Lengths.empty()) {
+      llvm::errs() << "error: cannot use -lines with -offset/-length\n";
+      return true;
+    }
+
+    for (unsigned i = 0, e = LineRanges.size(); i < e; ++i) {
+      unsigned FromLine, ToLine;
+      if (parseLineRange(LineRanges[i], FromLine, ToLine)) {
+        llvm::errs() << "error: invalid <start line>:<end line> pair\n";
+        return true;
+      }
+      if (FromLine > ToLine) {
+        llvm::errs() << "error: start line should be less than end line\n";
+        return true;
+      }
+      SourceLocation Start = Sources.translateLineCol(ID, FromLine, 1);
+      SourceLocation End = Sources.translateLineCol(ID, ToLine, UINT_MAX);
+      if (Start.isInvalid() || End.isInvalid())
+        return true;
+      Ranges.push_back(CharSourceRange::getCharRange(Start, End));
+    }
+    return false;
   }
-  if (Code->getBufferSize() == 0)
-    return true; // Empty files are formatted correctly.
-  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
+
   if (Offsets.empty())
     Offsets.push_back(0);
   if (Offsets.size() != Lengths.size() &&
@@ -173,7 +203,6 @@ static bool format(std::string FileName)
         << "error: number of -offset and -length arguments must match.\n";
     return true;
   }
-  std::vector<CharSourceRange> Ranges;
   for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
     if (Offsets[i] >= Code->getBufferSize()) {
       llvm::errs() << "error: offset " << Offsets[i]
@@ -196,6 +225,28 @@ static bool format(std::string FileName)
     }
     Ranges.push_back(CharSourceRange::getCharRange(Start, End));
   }
+  return false;
+}
+
+// Returns true on error.
+static bool format(std::string FileName) {
+  FileManager Files((FileSystemOptions()));
+  DiagnosticsEngine Diagnostics(
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
+      new DiagnosticOptions);
+  SourceManager Sources(Diagnostics, Files);
+  OwningPtr<MemoryBuffer> Code;
+  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
+    llvm::errs() << ec.message() << "\n";
+    return true;
+  }
+  if (Code->getBufferSize() == 0)
+    return true; // Empty files are formatted correctly.
+  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
+  std::vector<CharSourceRange> Ranges;
+  if (fillRanges(Sources, ID, Code.get(), Ranges))
+    return true;
+
   FormatStyle FormatStyle = getStyle(Style, FileName);
   Lexer Lex(ID, Sources.getBuffer(ID), Sources,
             getFormattingLangOpts(FormatStyle.Standard));
@@ -282,8 +333,8 @@ int main(int argc, const char **argv) {
     Error = clang::format::format(FileNames[0]);
     break;
   default:
-    if (!Offsets.empty() || !Lengths.empty()) {
-      llvm::errs() << "error: \"-offset\" and \"-length\" can only be used for "
+    if (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty()) {
+      llvm::errs() << "error: -offset, -length and -lines can only be used for "
                       "single file.\n";
       return 1;
     }





More information about the cfe-commits mailing list