mirror of https://github.com/microsoft/clang.git
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
This commit is contained in:
parent
44b41b12a4
commit
d95f88a616
|
@ -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;
|
|
@ -1,6 +1,8 @@
|
||||||
// RUN: cp %s %t-1.cpp
|
// RUN: cp %s %t-1.cpp
|
||||||
// RUN: cp %s %t-2.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
|
// 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 ;
|
int i ;
|
||||||
|
|
|
@ -53,6 +53,14 @@ static cl::list<unsigned>
|
||||||
"of the file.\n"
|
"of the file.\n"
|
||||||
"Can only be used with one input file."),
|
"Can only be used with one input file."),
|
||||||
cl::cat(ClangFormatCategory));
|
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>
|
static cl::opt<std::string>
|
||||||
Style("style",
|
Style("style",
|
||||||
cl::desc("Coding style, currently supports:\n"
|
cl::desc("Coding style, currently supports:\n"
|
||||||
|
@ -150,21 +158,43 @@ FormatStyle getStyle(StringRef StyleName, StringRef FileName) {
|
||||||
return Style;
|
return Style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parses <start line>:<end line> input to a pair of line numbers.
|
||||||
// Returns true on error.
|
// Returns true on error.
|
||||||
static bool format(std::string FileName) {
|
static bool parseLineRange(StringRef Input, unsigned &FromLine,
|
||||||
FileManager Files((FileSystemOptions()));
|
unsigned &ToLine) {
|
||||||
DiagnosticsEngine Diagnostics(
|
std::pair<StringRef, StringRef> LineRange = Input.split(':');
|
||||||
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
|
return LineRange.first.getAsInteger(0, FromLine) ||
|
||||||
new DiagnosticOptions);
|
LineRange.second.getAsInteger(0, ToLine);
|
||||||
SourceManager Sources(Diagnostics, Files);
|
}
|
||||||
OwningPtr<MemoryBuffer> Code;
|
|
||||||
if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
|
static bool fillRanges(SourceManager &Sources, FileID ID,
|
||||||
llvm::errs() << ec.message() << "\n";
|
const MemoryBuffer *Code,
|
||||||
return true;
|
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())
|
if (Offsets.empty())
|
||||||
Offsets.push_back(0);
|
Offsets.push_back(0);
|
||||||
if (Offsets.size() != Lengths.size() &&
|
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";
|
<< "error: number of -offset and -length arguments must match.\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::vector<CharSourceRange> Ranges;
|
|
||||||
for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
|
||||||
if (Offsets[i] >= Code->getBufferSize()) {
|
if (Offsets[i] >= Code->getBufferSize()) {
|
||||||
llvm::errs() << "error: offset " << Offsets[i]
|
llvm::errs() << "error: offset " << Offsets[i]
|
||||||
|
@ -196,6 +225,28 @@ static bool format(std::string FileName) {
|
||||||
}
|
}
|
||||||
Ranges.push_back(CharSourceRange::getCharRange(Start, End));
|
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);
|
FormatStyle FormatStyle = getStyle(Style, FileName);
|
||||||
Lexer Lex(ID, Sources.getBuffer(ID), Sources,
|
Lexer Lex(ID, Sources.getBuffer(ID), Sources,
|
||||||
getFormattingLangOpts(FormatStyle.Standard));
|
getFormattingLangOpts(FormatStyle.Standard));
|
||||||
|
@ -282,8 +333,8 @@ int main(int argc, const char **argv) {
|
||||||
Error = clang::format::format(FileNames[0]);
|
Error = clang::format::format(FileNames[0]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!Offsets.empty() || !Lengths.empty()) {
|
if (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty()) {
|
||||||
llvm::errs() << "error: \"-offset\" and \"-length\" can only be used for "
|
llvm::errs() << "error: -offset, -length and -lines can only be used for "
|
||||||
"single file.\n";
|
"single file.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue