Console: More OverloadedCommandNode documentation and testing
[senf.git] / Console / Node.hh
index cadc057..961a1b8 100644 (file)
 
     \section console_tree The tree
 
+    We will start by giving a more complete example. This example contains most of the stuff needed
+    for using the console/config library.
+
+    \code
+    // Define callback function.
+    void mycommand(std::ostream & os, senf::console::Arguments const & args)
+    {
+        // ...
+        os << "!! Important message ...\n";
+    }
+
+    class SomeClass
+    {
+    public:
+        // Declare a directory node (proxy) for use by this class. This must be public so we can add
+        // it to the node tree later.
+        senf::console::ScopedDirectory<SomeClass> dir;
+
+        SomeClass() : dir(this) 
+        {
+            // You may document the directory here or later when adding it to the tree
+            dir.doc("Manager for something");
+
+            // Add a member function (the pointer-to-member is automatically bound to this instance)
+            dir.add("member", &SomeClass::member)
+                .doc("Do the member operation");
+        }
+
+        void member(std::ostream & os, senf::console::Arguments const & args)
+        {
+            // ...
+        }
+    };
+
+    int main(int, char**)
+    {
+        // Provide global documentation
+        senf::console::root()
+            .doc("This is someServer server");
+
+        // Add a new directory to the root and document it. All the mutators return the node object
+        // itself so operations can be chained.
+        senf::console::DirectoryNode & mydir (
+                .mkdir("myserver")
+                .doc("My server specific directory"));
+
+        // Add a command to that directory
+        mydir.add("mycommand", &mycommand)
+            .doc("mycommand <foo> [<bar>]\n\n"
+                 "If <bar> is given, flurgle the <foo>, otherwise burgle it");
+
+        // Create a SomeClass instance and add it's directory.
+        SomeClass someClass;
+        mydir.add("someClass", someClass.dir);
+
+        // Start the interactive console server
+        senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u))
+            .name("someServer");
+    }
+    \endcode
+
     \subsection console_nodes Node types
 
     The console/config library tree consists of two basic node types:
 
     Most objects will register several commands. So it makes sense for these objects to manage their
     own directory. Since directories are however allocated on the heap, they cannot be directly
-    added to a class. To facilitate this usage, the senf::console::ObjectDirectory is used. This
+    added to a class. To facilitate this usage, the senf::console::ScopedDirectory is used. This
     class provides a senf::console::DirectoryNode facade. Internally, it automatically creates a
     senf::console::DirectoryNode to which all calls are forwarded.
 
-    The senf::console::ObjectDirectory member should be declared public. This allows the user of the
+    The senf::console::ScopedDirectory member should be declared public. This allows the user of the
     class to add the node to the tree.
-
-    \section console_long_example Example
-
-    The following is a more complete example. It uses most of the features you will be using from
-    the console library.
-
-    \code
-    // Define callback function.
-    void mycommand(std::ostream & os, senf::console::Arguments const & args)
-    {
-        // ...
-        os << "!! Important message ...\n";
-    }
-
-    class SomeClass
-    {
-    public:
-        // Declare a directory node (proxy) for use by this class. This must be public so we can add
-        // it to the node tree later.
-        senf::console::ObjectDirectory<SomeClass> dir;
-
-        SomeClass() : dir(this) 
-        {
-            // You may document the directory here or later when adding it to the tree
-            dir.doc("Manager for something");
-
-            // Add a member function (the pointer-to-member is automatically bound to this instance)
-            dir.add("member", &SomeClass::member)
-                .doc("Do the member operation");
-        }
-
-        void member(std::ostream & os, senf::console::Arguments const & args)
-        {
-            // ...
-        }
-    };
-
-    int main(int, char**)
-    {
-        // Provide global documentation
-        senf::console::root()
-            .doc("This is someServer server");
-
-        // Add a new directory to the root and document it. All the mutators return the node object
-        // itself so operations can be chained.
-        senf::console::DirectoryNode & mydir (
-                .mkdir("myserver")
-                .doc("My server specific directory"));
-
-        // Add a command to that directory
-        mydir.add("mycommand", &mycommand)
-            .doc("mycommand <foo> [<bar>]\n\n"
-                 "If <bar> is given, flurgle the <foo>, otherwise burgle it");
-
-        // Create a SomeClass instance and add it's directory.
-        SomeClass someClass;
-        mydir.add("someClass", someClass.dir);
-
-        // Start the interactive console server
-        senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u))
-            .name("someServer");
-    }
-    \endcode
  */
 
 #ifndef HH_Node_
@@ -326,8 +324,8 @@ namespace console {
         mkdir() or add(). Special add() members however allow externally allocated node objects.
 
         Nodes may be added to the tree only once, otherwise chaos will ensue. Since nodes are always
-        managed dynamically, there is a special ObjectDirectory proxy template which provides a
-        DirectoryNode facade. ObjectDirectory is used if a class wants to manage it's own directory
+        managed dynamically, there is a special ScopedDirectory proxy template which provides a
+        DirectoryNode facade. ScopedDirectory is used if a class wants to manage it's own directory
         as a data member.
 
         Every node is assigned a (new) name when it is added to a directory. If the directory
@@ -359,7 +357,7 @@ namespace console {
 
         static ptr create();            ///< Create node object.
                                         /**< You should normally use either mkdir() or
-                                             ObjectDirectory instead of create() */
+                                             ScopedDirectory instead of create() */
 
         ///\}
         ///////////////////////////////////////////////////////////////////////////
@@ -481,6 +479,13 @@ namespace console {
     {};
 #endif
 
+    struct SyntaxErrorException : public senf::Exception
+    {
+        explicit SyntaxErrorException(std::string const & msg = "");
+
+        virtual char const * what() const throw();
+    };
+
     /** \brief Config/console tree command node
 
         The CommandNode is the base-class for the tree leaf nodes. Concrete command node
@@ -506,8 +511,8 @@ namespace console {
 
         ///////////////////////////////////////////////////////////////////////////
 
-        virtual void operator()(std::ostream & output, Arguments const & arguments) = 0;
-                                        ///< Called to execute the command
+        void operator()(std::ostream & output, Arguments const & arguments) const;
+                                        ///< Execute the command
                                         /**< \param[in] output stream where result messages may be
                                                  written to
                                              \param[in] arguments command arguments. This is a
@@ -519,6 +524,16 @@ namespace console {
     protected:
         CommandNode();
 
+#ifndef DOXYGEN
+    private:
+#endif
+        virtual void v_execute(std::ostream & output, Arguments const & arguments) const = 0;
+                                        ///< Called to execute the command
+                                        /**< \param[in] output stream where result messages may be
+                                                 written to
+                                             \param[in] arguments command arguments. This is a
+                                                 range of ranges of ArgumentToken instances. */
+
     private:
     };
 
@@ -553,8 +568,6 @@ namespace console {
         ///\}
         ///////////////////////////////////////////////////////////////////////////
 
-        virtual void operator()(std::ostream & output, Arguments const & arguments);
-
         ptr thisptr();
         cptr thisptr() const;
 
@@ -565,6 +578,8 @@ namespace console {
 
     private:
         virtual void v_help(std::ostream & output) const;
+        virtual void v_execute(std::ostream & output, Arguments const & arguments) const;
+        
 
         Function fn_;
         std::string doc_;