LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard =
FormatStyle::LS_Cpp11);
+/// \brief Description to be used for help text for a llvm::cl option for
+/// specifying format style. The description is closely related to the operation
+/// of getStyle().
+extern const char *StyleOptionHelpDescription;
+
+/// \brief Construct a FormatStyle based on \c StyleName.
+///
+/// \c StyleName can take several forms:
+/// \li "{<key>: <value>, ...}" - Set specic style parameters.
+/// \li "<style name>" - One of the style names supported by
+/// getPredefinedStyle().
+/// \li "file" - Load style configuration from a file called '.clang-format'
+/// located in one of the parent directories of \c FileName or the current
+/// directory if \c FileName is empty.
+///
+/// \param[in] StyleName Style name to interpret according to the description
+/// above.
+/// \param[in] FileName Path to start search for .clang-format if \c StyleName
+/// == "file".
+///
+/// \returns FormatStyle as specified by \c StyleName. If no style could be
+/// determined, the default is LLVM Style (see getLLVMStyle()).
+FormatStyle getStyle(StringRef StyleName, StringRef FileName);
+
} // end namespace format
} // end namespace clang
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/Path.h"
#include <queue>
#include <string>
return LangOpts;
}
+const char *StyleOptionHelpDescription =
+ "Coding style, currently supports:\n"
+ " LLVM, Google, Chromium, Mozilla, WebKit.\n"
+ "Use -style=file to load style configuration from\n"
+ ".clang-format file located in one of the parent\n"
+ "directories of the source file (or current\n"
+ "directory for stdin).\n"
+ "Use -style=\"{key: value, ...}\" to set specific\n"
+ "parameters, e.g.:\n"
+ " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
+
+FormatStyle getStyle(StringRef StyleName, StringRef FileName) {
+ // Fallback style in case the rest of this function can't determine a style.
+ StringRef FallbackStyle = "LLVM";
+ FormatStyle Style;
+ getPredefinedStyle(FallbackStyle, &Style);
+
+ if (StyleName.startswith("{")) {
+ // Parse YAML/JSON style from the command line.
+ if (llvm::error_code ec = parseConfiguration(StyleName, &Style)) {
+ llvm::errs() << "Error parsing -style: " << ec.message()
+ << ", using " << FallbackStyle << " style\n";
+ }
+ return Style;
+ }
+
+ if (!StyleName.equals_lower("file")) {
+ if (!getPredefinedStyle(StyleName, &Style))
+ llvm::errs() << "Invalid value for -style, using " << FallbackStyle
+ << " style\n";
+ return Style;
+ }
+
+ SmallString<128> Path(FileName);
+ llvm::sys::fs::make_absolute(Path);
+ for (StringRef Directory = Path;
+ !Directory.empty();
+ Directory = llvm::sys::path::parent_path(Directory)) {
+ if (!llvm::sys::fs::is_directory(Directory))
+ continue;
+ SmallString<128> ConfigFile(Directory);
+
+ llvm::sys::path::append(ConfigFile, ".clang-format");
+ DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
+ bool IsFile = false;
+ // Ignore errors from is_regular_file: we only need to know if we can read
+ // the file or not.
+ llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
+
+ if (!IsFile) {
+ // Try _clang-format too, since dotfiles are not commonly used on Windows.
+ ConfigFile = Directory;
+ llvm::sys::path::append(ConfigFile, "_clang-format");
+ DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
+ llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
+ }
+
+ if (IsFile) {
+ OwningPtr<llvm::MemoryBuffer> Text;
+ if (llvm::error_code ec = llvm::MemoryBuffer::getFile(ConfigFile, Text)) {
+ llvm::errs() << ec.message() << "\n";
+ continue;
+ }
+ if (llvm::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 " << FallbackStyle
+ << " style\n";
+ return Style;
+}
+
} // namespace format
} // namespace clang
cl::cat(ClangFormatCategory));
static cl::opt<std::string>
Style("style",
- cl::desc("Coding style, currently supports:\n"
- " LLVM, Google, Chromium, Mozilla, WebKit.\n"
- "Use -style=file to load style configuration from\n"
- ".clang-format file located in one of the parent\n"
- "directories of the source file (or current\n"
- "directory for stdin).\n"
- "Use -style=\"{key: value, ...}\" to set specific\n"
- "parameters, e.g.:\n"
- " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""),
+ cl::desc(clang::format::StyleOptionHelpDescription),
cl::init("file"), cl::cat(ClangFormatCategory));
static cl::opt<std::string>
return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
}
-FormatStyle getStyle(StringRef StyleName, StringRef FileName) {
- FormatStyle Style;
- getPredefinedStyle(FallbackStyle, &Style);
-
- if (StyleName.startswith("{")) {
- // Parse YAML/JSON style from the command line.
- if (error_code ec = parseConfiguration(StyleName, &Style)) {
- llvm::errs() << "Error parsing -style: " << ec.message()
- << ", using " << FallbackStyle << " style\n";
- }
- return Style;
- }
-
- if (!StyleName.equals_lower("file")) {
- if (!getPredefinedStyle(StyleName, &Style))
- llvm::errs() << "Invalid value for -style, using " << FallbackStyle
- << " style\n";
- return Style;
- }
-
- if (FileName == "-")
- FileName = AssumeFilename;
- SmallString<128> Path(FileName);
- llvm::sys::fs::make_absolute(Path);
- for (StringRef Directory = Path;
- !Directory.empty();
- Directory = llvm::sys::path::parent_path(Directory)) {
- if (!llvm::sys::fs::is_directory(Directory))
- continue;
- SmallString<128> ConfigFile(Directory);
-
- llvm::sys::path::append(ConfigFile, ".clang-format");
- DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
- bool IsFile = false;
- // Ignore errors from is_regular_file: we only need to know if we can read
- // the file or not.
- llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
-
- if (!IsFile) {
- // Try _clang-format too, since dotfiles are not commonly used on Windows.
- ConfigFile = Directory;
- llvm::sys::path::append(ConfigFile, "_clang-format");
- DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
- 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;
- }
- 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 " << FallbackStyle
- << " style\n";
- return Style;
-}
-
// Parses <start line>:<end line> input to a pair of line numbers.
// Returns true on error.
static bool parseLineRange(StringRef Input, unsigned &FromLine,
if (fillRanges(Sources, ID, Code.get(), Ranges))
return true;
- FormatStyle FormatStyle = getStyle(Style, FileName);
+ FormatStyle FormatStyle =
+ getStyle(Style, (FileName == "-") ? AssumeFilename : FileName);
Lexer Lex(ID, Sources.getBuffer(ID), Sources,
getFormattingLangOpts(FormatStyle.Standard));
tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
cl::PrintHelpMessage();
if (DumpConfig) {
- std::string Config = clang::format::configurationAsText(
- clang::format::getStyle(Style, FileNames.empty() ? "-" : FileNames[0]));
+ std::string Config =
+ clang::format::configurationAsText(clang::format::getStyle(
+ Style, FileNames.empty() ? AssumeFilename : FileNames[0]));
llvm::outs() << Config << "\n";
return 0;
}