diff options
Diffstat (limited to 'tools/clang-format/ClangFormat.cpp')
-rw-r--r-- | tools/clang-format/ClangFormat.cpp | 65 |
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() << " "; + break; + case '\r': + llvm::outs() << " "; + 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; } |