summaryrefslogtreecommitdiff
path: root/tools/clang-format/ClangFormat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/clang-format/ClangFormat.cpp')
-rw-r--r--tools/clang-format/ClangFormat.cpp65
1 files changed, 52 insertions, 13 deletions
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index 768165b92e9d..cebb2757d4da 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -17,13 +17,14 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Signals.h"
-#include "llvm/ADT/StringMap.h"
using namespace llvm;
@@ -31,7 +32,7 @@ static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
// Mark all our options with this category, everything else (except for -version
// and -help) will be hidden.
-cl::OptionCategory ClangFormatCategory("Clang-format options");
+static cl::OptionCategory ClangFormatCategory("Clang-format options");
static cl::list<unsigned>
Offsets("offset",
@@ -62,6 +63,14 @@ static cl::opt<std::string>
Style("style",
cl::desc(clang::format::StyleOptionHelpDescription),
cl::init("file"), cl::cat(ClangFormatCategory));
+static cl::opt<std::string>
+FallbackStyle("fallback-style",
+ cl::desc("The name of the predefined style used as a\n"
+ "fallback in case clang-format is invoked with\n"
+ "-style=file, but can not find the .clang-format\n"
+ "file to use.\n"
+ "Use -fallback-style=none to skip formatting."),
+ cl::init("LLVM"), cl::cat(ClangFormatCategory));
static cl::opt<std::string>
AssumeFilename("assume-filename",
@@ -94,7 +103,7 @@ static cl::list<std::string> FileNames(cl::Positional, cl::desc("[<file> ...]"),
namespace clang {
namespace format {
-static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
+static FileID createInMemoryFile(StringRef FileName, MemoryBuffer *Source,
SourceManager &Sources, FileManager &Files) {
const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :
FileName,
@@ -173,6 +182,26 @@ static bool fillRanges(SourceManager &Sources, FileID ID,
return false;
}
+static void outputReplacementXML(StringRef Text) {
+ size_t From = 0;
+ size_t Index;
+ while ((Index = Text.find_first_of("\n\r", From)) != StringRef::npos) {
+ llvm::outs() << Text.substr(From, Index - From);
+ switch (Text[Index]) {
+ case '\n':
+ llvm::outs() << "&#10;";
+ break;
+ case '\r':
+ llvm::outs() << "&#13;";
+ break;
+ default:
+ llvm_unreachable("Unexpected character encountered!");
+ }
+ From = Index + 1;
+ }
+ llvm::outs() << Text.substr(From);
+}
+
// Returns true on error.
static bool format(StringRef FileName) {
FileManager Files((FileSystemOptions()));
@@ -180,11 +209,13 @@ static bool format(StringRef FileName) {
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";
+ ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
+ MemoryBuffer::getFileOrSTDIN(FileName);
+ if (std::error_code EC = CodeOrErr.getError()) {
+ llvm::errs() << EC.message() << "\n";
return true;
}
+ std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
if (Code->getBufferSize() == 0)
return false; // Empty files are formatted correctly.
FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
@@ -192,8 +223,8 @@ static bool format(StringRef FileName) {
if (fillRanges(Sources, ID, Code.get(), Ranges))
return true;
- FormatStyle FormatStyle =
- getStyle(Style, (FileName == "-") ? AssumeFilename : FileName);
+ FormatStyle FormatStyle = getStyle(
+ Style, (FileName == "-") ? AssumeFilename : FileName, FallbackStyle);
Lexer Lex(ID, Sources.getBuffer(ID), Sources,
getFormattingLangOpts(FormatStyle.Standard));
tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
@@ -205,8 +236,9 @@ static bool format(StringRef FileName) {
I != E; ++I) {
llvm::outs() << "<replacement "
<< "offset='" << I->getOffset() << "' "
- << "length='" << I->getLength() << "'>"
- << I->getReplacementText() << "</replacement>\n";
+ << "length='" << I->getLength() << "'>";
+ outputReplacementXML(I->getReplacementText());
+ llvm::outs() << "</replacement>\n";
}
llvm::outs() << "</replacements>\n";
} else {
@@ -217,8 +249,8 @@ static bool format(StringRef FileName) {
return true;
} else {
if (Cursor.getNumOccurrences() != 0)
- outs() << "{ \"Cursor\": " << tooling::shiftedCodePosition(
- Replaces, Cursor) << " }\n";
+ outs() << "{ \"Cursor\": "
+ << tooling::shiftedCodePosition(Replaces, Cursor) << " }\n";
Rewrite.getEditBuffer(ID).write(outs());
}
}
@@ -228,6 +260,11 @@ static bool format(StringRef FileName) {
} // namespace format
} // namespace clang
+static void PrintVersion() {
+ raw_ostream &OS = outs();
+ OS << clang::getClangToolFullVersion("clang-format") << '\n';
+}
+
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
@@ -241,6 +278,7 @@ int main(int argc, const char **argv) {
I->second->setHiddenFlag(cl::ReallyHidden);
}
+ cl::SetVersionPrinter(PrintVersion);
cl::ParseCommandLineOptions(
argc, argv,
"A tool to format C/C++/Obj-C code.\n\n"
@@ -256,7 +294,8 @@ int main(int argc, const char **argv) {
if (DumpConfig) {
std::string Config =
clang::format::configurationAsText(clang::format::getStyle(
- Style, FileNames.empty() ? AssumeFilename : FileNames[0]));
+ Style, FileNames.empty() ? AssumeFilename : FileNames[0],
+ FallbackStyle));
llvm::outs() << Config << "\n";
return 0;
}