Hi djasper,

http://reviews.llvm.org/D5821

Files:
  clang-tidy/ClangTidyOptions.cpp
  clang-tidy/ClangTidyOptions.h
Index: clang-tidy/ClangTidyOptions.cpp
===================================================================
--- clang-tidy/ClangTidyOptions.cpp
+++ clang-tidy/ClangTidyOptions.cpp
@@ -139,10 +139,19 @@
     const ClangTidyOptions &OverrideOptions)
     : DefaultOptionsProvider(GlobalOptions, DefaultOptions),
       OverrideOptions(OverrideOptions) {
+  ConfigHandlers.push_back(std::make_pair(".clang-tidy", parseConfiguration));
   CachedOptions[""] = DefaultOptions.mergeWith(OverrideOptions);
 }
 
-static const char ConfigFileName[] = ".clang-tidy";
+FileOptionsProvider::FileOptionsProvider(
+    const ClangTidyGlobalOptions &GlobalOptions,
+    const ClangTidyOptions &DefaultOptions,
+    const ClangTidyOptions &OverrideOptions,
+    const FileOptionsProvider::ConfigFileHandlers &ConfigHandlers)
+    : DefaultOptionsProvider(GlobalOptions, DefaultOptions),
+      OverrideOptions(OverrideOptions), ConfigHandlers(ConfigHandlers) {
+  CachedOptions[""] = DefaultOptions.mergeWith(OverrideOptions);
+}
 
 // FIXME: This method has some common logic with clang::format::getStyle().
 // Consider pulling out common bits to a findParentFileWithName function or
@@ -170,8 +179,17 @@
     if (Iter != CachedOptions.end())
       Result = Iter->second;
 
-    if (!Result)
-      Result = TryReadConfigFile(CurrentPath);
+    if (!Result) {
+      for (const auto& Handler : ConfigHandlers) {
+        Result = TryReadConfigFile(CurrentPath, Handler);
+        if (Result)
+          break;
+        if (Result.getError() != llvm::errc::no_such_file_or_directory) {
+          llvm::errs() << "Error reading " << Handler.first << " from " << Path
+                       << ": " << Result.getError().message() << "\n";
+        }
+      }
+    }
 
     if (Result) {
       // Store cached value for all intermediate directories.
@@ -183,22 +201,18 @@
       }
       return CachedOptions.GetOrCreateValue(Path, *Result).getValue();
     }
-    if (Result.getError() != llvm::errc::no_such_file_or_directory) {
-      llvm::errs() << "Error reading " << ConfigFileName << " from " << Path
-                   << ": " << Result.getError().message() << "\n";
-    }
   }
 }
 
-llvm::ErrorOr<ClangTidyOptions>
-FileOptionsProvider::TryReadConfigFile(StringRef Directory) {
+llvm::ErrorOr<ClangTidyOptions> FileOptionsProvider::TryReadConfigFile(
+    StringRef Directory, const FileOptionsProvider::ConfigHandler &Handler) {
   assert(!Directory.empty());
 
   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");
+  llvm::sys::path::append(ConfigFile, Handler.first);
   DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
 
   bool IsFile = false;
@@ -218,7 +232,7 @@
   if ((*Text)->getBuffer().empty())
     return make_error_code(llvm::errc::no_such_file_or_directory);
   llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
-      parseConfiguration((*Text)->getBuffer());
+      Handler.second((*Text)->getBuffer());
   if (ParsedOptions) {
     ClangTidyOptions Defaults = DefaultOptionsProvider::getOptions(Directory);
     // Only use checks from the config file.
Index: clang-tidy/ClangTidyOptions.h
===================================================================
--- clang-tidy/ClangTidyOptions.h
+++ clang-tidy/ClangTidyOptions.h
@@ -14,6 +14,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorOr.h"
+#include <functional>
 #include <map>
 #include <string>
 #include <system_error>
@@ -114,32 +115,60 @@
 };
 
 /// \brief Implementation of the \c ClangTidyOptionsProvider interface, which
-/// tries to find a .clang-tidy file in the closest parent directory of each
-/// file.
+/// tries to find a configuration file in the closest parent directory of each
+/// source file. By default, files named ".clang-tidy" will be considered, and
+/// will be parsed using \c clang::tidy::parseConfiguration, but a custom set of
+/// configuration file names and parsing functions can be specified.
 class FileOptionsProvider : public DefaultOptionsProvider {
 public:
+  typedef std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions>(
+                                     llvm::StringRef)>> ConfigHandler;
+  typedef std::vector<ConfigHandler> ConfigFileHandlers;
+
   /// \brief Initializes the \c FileOptionsProvider instance.
   ///
   /// \param GlobalOptions are just stored and returned to the caller of
   /// \c getGlobalOptions.
   ///
   /// \param DefaultOptions are used for all settings not specified in a
-  /// .clang-tidy file.
+  /// configuration file.
   ///
   /// If any of the \param OverrideOptions fields are set, they will override
   /// whatever options are read from the configuration file.
   FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions,
                       const ClangTidyOptions &DefaultOptions,
                       const ClangTidyOptions &OverrideOptions);
+
+  /// \brief Initializes the \c FileOptionsProvider instance with a custom set
+  /// of configuration file handlers.
+  ///
+  /// \param GlobalOptions are just stored and returned to the caller of
+  /// \c getGlobalOptions.
+  ///
+  /// \param DefaultOptions are used for all settings not specified in a
+  /// configuration file.
+  ///
+  /// If any of the \param OverrideOptions fields are set, they will override
+  /// whatever options are read from the configuration file.
+  ///
+  /// \param ConfigHandlers specifies a custom set of configuration file
+  /// handlers. Each handler is a pair of configuration file name and a function
+  /// that can parse configuration from this file type.
+  FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions,
+                      const ClangTidyOptions &DefaultOptions,
+                      const ClangTidyOptions &OverrideOptions,
+                      const ConfigFileHandlers &ConfigHandlers);
   const ClangTidyOptions &getOptions(llvm::StringRef FileName) override;
 
 private:
   /// \brief Try to read configuration file from \p Directory. If \p Directory
   /// is empty, use the default value.
-  llvm::ErrorOr<ClangTidyOptions> TryReadConfigFile(llvm::StringRef Directory);
+  llvm::ErrorOr<ClangTidyOptions>
+  TryReadConfigFile(llvm::StringRef Directory, const ConfigHandler& Handler);
 
   llvm::StringMap<ClangTidyOptions> CachedOptions;
   ClangTidyOptions OverrideOptions;
+  ConfigFileHandlers ConfigHandlers;
 };
 
 /// \brief Parses LineFilter from JSON and stores it to the \p Options.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to