aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/Format.cpp
diff options
context:
space:
mode:
authorZhao Wei Liew <zhaoweiliew@gmail.com>2022-01-03 11:37:20 +0100
committerMarek Kurdej <marek.kurdej+llvm.org@gmail.com>2022-01-03 11:43:25 +0100
commitb9e173fcd46b336b5589f577a74de9472d4deae3 (patch)
tree530323c4c70fada23e5dde1d7ba3408c2339018c /clang/lib/Format/Format.cpp
parent0090cd4e7a24bedeb24dfe5b3b55167ad74e231e (diff)
downloadllvm-b9e173fcd46b336b5589f577a74de9472d4deae3.zip
llvm-b9e173fcd46b336b5589f577a74de9472d4deae3.tar.gz
llvm-b9e173fcd46b336b5589f577a74de9472d4deae3.tar.bz2
[clang-format] Add option to explicitly specify a config file
This diff extends the -style=file option to allow a config file to be specified explicitly. This is useful (for instance) when adding IDE commands to reformat code to a personal style. Usage: `clang-format -style=file:<path/to/config/file> ...` Reviewed By: HazardyKnusperkeks, curdeius, MyDeveloperDay, zwliew Differential Revision: https://reviews.llvm.org/D72326
Diffstat (limited to 'clang/lib/Format/Format.cpp')
-rw-r--r--clang/lib/Format/Format.cpp47
1 files changed, 40 insertions, 7 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index f3c337a..0ae9fa60 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -3181,6 +3181,8 @@ const char *StyleOptionHelpDescription =
".clang-format file located in one of the parent\n"
"directories of the source file (or current\n"
"directory for stdin).\n"
+ "Use -style=file:<format_file_path> to explicitly specify"
+ "the configuration file.\n"
"Use -style=\"{key: value, ...}\" to set specific\n"
"parameters, e.g.:\n"
" -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
@@ -3233,6 +3235,18 @@ const char *DefaultFormatStyle = "file";
const char *DefaultFallbackStyle = "LLVM";
+llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
+ FormatStyle *Style, bool AllowUnknownOptions) {
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+ FS->getBufferForFile(ConfigFile.str());
+ if (auto EC = Text.getError())
+ return EC;
+ if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions))
+ return EC;
+ return Text;
+}
+
llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
StringRef FallbackStyleName,
StringRef Code, llvm::vfs::FileSystem *FS,
@@ -3263,6 +3277,28 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
return Style;
}
+ // User provided clang-format file using -style=file:path/to/format/file.
+ if (!Style.InheritsParentConfig &&
+ StyleName.startswith_insensitive("file:")) {
+ auto ConfigFile = StyleName.substr(5);
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+ loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions);
+ if (auto EC = Text.getError())
+ return make_string_error("Error reading " + ConfigFile + ": " +
+ EC.message());
+
+ LLVM_DEBUG(llvm::dbgs()
+ << "Using configuration file " << ConfigFile << "\n");
+
+ if (!Style.InheritsParentConfig)
+ return Style;
+
+ // Search for parent configs starting from the parent directory of
+ // ConfigFile.
+ FileName = ConfigFile;
+ ChildFormatTextToApply.emplace_back(std::move(*Text));
+ }
+
// If the style inherits the parent configuration it is a command line
// configuration, which wants to inherit, so we have to skip the check of the
// StyleName.
@@ -3318,19 +3354,16 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
if (Status &&
(Status->getType() == llvm::sys::fs::file_type::regular_file)) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
- FS->getBufferForFile(ConfigFile.str());
- if (std::error_code EC = Text.getError())
- return make_string_error(EC.message());
- if (std::error_code ec =
- parseConfiguration(*Text.get(), &Style, AllowUnknownOptions)) {
- if (ec == ParseError::Unsuitable) {
+ loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions);
+ if (auto EC = Text.getError()) {
+ if (EC == ParseError::Unsuitable) {
if (!UnsuitableConfigFiles.empty())
UnsuitableConfigFiles.append(", ");
UnsuitableConfigFiles.append(ConfigFile);
continue;
}
return make_string_error("Error reading " + ConfigFile + ": " +
- ec.message());
+ EC.message());
}
LLVM_DEBUG(llvm::dbgs()
<< "Using configuration file " << ConfigFile << "\n");