summaryrefslogtreecommitdiff
path: root/tools/clang-format/ClangFormat.cpp
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2013-05-10 11:56:10 +0000
committerAlexander Kornienko <alexfh@google.com>2013-05-10 11:56:10 +0000
commitdd256314cf391063329e504f0ece46ee51bbfa2a (patch)
tree54d11f2326b3c476466868b05738a2c6ff185b8a /tools/clang-format/ClangFormat.cpp
parentacf02715ab1aa1e5a791f20e0d1ca217af256823 (diff)
downloadclang-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.cpp64
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: