core, main: make missing config file section behavior configurable

refs: #1499

Change-Id: I01cce3c73214f592d8c342d8aeda4fbafc6804b8
diff --git a/core/config-file.cpp b/core/config-file.cpp
index 436c480..5887c2b 100644
--- a/core/config-file.cpp
+++ b/core/config-file.cpp
@@ -32,7 +32,30 @@
 
 NFD_LOG_INIT("ConfigFile");
 
-ConfigFile::ConfigFile()
+void
+ConfigFile::throwErrorOnUnknownSection(const std::string& filename,
+                                       const std::string& sectionName,
+                                       const ConfigSection& section,
+                                       bool isDryRun)
+{
+  std::string msg = "Error processing configuration file ";
+  msg += filename;
+  msg += ": no module subscribed for section \"" + sectionName + "\"";
+
+  throw ConfigFile::Error(msg);
+}
+
+void
+ConfigFile::ignoreUnknownSection(const std::string& filename,
+                                 const std::string& sectionName,
+                                 const ConfigSection& section,
+                                 bool isDryRun)
+{
+  // do nothing
+}
+
+ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
+  : m_unknownSectionCallback(unknownSectionCallback)
 {
 }
 
@@ -93,8 +116,7 @@
 
   if (m_global.begin() == m_global.end())
     {
-      std::string msg = "Error processing configuration file";
-      msg += ": ";
+      std::string msg = "Error processing configuration file: ";
       msg += filename;
       msg += " no data";
       throw Error(msg);
@@ -113,11 +135,7 @@
         }
       else
         {
-          std::string msg = "Error processing configuration file";
-          msg += " ";
-          msg += filename;
-          msg += " no module subscribed for section: " + sectionName;
-          throw Error(msg);
+          m_unknownSectionCallback(filename, sectionName, section, isDryRun);
         }
     }
 }
diff --git a/core/config-file.hpp b/core/config-file.hpp
index f3128c4..b7dd886 100644
--- a/core/config-file.hpp
+++ b/core/config-file.hpp
@@ -34,7 +34,15 @@
 typedef boost::property_tree::ptree ConfigSection;
 
 /// \brief callback for config file sections
-typedef function<void(const ConfigSection&, bool, const std::string&)> ConfigSectionHandler;
+typedef function<void(const ConfigSection& /*section*/,
+                      bool /*isDryRun*/,
+                      const std::string& /*filename*/)> ConfigSectionHandler;
+
+/// \brief callback for config file sections without a subscribed handler
+typedef function<void(const std::string& /*filename*/,
+                      const std::string& /*sectionName*/,
+                      const ConfigSection& /*section*/,
+                      bool /*isDryRun*/)> UnknownConfigSectionHandler;
 
 class ConfigFile : noncopyable
 {
@@ -51,7 +59,19 @@
     }
   };
 
-  ConfigFile();
+  ConfigFile(UnknownConfigSectionHandler unknownSectionCallback = throwErrorOnUnknownSection);
+
+  static void
+  throwErrorOnUnknownSection(const std::string& filename,
+                             const std::string& sectionName,
+                             const ConfigSection& section,
+                             bool isDryRun);
+
+  static void
+  ignoreUnknownSection(const std::string& filename,
+                       const std::string& sectionName,
+                       const ConfigSection& section,
+                       bool isDryRun);
 
   /// \brief setup notification of configuration file sections
   void
@@ -93,6 +113,7 @@
   process(bool isDryRun, const std::string& filename);
 
 private:
+  UnknownConfigSectionHandler m_unknownSectionCallback;
 
   typedef std::map<std::string, ConfigSectionHandler> SubscriptionTable;