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);
}
Example #3
0
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;
}