Console: Add member function argument parsing
g0dil [Tue, 8 Apr 2008 09:38:55 +0000 (09:38 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@791 270642c3-0616-0410-b53a-bc976706d245

Console/ParsedCommand.cti
Console/ParsedCommand.hh
Console/ParsedCommand.mpp
Console/ParsedCommand.test.cc
Console/ScopedDirectory.cti
Console/ScopedDirectory.hh

index 86a78fc..9cdb279 100644 (file)
@@ -26,6 +26,7 @@
 #include "ParsedCommand.ih"
 
 // Custom includes
+#include "../Utils/membind.hh"
 
 #define prefix_ inline
 ///////////////////////////////cti.p///////////////////////////////////////
@@ -112,6 +113,26 @@ senf::console::senf_console_add_node(DirectoryNode & node, std::string const & n
                             typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(fn) );
 }
 
+template <class Owner, class Function>
+prefix_ senf::console::ParsedCommandOverload<
+    typename senf::console::detail::ParsedCommandTraits<Function>::traits> &
+senf::console::
+senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
+                      Function fn, int,
+                      typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type *)
+{
+    OverloadedCommandNode & cmdNode (
+        node.hasChild(name) 
+        ? dynamic_cast<OverloadedCommandNode &>(node(name))
+        : node.add(name, OverloadedCommandNode::create()) );
+
+    typedef senf::console::detail::ParsedCommandTraits<Function> CmdTraits;
+
+    return cmdNode.add( CreateParsedCommandOverload<
+                            typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(
+                                senf::membind(fn,&owner)) );
+}
+
 ///////////////////////////////cti.e///////////////////////////////////////
 #undef prefix_
 
index cd126c3..b2fca48 100644 (file)
@@ -32,6 +32,7 @@
 #include <boost/type_traits/is_member_pointer.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/mpl/if.hpp>
+#include <boost/utility.hpp>
 #include "../config.hh"
 #include "OverloadedCommand.hh"
 #include "ParseParameter.hh"
@@ -74,10 +75,20 @@ namespace console {
                                             1))
 #   include BOOST_PP_ITERATE()
 
+#ifndef DOXYGEN
+
     template <class Function>
     ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> &
     senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int);
 
+    template <class Owner, class Function>
+    ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> &
+    senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
+                          Function fn, int,
+                          typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
+
+#endif
+
 }}
 
 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
index 3052290..57948c1 100644 (file)
@@ -33,6 +33,7 @@
 #include <boost/preprocessor/arithmetic/inc.hpp>
 #include <boost/preprocessor/repetition/repeat.hpp>
 #include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
 #include <boost/bind.hpp>
 
 // ///////////////////////////mpp.p////////////////////////////////////////
@@ -68,9 +69,10 @@ public:
     typedef boost::function<typename traits::result_type(std::ostream &
                                                          mpp_TrailingArgTypes())> Function;
 
-#   define mpp_l(z,n,d)                                                                         \
-        typedef typename boost::remove_reference<typename traits::mpp_ArgTypeN(n)>::type        \
-            mpp_ArgTypeN(n);
+#   define mpp_l(z,n,d)                                                                           \
+        typedef typename boost::remove_const<                                                     \
+            typename boost::remove_reference< typename traits::mpp_ArgTypeN(n) >::type >::type    \
+                mpp_ArgTypeN(n);
     BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
 #   undef mpp_l
 
index 6365608..2b239d6 100644 (file)
@@ -113,8 +113,55 @@ BOOST_AUTO_UNIT_TEST(parsedCommand)
                          boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )),
             senf::console::SyntaxErrorException );
     }
+
+    {
+        std::stringstream ss;
+
+        dir.add("cb", &cb1);
+        dir.add("cb", &cb5);
+        dir.add("cb", &cb2);
+        parser.parse("test/cb 111 222.4; test/cb 222; test/cb",
+                     boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
+        BOOST_CHECK_EQUAL( ss.str(), "333\n" "Value: 222\n" "1.2\n" );
+    }
+}
+
+namespace {
+
+    struct Test 
+    {
+        senf::console::ScopedDirectory<Test> dir;
+        std::string name_;
+
+        Test(std::string const & name) : dir(this), name_ (name) {
+            dir.add("name", &Test::name);
+        }
+
+        std::string name(std::string const & suffix) {
+            return name_ + suffix;
+        }
+
+    };
 }
 
+BOOST_AUTO_UNIT_TEST(memberParsedCommand)
+{
+    senf::console::Executor executor;
+    senf::console::CommandParser parser;
+    senf::console::ScopedDirectory<> dir;
+    senf::console::root().add("test", dir);
+    
+    {
+        Test obj ("bar");
+        dir.add("obj", obj.dir);
+        
+        std::stringstream ss;
+        parser.parse("test/obj/name \": foo\"",
+                     boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
+        BOOST_CHECK_EQUAL( ss.str(), "bar: foo\n" );
+    }
+}
+    
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 
index d1fbe7a..04193e9 100644 (file)
@@ -41,7 +41,7 @@ senf::console::OwnerNodeCreateTraits<Owner,Object>::Creator::create(DirectoryNod
                                                                     std::string const & name,
                                                                     Object const & ob)
 {
-    return senf_console_add_node(node, owner, name, ob);
+    return senf_console_add_node(node, owner, name, ob, 0);
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -65,7 +65,7 @@ senf::console::ScopedDirectory<Owner>::add(std::string const & name, Object cons
 template <class Owner, class Function>
 prefix_ senf::console::SimpleCommandNode & senf::console::
 senf_console_add_node(DirectoryNode & node, Owner & , std::string const & name,
-                      Function const & fn)
+                      Function const & fn, ...)
 {
     return node.add(name,fn);
 }
@@ -73,7 +73,7 @@ senf_console_add_node(DirectoryNode & node, Owner & , std::string const & name,
 template <class Owner>
 prefix_ senf::console::SimpleCommandNode & senf::console::
 senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
-                      void (Owner::*fn)(std::ostream &, ParseCommandInfo const &))
+                      void (Owner::*fn)(std::ostream &, ParseCommandInfo const &), int)
 {
     return node.add(name, boost::bind(fn,boost::ref(owner),_1,_2));
 }
index d28e157..e86dc59 100644 (file)
@@ -49,7 +49,8 @@ namespace console {
                                       * static_cast<DirectoryNode *>(0),
                                       * static_cast<Owner *>(0),
                                       * static_cast<std::string const *>(0),
-                                      * static_cast<Object const *>(0)) ) result_type;
+                                      * static_cast<Object const *>(0),
+                                      * static_cast<int *>(0)) ) result_type;
 
         typedef typename boost::remove_reference<result_type>::type NodeType;
 
@@ -172,12 +173,12 @@ namespace console {
 #ifndef DOXYGEN
     template <class Owner, class Function>
     SimpleCommandNode & senf_console_add_node(
-        DirectoryNode & node, Owner & owner, std::string const & name, Function const & fn);
+        DirectoryNode & node, Owner & owner, std::string const & name, Function const & fn, ...);
 
     template <class Owner>
     SimpleCommandNode & senf_console_add_node(
         DirectoryNode & node, Owner & owner, std::string const & name,
-        void (Owner::*fn)(std::ostream &, ParseCommandInfo const &));
+        void (Owner::*fn)(std::ostream &, ParseCommandInfo const &), int);
 
     template <class Node>
     DirectoryNode & senf_console_add_node(