Add 'unflatten' to doxygen/dot processing
[senf.git] / Utils / Console / Node.hh
index 137c8b0..b8702be 100644 (file)
 #include <boost/range/iterator_range.hpp>
 #include <boost/typeof/typeof.hpp>
 #include <boost/type_traits/remove_reference.hpp>
+#include <boost/any.hpp>
 #include "../../Utils/Exception.hh"
 #include "../../Utils/mpl.hh"
 #include "../../Utils/Logger/SenfLog.hh"
@@ -222,8 +223,19 @@ namespace console {
     class DirectoryNode;
     class CommandNode;
 
+    /** \brief Get console root node */
     DirectoryNode & root();
 
+    /** \brief Dump console directory structure
+
+        Recursively dumps the console directory structure starting at \a dir. By default, dumps the
+        complete tree beginning at the root node.
+        
+        In contrast to the console 'lr' command, links are dumped by showing the \e absolute path
+        to the target node.
+     */
+    void dump(std::ostream & os, DirectoryNode & dir=root());
+
     /** \brief Config/console node tree base-class
 
         GenericNode is the base class of all node objects. There are two basic node types derived
@@ -277,7 +289,8 @@ namespace console {
 
         bool active() const;            ///< \c true, if node is attached to the root() node
 
-        void help(std::ostream & output) const; /// Write help info to \a output
+        void help(std::ostream & output) const; ///< Write help info to \a output
+        std::string shorthelp() const;  ///< Get short (one-line) documentation
 
         ptr thisptr();                  ///< Get smart pointer to node
         cptr thisptr() const;           ///< Get smart pointer to node (const)
@@ -296,6 +309,9 @@ namespace console {
         bool isLink() const;            ///< \c true, if this is a link node
         bool isCommand() const;         ///< \c true, if this is a command node
 
+        GenericNode const & followLink() const; ///< Follow link if \c this node is a link node
+        GenericNode & followLink();     ///< Follow link if \c this node is a link node
+
     protected:
         GenericNode();
 
@@ -308,8 +324,12 @@ namespace console {
 #endif
         virtual void v_help(std::ostream & output) const = 0;
                                         ///< Provide help information
-                                        /**< This member must be implemented in derived classes
-                                             to provide node specific help information. */
+                                        /**< This member must be implemented in derived classes to
+                                             provide node specific help information. */
+        virtual std::string v_shorthelp() const = 0;
+                                        ///< Provide short documentation
+                                        /**< This member must be implemented in derived classes to
+                                             provide node specific documentation. */
 
     private:
         std::string name_;
@@ -355,6 +375,7 @@ namespace console {
         explicit LinkNode(GenericNode & node);
 
         virtual void v_help(std::ostream &) const;
+        virtual std::string v_shorthelp() const;
 
         GenericNode::ptr node_;
     };
@@ -432,6 +453,7 @@ namespace console {
         static ptr create();            ///< Create node object.
                                         /**< You should normally use either mkdir() or
                                              ScopedDirectory instead of create() */
+        ~DirectoryNode();
 
         ///\}
         ///////////////////////////////////////////////////////////////////////////
@@ -491,7 +513,7 @@ namespace console {
                                         ///< \c true, if there is a child with name \a name
 
         GenericNode & get(std::string const & name) const;
-                                        ///< Get child node
+                                        ///< Get child node automatically dereferencing links
                                         /**< \throws UnknownNodeNameException if a child \a name
                                                  does not exist */
         GenericNode & getLink(std::string const & name) const;
@@ -500,7 +522,7 @@ namespace console {
                                                  does not exist */
 
         DirectoryNode & getDirectory(std::string const & name) const;
-                                        ///< Get directory child node
+                                        ///< Get directory child node (dereferencing links)
                                         /**< Same as operator[]
                                              \throws UnknownNodeNameException if a child \a name
                                                  does not exist.
@@ -508,7 +530,7 @@ namespace console {
                                                  directory node. */
 
         DirectoryNode & operator[](std::string const & name) const;
-                                        ///< Get directory child node
+                                        ///< Get directory child node (dereferencing links)
                                         /**< Same as getDirectory
                                              \throws UnknownNodeNameException if a child \a name
                                                  does not exist.
@@ -516,7 +538,7 @@ namespace console {
                                                  directory node. */
 
         CommandNode & getCommand(std::string const & name) const;
-                                        ///< Get command child node
+                                        ///< Get command child node (dereferencing links)
                                         /**< Same as operator()
                                              \throws UnknownNodeNameException if a child \a name
                                                  does not exist
@@ -524,7 +546,7 @@ namespace console {
                                                  command node. */
 
         CommandNode & operator()(std::string const & name) const;
-                                        ///< Get command child node
+                                        ///< Get command child node (dereferencing links)
                                         /**< Same as getCommand()
                                              \throws UnknownNodeNameException if a child \a name
                                                  does not exist
@@ -533,6 +555,8 @@ namespace console {
 
         DirectoryNode & mkdir(std::string const & name);
                                         ///< Create sub-directory node
+        DirectoryNode & provideDirectory(std::string const & name);
+                                        ///< Return subdirectory, possibly creating it
 
         ChildrenRange children() const; ///< Return iterator range over all children.
                                         /**< The returned range is sorted by child name. */
@@ -549,6 +573,7 @@ namespace console {
         ///////////////////////////////////////////////////////////////////////////
 
         DirectoryNode & doc(std::string const & doc); ///< Set node documentation
+        DirectoryNode & shortdoc(std::string const & doc); ///< Set node short documentation
 
         ptr thisptr();
         cptr thisptr() const;
@@ -559,9 +584,11 @@ namespace console {
     private:
         void add(GenericNode::ptr node);
         virtual void v_help(std::ostream & output) const;
+        virtual std::string v_shorthelp() const;
 
         ChildMap children_;
         std::string doc_;
+        std::string shortdoc_;
 
         friend DirectoryNode & root();
     };
@@ -603,7 +630,15 @@ namespace console {
 
         void execute(std::ostream & output, ParseCommandInfo const & command) const;
                                         ///< Execute the command
-                                        /**< Same as operator()()
+                                        /**< \param[in] output stream where result messages may be
+                                                 written to
+                                             \param[in] arguments command arguments. This is a
+                                                 range of ranges of Token instances. */
+
+        void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command) 
+            const;
+                                        ///< Execute the command
+                                        /**< \param[out] rv command return value
                                              \param[in] output stream where result messages may be
                                                  written to
                                              \param[in] arguments command arguments. This is a
@@ -616,6 +651,8 @@ namespace console {
                                                  written to
                                              \param[in] arguments command arguments. This is a
                                                  range of ranges of Token instances. */
+        void operator()(boost::any & rv, std::ostream & output, ParseCommandInfo const & command)
+            const;
 
         ptr thisptr();
         cptr thisptr() const;
@@ -626,10 +663,10 @@ namespace console {
 #ifndef DOXYGEN
     private:
 #endif
-        virtual void v_execute(std::ostream & output, ParseCommandInfo const & command) const = 0;
+        virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
+            const = 0;
                                         ///< Called to execute the command
-                                        /**< \param[in] output stream where result messages may be
-                                                 written to
+                                        /**< \param[out] rv return value holder
                                              \param[in] arguments command arguments. This is a
                                                  range of ranges of Token instances. */
 
@@ -677,17 +714,21 @@ namespace console {
         cptr thisptr() const;
 
         SimpleCommandNode & doc(std::string const & doc);
+        SimpleCommandNode & shortdoc(std::string const & doc);
 
     protected:
         SimpleCommandNode(Function const & fn);
 
     private:
         virtual void v_help(std::ostream & output) const;
-        virtual void v_execute(std::ostream & output, ParseCommandInfo const & command) const;
+        virtual std::string v_shorthelp() const;
+        virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
+            const;
 
 
         Function fn_;
         std::string doc_;
+        std::string shortdoc_;
     };
 
 #ifndef DOXYGEN
@@ -695,6 +736,9 @@ namespace console {
     SimpleCommandNode & senf_console_add_node(DirectoryNode & node, std::string const & name,
                                               SimpleCommandNode::Function fn, int);
 
+    DirectoryNode & senf_console_add_node(DirectoryNode & node, std::string const & name,
+                                          DirectoryNode & dir, int);
+
 #endif
 
 }}