Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit d95f88a

Browse files
committedJul 18, 2013
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186625 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 44b41b1 commit d95f88a

File tree

3 files changed

+81
-17
lines changed

3 files changed

+81
-17
lines changed
 

‎test/Format/line-ranges.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
2+
// RUN: clang-format -style=LLVM -lines=1:1 -lines=5:5 -i %t.cpp
3+
// RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s
4+
// CHECK: {{^int\ \*i;$}}
5+
int*i;
6+
7+
// CHECK: {{^\ \ int\ \ \*\ \ i;$}}
8+
int * i;
9+
10+
// CHECK: {{^\ \ int\ \*i;$}}
11+
int * i;

‎test/Format/multiple-inputs-error.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: cp %s %t-1.cpp
22
// RUN: cp %s %t-2.cpp
33
// RUN: not clang-format 2>&1 >/dev/null -offset=1 -length=0 %t-1.cpp %t-2.cpp |FileCheck %s
4-
// CHECK: error: "-offset" and "-length" can only be used for single file.
4+
// RUN: not clang-format 2>&1 >/dev/null -lines=1:1 %t-1.cpp %t-2.cpp |FileCheck %s -check-prefix=CHECK-LINE
5+
// CHECK: error: -offset, -length and -lines can only be used for single file.
6+
// CHECK-LINE: error: -offset, -length and -lines can only be used for single file.
57

68
int i ;

‎tools/clang-format/ClangFormat.cpp

+67-16
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ static cl::list<unsigned>
5353
"of the file.\n"
5454
"Can only be used with one input file."),
5555
cl::cat(ClangFormatCategory));
56+
static cl::list<std::string>
57+
LineRanges("lines", cl::desc("<start line>:<end line> - format a range of\n"
58+
"lines (both 1-based).\n"
59+
"Multiple ranges can be formatted by specifying\n"
60+
"several -lines arguments.\n"
61+
"Can't be used with -offset and -length.\n"
62+
"Can only be used with one input file."),
63+
cl::cat(ClangFormatCategory));
5664
static cl::opt<std::string>
5765
Style("style",
5866
cl::desc("Coding style, currently supports:\n"
@@ -150,21 +158,43 @@ FormatStyle getStyle(StringRef StyleName, StringRef FileName) {
150158
return Style;
151159
}
152160

161+
// Parses <start line>:<end line> input to a pair of line numbers.
153162
// Returns true on error.
154-
static bool format(std::string FileName) {
155-
FileManager Files((FileSystemOptions()));
156-
DiagnosticsEngine Diagnostics(
157-
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
158-
new DiagnosticOptions);
159-
SourceManager Sources(Diagnostics, Files);
160-
OwningPtr<MemoryBuffer> Code;
161-
if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
162-
llvm::errs() << ec.message() << "\n";
163-
return true;
163+
static bool parseLineRange(StringRef Input, unsigned &FromLine,
164+
unsigned &ToLine) {
165+
std::pair<StringRef, StringRef> LineRange = Input.split(':');
166+
return LineRange.first.getAsInteger(0, FromLine) ||
167+
LineRange.second.getAsInteger(0, ToLine);
168+
}
169+
170+
static bool fillRanges(SourceManager &Sources, FileID ID,
171+
const MemoryBuffer *Code,
172+
std::vector<CharSourceRange> &Ranges) {
173+
if (!LineRanges.empty()) {
174+
if (!Offsets.empty() || !Lengths.empty()) {
175+
llvm::errs() << "error: cannot use -lines with -offset/-length\n";
176+
return true;
177+
}
178+
179+
for (unsigned i = 0, e = LineRanges.size(); i < e; ++i) {
180+
unsigned FromLine, ToLine;
181+
if (parseLineRange(LineRanges[i], FromLine, ToLine)) {
182+
llvm::errs() << "error: invalid <start line>:<end line> pair\n";
183+
return true;
184+
}
185+
if (FromLine > ToLine) {
186+
llvm::errs() << "error: start line should be less than end line\n";
187+
return true;
188+
}
189+
SourceLocation Start = Sources.translateLineCol(ID, FromLine, 1);
190+
SourceLocation End = Sources.translateLineCol(ID, ToLine, UINT_MAX);
191+
if (Start.isInvalid() || End.isInvalid())
192+
return true;
193+
Ranges.push_back(CharSourceRange::getCharRange(Start, End));
194+
}
195+
return false;
164196
}
165-
if (Code->getBufferSize() == 0)
166-
return true; // Empty files are formatted correctly.
167-
FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
197+
168198
if (Offsets.empty())
169199
Offsets.push_back(0);
170200
if (Offsets.size() != Lengths.size() &&
@@ -173,7 +203,6 @@ static bool format(std::string FileName) {
173203
<< "error: number of -offset and -length arguments must match.\n";
174204
return true;
175205
}
176-
std::vector<CharSourceRange> Ranges;
177206
for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
178207
if (Offsets[i] >= Code->getBufferSize()) {
179208
llvm::errs() << "error: offset " << Offsets[i]
@@ -196,6 +225,28 @@ static bool format(std::string FileName) {
196225
}
197226
Ranges.push_back(CharSourceRange::getCharRange(Start, End));
198227
}
228+
return false;
229+
}
230+
231+
// Returns true on error.
232+
static bool format(std::string FileName) {
233+
FileManager Files((FileSystemOptions()));
234+
DiagnosticsEngine Diagnostics(
235+
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
236+
new DiagnosticOptions);
237+
SourceManager Sources(Diagnostics, Files);
238+
OwningPtr<MemoryBuffer> Code;
239+
if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
240+
llvm::errs() << ec.message() << "\n";
241+
return true;
242+
}
243+
if (Code->getBufferSize() == 0)
244+
return true; // Empty files are formatted correctly.
245+
FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
246+
std::vector<CharSourceRange> Ranges;
247+
if (fillRanges(Sources, ID, Code.get(), Ranges))
248+
return true;
249+
199250
FormatStyle FormatStyle = getStyle(Style, FileName);
200251
Lexer Lex(ID, Sources.getBuffer(ID), Sources,
201252
getFormattingLangOpts(FormatStyle.Standard));
@@ -282,8 +333,8 @@ int main(int argc, const char **argv) {
282333
Error = clang::format::format(FileNames[0]);
283334
break;
284335
default:
285-
if (!Offsets.empty() || !Lengths.empty()) {
286-
llvm::errs() << "error: \"-offset\" and \"-length\" can only be used for "
336+
if (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty()) {
337+
llvm::errs() << "error: -offset, -length and -lines can only be used for "
287338
"single file.\n";
288339
return 1;
289340
}

0 commit comments

Comments
 (0)
This repository has been archived.