Console: Documentation of the configuration support
[senf.git] / Console / Config.hh
index ce74973..f5804b7 100644 (file)
 #include "Executor.hh"
 
 //#include "Config.mpp"
+#include "Config.ih"
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
 namespace console {
 
-    /** \brief
+    /** \brief Combine multiple configuration sources
+
+        A ConfigBundle combines several sources and parses them together, in the order they were
+        added. Parse restrictions are applied uniformly to all sources.
+        \code
+        // Add three configuration sources: A system configuration file, a user configuration file
+        // and command line options
+        senf::console::ConfigBundle conf;
+        conf.add( senf::console::FileConfig("/etc/some.conf") );
+        conf.add( senf::console::FileConfig("local.conf") );
+        conf.add( senf::console::OptionsConfig(senf::Daemon::instance().argc(),
+                                               senf::Daemon::instance().argv()) );
+
+        conf.parse();
+        \endcode
+
+        This bundle may also be passed to other code which may use restricted parsing to parse
+        partial information from all configuration sources.
+        
+        \ingroup console_access
       */
-    class ConfigFile
-        : boost::noncopyable
+    class ConfigBundle
     {
     public:
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
 
-        explicit ConfigFile(std::string const & filename);
+        ConfigBundle();
+        ConfigBundle(DirectoryNode & root); ///< Set custom root node
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
-        void parse();
-        void parse(DirectoryNode & restrict);
+        template <class Source>
+        Source & add(boost::intrusive_ptr<Source> source);
+                                        ///< Add configuration source
+       
+        void parse();                   ///< Parse config file
+                                        /**< All nodes already parsed are skipped */
+        void parse(DirectoryNode & restrict); ///< Parse config file under \a restrict
+                                        /**< Only nodes which are children of \a restrict are
+                                             parsed.  */
+
+        bool complete() const;          ///< \c true, if all nodes have been parsed
+        bool parsed(GenericNode & node) const; ///< \c true. if \a node has been parsed
+        void reset();                   ///< Reset node parse info state
+                                        /**< After a call to reset(), all information about already
+                                             parsed nodes is cleared. Calling parse() will parse the
+                                             complete config file again. */
 
     protected:
 
     private:
-        void policyCallback(DirectoryNode & dir, std::string const & item);
+        void parseInternal();
 
-        typedef std::vector<DirectoryNode::weak_ptr> ParsedNodes;
+        typedef std::vector<detail::ConfigSource::ptr> Sources;
 
-        std::string filename_;
-        CommandParser parser_;
-        Executor executor_;
-
-        DirectoryNode::ptr restrict_;
-        ParsedNodes parsedNodes_;
+        Sources sources_;
+        detail::RestrictedExecutor executor_;
     };
 
-    void readConfig(std::string const & filename);
+namespace detail {
+    // hrmpf ... Can't place this into Config.ih ...
+
+    /** \brief Internal: Provide ConfigBundle facade for a single-source config.
+
+        The BundleMixin is used to define supplementary configuration objects for one specific
+        configuration source. A BundleMixin is \e not a ConfigBundle since it has no public \c add()
+        member.
+     */
+    class BundleMixin
+    {
+    public:
+        BundleMixin();
+        BundleMixin(DirectoryNode & root);
+
+        void parse();                   ///< Parse config file
+                                        /**< All nodes already parsed are skipped */
+        void parse(DirectoryNode & restrict); ///< Parse config file under \a restrict
+                                        /**< Only nodes which are children of \a restrict are
+                                             parsed.  */
+
+        bool complete() const;          ///< \c true, if all nodes have been parsed
+        bool parsed(GenericNode & node) const; ///< \c true. if \a node has been parsed
+        void reset();                   ///< Reset node parse info state
+                                        /**< After a call to reset(), all information about already
+                                             parsed nodes is cleared. Calling parse() will parse the
+                                             complete config file again. */
+
+    protected:
+        template <class Source>
+        Source & add(boost::intrusive_ptr<Source> source);
+        
+    private:
+        ConfigBundle bundle_;
+    };
 
-}}
+}}}
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "Config.cci"
 //#include "Config.ct"
-//#include "Config.cti"
+#include "Config.cti"
 #endif
 
 \f