[PATCH] Clang-format: added -fromline and -toline options to specify ranges in line numbers instead of byte offsets.
Alexander Kornienko
alexfh at google.com
Thu Jul 18 01:52:37 PDT 2013
Changed command-line syntax from -fromline X -toline Y to -lines X:Y.
Hi djasper,
http://llvm-reviews.chandlerc.com/D1160
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1160?vs=2855&id=2879#toc
Files:
test/Format/line-ranges.cpp
test/Format/multiple-inputs-error.cpp
tools/clang-format/ClangFormat.cpp
Index: test/Format/line-ranges.cpp
===================================================================
--- /dev/null
+++ test/Format/line-ranges.cpp
@@ -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;
Index: test/Format/multiple-inputs-error.cpp
===================================================================
--- test/Format/multiple-inputs-error.cpp
+++ test/Format/multiple-inputs-error.cpp
@@ -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 ;
Index: tools/clang-format/ClangFormat.cpp
===================================================================
--- tools/clang-format/ClangFormat.cpp
+++ tools/clang-format/ClangFormat.cpp
@@ -53,6 +53,14 @@
"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,6 +158,65 @@
return Style;
}
+// Gets offset of the first character of the line with given 1-based LineNumber
+// in Contents.
+// Returns true on error.
+static bool getLineStartOffset(unsigned LineNumber, StringRef Contents,
+ unsigned &Offset) {
+ StringRef::size_type LineOffset = 0;
+ for (unsigned CurrentLine = 1; CurrentLine < LineNumber; ++CurrentLine) {
+ LineOffset = Contents.find('\n', LineOffset);
+ if (LineOffset == StringRef::npos)
+ return true;
+ ++LineOffset;
+ }
+ Offset = LineOffset;
+ return false;
+}
+
+// Parses <start line>:<end line> input to a pair of line numbers.
+// Returns true on error.
+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);
+}
+
+// Converts -lines option values (LineRanges) to Offsets and Lengths.
+// Returns true on error.
+static bool convertLinesToOffsets(StringRef FileContents) {
+ if (LineRanges.empty())
+ return false;
+
+ if (!Offsets.empty() || !Lengths.empty()) {
+ llvm::errs() << "error: can not 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;
+ }
+ unsigned StartOffset, EndOffset;
+ if (getLineStartOffset(FromLine, FileContents, StartOffset) ||
+ getLineStartOffset(ToLine + 1, FileContents, EndOffset))
+ return true;
+ --EndOffset;
+ assert(StartOffset <= EndOffset);
+ Offsets.push_back(StartOffset);
+ Lengths.push_back(EndOffset - StartOffset);
+ }
+
+ return false;
+}
+
// Returns true on error.
static bool format(std::string FileName) {
FileManager Files((FileSystemOptions()));
@@ -164,6 +231,8 @@
}
if (Code->getBufferSize() == 0)
return true; // Empty files are formatted correctly.
+ if (convertLinesToOffsets(Code->getBuffer()))
+ return true;
FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
if (Offsets.empty())
Offsets.push_back(0);
@@ -282,8 +351,8 @@
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;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1160.2.patch
Type: text/x-patch
Size: 5094 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130718/2668e303/attachment.bin>
More information about the cfe-commits
mailing list