From d5acef30819a12b787adfd573909ae079fd20797 Mon Sep 17 00:00:00 2001 From: g0dil <g0dil@wiback.org> Date: Tue, 8 Apr 2008 09:38:55 +0000 Subject: [PATCH] Console: Add member function argument parsing --- Console/ParsedCommand.cti | 21 ++++++++++++++++ Console/ParsedCommand.hh | 11 ++++++++ Console/ParsedCommand.mpp | 8 +++--- Console/ParsedCommand.test.cc | 47 +++++++++++++++++++++++++++++++++++ Console/ScopedDirectory.cti | 6 ++--- Console/ScopedDirectory.hh | 7 +++--- 6 files changed, 91 insertions(+), 9 deletions(-) diff --git a/Console/ParsedCommand.cti b/Console/ParsedCommand.cti index 86a78fc4f..9cdb2792b 100644 --- a/Console/ParsedCommand.cti +++ b/Console/ParsedCommand.cti @@ -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_ diff --git a/Console/ParsedCommand.hh b/Console/ParsedCommand.hh index cd126c30a..b2fca4867 100644 --- a/Console/ParsedCommand.hh +++ b/Console/ParsedCommand.hh @@ -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() diff --git a/Console/ParsedCommand.mpp b/Console/ParsedCommand.mpp index 305229017..57948c197 100644 --- a/Console/ParsedCommand.mpp +++ b/Console/ParsedCommand.mpp @@ -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 diff --git a/Console/ParsedCommand.test.cc b/Console/ParsedCommand.test.cc index 636560831..2b239d600 100644 --- a/Console/ParsedCommand.test.cc +++ b/Console/ParsedCommand.test.cc @@ -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_ diff --git a/Console/ScopedDirectory.cti b/Console/ScopedDirectory.cti index d1fbe7aea..04193e9b8 100644 --- a/Console/ScopedDirectory.cti +++ b/Console/ScopedDirectory.cti @@ -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)); } diff --git a/Console/ScopedDirectory.hh b/Console/ScopedDirectory.hh index d28e15791..e86dc59de 100644 --- a/Console/ScopedDirectory.hh +++ b/Console/ScopedDirectory.hh @@ -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( -- GitLab