diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-05-10 11:56:10 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-05-10 11:56:10 +0000 |
commit | dd256314cf391063329e504f0ece46ee51bbfa2a (patch) | |
tree | 54d11f2326b3c476466868b05738a2c6ff185b8a /tools/clang-format/ClangFormat.cpp | |
parent | acf02715ab1aa1e5a791f20e0d1ca217af256823 (diff) | |
download | clang-dd256314cf391063329e504f0ece46ee51bbfa2a.tar.gz clang-dd256314cf391063329e504f0ece46ee51bbfa2a.tar.bz2 clang-dd256314cf391063329e504f0ece46ee51bbfa2a.tar.xz |
Config file support for clang-format, part 2.
Summary:
Adds actual config file reading to the clang-format utility.
Configuration file name is .clang-format. It is looked up for each input file
in its parent directories starting from immediate one. First found .clang-format
file is used. When using standard input, .clang-format is searched starting from
the current directory.
Added -dump-config option to easily create configuration files.
Reviewers: djasper, klimek
Reviewed By: klimek
CC: cfe-commits, jordan_rose, kimgr
Differential Revision: http://llvm-reviews.chandlerc.com/D758
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181589 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/clang-format/ClangFormat.cpp')
-rw-r--r-- | tools/clang-format/ClangFormat.cpp | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp index 57833edf0f..5ae95781fb 100644 --- a/tools/clang-format/ClangFormat.cpp +++ b/tools/clang-format/ClangFormat.cpp @@ -20,6 +20,7 @@ #include "clang/Format/Format.h" #include "clang/Lex/Lexer.h" #include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Signals.h" @@ -36,13 +37,20 @@ Lengths("length", cl::desc("Format a range of this length. " "Can only be used with one input file.")); static cl::opt<std::string> Style( "style", - cl::desc("Coding style, currently supports: LLVM, Google, Chromium, Mozilla."), + cl::desc( + "Coding style, currently supports: LLVM, Google, Chromium, Mozilla. " + "Use '-style file' to load style configuration from .clang-format file " + "located in one of the parent directories of the source file (or " + "current directory for stdin)."), cl::init("LLVM")); static cl::opt<bool> Inplace("i", cl::desc("Inplace edit <file>s, if specified.")); static cl::opt<bool> OutputXML( "output-replacements-xml", cl::desc("Output replacements as XML.")); +static cl::opt<bool> + DumpConfig("dump-config", + cl::desc("Dump configuration options to stdout and exit. Can be used with -style option.")); static cl::list<std::string> FileNames(cl::Positional, cl::desc("[<file> ...]")); @@ -59,18 +67,38 @@ static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source, return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User); } -static FormatStyle getStyle() { - FormatStyle TheStyle = getGoogleStyle(); - if (Style == "LLVM") - TheStyle = getLLVMStyle(); - else if (Style == "Chromium") - TheStyle = getChromiumStyle(); - else if (Style == "Mozilla") - TheStyle = getMozillaStyle(); - else if (Style != "Google") - llvm::errs() << "Unknown style " << Style << ", using Google style.\n"; - - return TheStyle; +FormatStyle getStyle(StringRef StyleName, StringRef FileName) { + if (!StyleName.equals_lower("file")) + return getPredefinedStyle(StyleName); + + SmallString<128> Path(FileName); + llvm::sys::fs::make_absolute(Path); + for (StringRef Directory = llvm::sys::path::parent_path(Path); + !Directory.empty(); + Directory = llvm::sys::path::parent_path(Directory)) { + SmallString<128> ConfigFile(Directory); + llvm::sys::path::append(ConfigFile, ".clang-format"); + DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); + bool IsFile = false; + llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile); + if (IsFile) { + OwningPtr<MemoryBuffer> Text; + if (error_code ec = MemoryBuffer::getFile(ConfigFile, Text)) { + llvm::errs() << ec.message() << "\n"; + continue; + } + FormatStyle Style; + if (error_code ec = parseConfiguration(Text->getBuffer(), &Style)) { + llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message() + << "\n"; + continue; + } + DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n"); + return Style; + } + } + llvm::errs() << "Can't find usable .clang-format, using LLVM style\n"; + return getLLVMStyle(); } // Returns true on error. @@ -118,7 +146,8 @@ static bool format(std::string FileName) { } Ranges.push_back(CharSourceRange::getCharRange(Start, End)); } - tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges); + tooling::Replacements Replaces = + reformat(getStyle(Style, FileName), Lex, Sources, Ranges); if (OutputXML) { llvm::outs() << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n"; @@ -171,6 +200,13 @@ int main(int argc, const char **argv) { if (Help) cl::PrintHelpMessage(); + if (DumpConfig) { + std::string Config = clang::format::configurationAsText( + clang::format::getStyle(Style, FileNames.empty() ? "-" : FileNames[0])); + llvm::outs() << Config << "\n"; + return 0; + } + bool Error = false; switch (FileNames.size()) { case 0: |