ClangTidyOptions ClangTidyOptionsProvider::getOptions(llvm::StringRef FileName) { ClangTidyOptions Result; for (const auto &Source : getRawOptions(FileName)) Result = Result.mergeWith(Source.first); return Result; }
llvm::ErrorOr<ClangTidyOptions> FileOptionsProvider::TryReadConfigFile(StringRef Directory) { assert(!Directory.empty()); ClangTidyOptions Options = DefaultOptionsProvider::getOptions(Directory); if (!llvm::sys::fs::is_directory(Directory)) return make_error_code(llvm::errc::not_a_directory); SmallString<128> ConfigFile(Directory); llvm::sys::path::append(ConfigFile, ".clang-tidy"); 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) return make_error_code(llvm::errc::no_such_file_or_directory); llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = llvm::MemoryBuffer::getFile(ConfigFile.c_str()); if (std::error_code EC = Text.getError()) return EC; // Skip empty files, e.g. files opened for writing via shell output // redirection. if ((*Text)->getBuffer().empty()) return make_error_code(llvm::errc::no_such_file_or_directory); if (std::error_code EC = parseConfiguration((*Text)->getBuffer(), Options)) return EC; return Options.mergeWith(OverrideOptions); }
llvm::Optional<ClangTidyOptions> FileOptionsProvider::TryReadConfigFile(StringRef Directory) { assert(!Directory.empty()); if (!llvm::sys::fs::is_directory(Directory)) { llvm::errs() << "Error reading configuration from " << Directory << ": directory doesn't exist.\n"; return llvm::None; } for (const ConfigFileHandler &ConfigHandler : ConfigHandlers) { SmallString<128> ConfigFile(Directory); llvm::sys::path::append(ConfigFile, ConfigHandler.first); 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) continue; llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = llvm::MemoryBuffer::getFile(ConfigFile.c_str()); if (std::error_code EC = Text.getError()) { llvm::errs() << "Can't read " << ConfigFile << ": " << EC.message() << "\n"; continue; } // Skip empty files, e.g. files opened for writing via shell output // redirection. if ((*Text)->getBuffer().empty()) continue; llvm::ErrorOr<ClangTidyOptions> ParsedOptions = ConfigHandler.second((*Text)->getBuffer()); if (!ParsedOptions) { if (ParsedOptions.getError()) llvm::errs() << "Error parsing " << ConfigFile << ": " << ParsedOptions.getError().message() << "\n"; continue; } ClangTidyOptions Defaults = DefaultOptionsProvider::getOptions(Directory); // Only use checks from the config file. Defaults.Checks = None; return Defaults.mergeWith(*ParsedOptions).mergeWith(OverrideOptions); } return llvm::None; }