Console: More OverloadedCommandNode documentation and testing
g0dil [Wed, 2 Apr 2008 08:02:44 +0000 (08:02 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@773 270642c3-0616-0410-b53a-bc976706d245

Console/OverloadedCommand.cci
Console/OverloadedCommand.cti [new file with mode: 0644]
Console/OverloadedCommand.hh
Console/OverloadedCommand.test.cc
senf.dict

index 21add3b..ea87c2d 100644 (file)
@@ -65,11 +65,6 @@ prefix_ senf::console::OverloadedCommandNode::ptr senf::console::OverloadedComma
     return ptr(new OverloadedCommandNode());
 }
 
-prefix_ void senf::console::OverloadedCommandNode::add(CommandOverload::ptr overload)
-{
-    overloads_.push_back(overload);
-}
-
 prefix_ senf::console::OverloadedCommandNode::ptr senf::console::OverloadedCommandNode::thisptr()
 {
     return boost::static_pointer_cast<OverloadedCommandNode>(shared_from_this());
diff --git a/Console/OverloadedCommand.cti b/Console/OverloadedCommand.cti
new file mode 100644 (file)
index 0000000..d4d6df8
--- /dev/null
@@ -0,0 +1,56 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief OverloadedCommand inline template implementation */
+
+//#include "OverloadedCommand.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::OverloadedCommandNode
+
+template <class Command>
+prefix_ Command &
+senf::console::OverloadedCommandNode::add(boost::intrusive_ptr<Command> overload)
+{
+    overloads_.push_back(overload);
+    return *overload;
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index a255eb5..e1481e5 100644 (file)
@@ -39,7 +39,10 @@ namespace console {
 
     class OverloadedCommandNode;
 
-    /** \brief
+    /** \brief Base class for command overload of OverloadedCommandNode
+
+        This class is the base class of the commands which may be added to an
+        OverloadedCommandNode.
       */
     class CommandOverload
         : public senf::intrusive_refcount
@@ -56,9 +59,14 @@ namespace console {
         virtual ~CommandOverload();
 
         void operator()(std::ostream & os, Arguments const & arguments);
-        void help(std::ostream & os);
+                                        ///< Call the overload
+                                        /**< If the \a arguments are not acceptable for this
+                                             overload, a SyntaxErrorException must be thrown. */
+        void help(std::ostream & os);   ///< Provide help for this specific overload
 
-        OverloadedCommandNode & node();
+        OverloadedCommandNode & node(); ///< Access owning node
+                                        /**< \pre The command \e must have been added to an
+                                             OverloadedCommandNode. */
 
     protected:
         CommandOverload();
@@ -77,9 +85,22 @@ namespace console {
 
     /** \brief Command node which allows multiple registered callbacks
 
-        OverloadedCommand is like SimpleCommand but allows to register multiple commands to a single
-        node. This works by calling each command in the list consecutively until no 'SyntaxError'
-        exception is thrown. 
+        OverloadedCommandNode is like SimpleCommandNode but allows to register multiple commands to
+        a single node. This works by calling each command in the list consecutively until no
+        'SyntaxErrorException' exception is thrown.
+
+        This works by first adding an OverloadedCommandNode to the directory in question and then
+        adding commands to that node. Commands are derived from CommandOverload. 
+        \code
+        senf::console::DirectoryNode & dir (...);
+        senf::console::OverloadedCommandNode & cmd (
+            dir.add("cmd", senf::console::OverloadedCommandNode::create()) );
+        cmd.add(senf::console::SimpleCommandOverload::create(&callback));
+        cmd.add(senf::console::SimpleCommandOverload::create(&anotherCallback));
+        \endcode
+
+        However, this facility is mostly used not directly but indirectly (and automatically) when
+        adding argument parsing callbacks.
 
         \warning For this to work, the commands <b>must</b> do all syntax checking before doing any
             operation
@@ -105,13 +126,15 @@ namespace console {
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
-
-        void add(CommandOverload::ptr overload);
+        
+        template <class Command>
+        Command & add(boost::intrusive_ptr<Command> overload); ///< Add an additional overload
 
         ptr thisptr();
         cptr thisptr() const;
 
         OverloadedCommandNode & doc(std::string const & doc);
+                                        ///< Assign global help for all overloads
 
     protected:
 
@@ -127,7 +150,10 @@ namespace console {
         std::string doc_;
     };
 
-    /** \brief
+    /** \brief Basic command overload
+
+        This is an implementation of CommandOverload which allows to call an arbitrary callback with
+        the correct signature (<tt>void (std::ostream &, Arguments const &)</tt>)
       */
     class SimpleCommandOverload
         : public CommandOverload
@@ -144,11 +170,14 @@ namespace console {
         ///@{
 
         static SimpleCommandOverload::ptr create(Function fn);
+                                        ///< Create new SimpleCommandOverload
+                                        /**< \param[in] fn callback to call */
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
         SimpleCommandOverload & doc(std::string const & doc);
+                                        ///< Assign overload specific documentation
 
     protected:
 
@@ -167,7 +196,7 @@ namespace console {
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "OverloadedCommand.cci"
 //#include "OverloadedCommand.ct"
-//#include "OverloadedCommand.cti"
+#include "OverloadedCommand.cti"
 #endif
 
 \f
index 2879201..ece3da8 100644 (file)
@@ -58,18 +58,28 @@ namespace {
 BOOST_AUTO_UNIT_TEST(overladedCommand)
 {
     senf::console::OverloadedCommandNode & cmd (
-        senf::console::root().add("overload", senf::console::OverloadedCommandNode::create()));
-    cmd.add(senf::console::SimpleCommandOverload::create(&fn1));
-    cmd.add(senf::console::SimpleCommandOverload::create(&fn2));
+        senf::console::root()
+            .add("overload", senf::console::OverloadedCommandNode::create())
+            .doc("cmd") );
+    cmd.add(senf::console::SimpleCommandOverload::create(&fn1)).doc("fn1");
+    cmd.add(senf::console::SimpleCommandOverload::create(&fn2)).doc("fn2");
 
-    senf::console::ParseCommandInfo info;
-    std::stringstream ss;
-    BOOST_CHECK_THROW( senf::console::root()("overload")(ss, info.arguments()),
-                       senf::console::SyntaxErrorException );
-
-    cmd.add(senf::console::SimpleCommandOverload::create(&fn3));
-    BOOST_CHECK_NO_THROW( senf::console::root()("overload")(ss, info.arguments()) );
-    BOOST_CHECK_EQUAL( ss.str(), "fn3\n" );
+    {
+        senf::console::ParseCommandInfo info;
+        std::stringstream ss;
+        BOOST_CHECK_THROW( senf::console::root()("overload")(ss, info.arguments()),
+                           senf::console::SyntaxErrorException );
+        
+        cmd.add(senf::console::SimpleCommandOverload::create(&fn3)).doc("fn3");
+        BOOST_CHECK_NO_THROW( senf::console::root()("overload")(ss, info.arguments()) );
+        BOOST_CHECK_EQUAL( ss.str(), "fn3\n" );
+    }
+    
+    {
+        std::stringstream ss;
+        cmd.help(ss);
+        BOOST_CHECK_EQUAL( ss.str(), "cmd\n\nfn1\n\nfn2\n\nfn3" );
+    }
 
     cmd.unlink();
 }
index 05fa799..19e7576 100644 (file)
--- a/senf.dict
+++ b/senf.dict
@@ -16,6 +16,7 @@ AddressParser
 addtogroup
 aListCollection
 alloc
+anotherCallback
 api
 arg
 argc
@@ -46,7 +47,9 @@ checksumPresent
 CIDR
 ClientSocketHandle
 CloneSource
+cmd
 CommandNode
+CommandOverload
 CommandParser
 CommunicationPolicy
 CommunicationPolicyBase
@@ -250,6 +253,8 @@ OutputConnector
 outputRequest
 outputSocket
 OverlayField
+OverloadedCommand
+OverloadedCommandNode
 PacketData
 PacketImpl
 PacketInterpreter
@@ -339,6 +344,8 @@ setEnd
 setfill
 setFromPosition
 setw
+SimpleCommandNode
+SimpleCommandOverload
 SimplePacketType
 SimpleVectorSizer
 SiteScope
@@ -371,6 +378,7 @@ STL
 strerror
 struct
 structors
+SyntaxErrorException
 SyntaxException
 SystemException
 TapSocketHandle