From: g0dil Date: Tue, 1 Apr 2008 18:51:31 +0000 (+0000) Subject: HowTos/NewPacket: Remove old code from example X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=30c1daf8a1c404209210f76a9a54bcfde443603b;p=senf.git HowTos/NewPacket: Remove old code from example Console: Implement OverloadableCommandNode Console: Make all virtual functions private Console: Rename ObjectDirectory to ScopedDirectory Console: Move non-template dependent ScopedDirectory members to ScopedDirectoryBase Console: Provide owner-less void specialization of ScopedDirectory git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@772 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Console/Node.cc b/Console/Node.cc index 5e1e427..1cd8d40 100644 --- a/Console/Node.cc +++ b/Console/Node.cc @@ -117,6 +117,15 @@ prefix_ void senf::console::DirectoryNode::v_help(std::ostream & output) } /////////////////////////////////////////////////////////////////////////// +// senf::console::SyntaxErrorException + +prefix_ char const * senf::console::SyntaxErrorException::what() + const throw() +{ + return message().empty() ? "syntax error" : message().c_str(); +} + +/////////////////////////////////////////////////////////////////////////// // senf::console::SimpleCommandNode prefix_ void senf::console::SimpleCommandNode::v_help(std::ostream & output) @@ -125,6 +134,13 @@ prefix_ void senf::console::SimpleCommandNode::v_help(std::ostream & output) output << doc_ << "\n"; } +prefix_ void senf::console::SimpleCommandNode::v_execute(std::ostream & output, + Arguments const & arguments) + const +{ + fn_(output, arguments); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Node.mpp" diff --git a/Console/Node.cci b/Console/Node.cci index 43954f3..5f824bd 100644 --- a/Console/Node.cci +++ b/Console/Node.cci @@ -140,6 +140,13 @@ prefix_ senf::console::DirectoryNode::cptr senf::console::DirectoryNode::thisptr } /////////////////////////////////////////////////////////////////////////// +// senf::console::SyntaxErrorException + +prefix_ senf::console::SyntaxErrorException::SyntaxErrorException(std::string const & msg) + : Exception(msg) +{} + +/////////////////////////////////////////////////////////////////////////// // senf::console::CommandNode prefix_ senf::console::CommandNode::ptr senf::console::CommandNode::thisptr() @@ -156,15 +163,16 @@ prefix_ senf::console::CommandNode::cptr senf::console::CommandNode::thisptr() prefix_ senf::console::CommandNode::CommandNode() {} -/////////////////////////////////////////////////////////////////////////// -// senf::console::SimpleCommandNode - -prefix_ void senf::console::SimpleCommandNode::operator()(std::ostream & output, - Arguments const & arguments) +prefix_ void senf::console::CommandNode::operator()(std::ostream & output, + Arguments const & arguments) + const { - fn_(output, arguments); + v_execute(output, arguments); } +/////////////////////////////////////////////////////////////////////////// +// senf::console::SimpleCommandNode + prefix_ senf::console::SimpleCommandNode::SimpleCommandNode(Function const & fn) : fn_ (fn) {} @@ -182,6 +190,17 @@ senf::console::SimpleCommandNode::doc(std::string const & doc) return *this; } +prefix_ senf::console::SimpleCommandNode::ptr senf::console::SimpleCommandNode::thisptr() +{ + return boost::static_pointer_cast(shared_from_this()); +} + +prefix_ senf::console::SimpleCommandNode::cptr senf::console::SimpleCommandNode::thisptr() + const +{ + return boost::static_pointer_cast(shared_from_this()); +} + ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Console/Node.hh b/Console/Node.hh index 0bed22b..961a1b8 100644 --- a/Console/Node.hh +++ b/Console/Node.hh @@ -49,7 +49,7 @@ 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 dir; + senf::console::ScopedDirectory dir; SomeClass() : dir(this) { @@ -178,11 +178,11 @@ 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. */ @@ -324,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 @@ -357,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() */ ///\} /////////////////////////////////////////////////////////////////////////// @@ -479,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 @@ -504,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 @@ -517,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: }; @@ -551,8 +568,6 @@ namespace console { ///\} /////////////////////////////////////////////////////////////////////////// - virtual void operator()(std::ostream & output, Arguments const & arguments); - ptr thisptr(); cptr thisptr() const; @@ -563,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_; diff --git a/Console/OverloadedCommand.cc b/Console/OverloadedCommand.cc new file mode 100644 index 0000000..30e7fbb --- /dev/null +++ b/Console/OverloadedCommand.cc @@ -0,0 +1,98 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 non-inline non-template implementation */ + +#include "OverloadedCommand.hh" +//#include "OverloadedCommand.ih" + +// Custom includes + +//#include "OverloadedCommand.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// senf::console::OverloadedCommandNode + +prefix_ void senf::console::OverloadedCommandNode::v_help(std::ostream & os) + const +{ + os << doc_; + Overloads::const_iterator i (overloads_.begin()); + Overloads::const_iterator const i_end (overloads_.end()); + for (; i != i_end; ++i) { + os << "\n\n"; + (*i)->help(os); + } +} + +prefix_ void senf::console::OverloadedCommandNode::v_execute(std::ostream & output, + Arguments const & arguments) + const +{ + Overloads::const_iterator i (overloads_.begin()); + Overloads::const_iterator const i_end (overloads_.end()); + SyntaxErrorException err; + for (; i != i_end; ++i) { + try { + (**i)(output, arguments); + return; + } + catch (SyntaxErrorException & ex) { + err = ex; + }; + } + throw err; +} + +/////////////////////////////////////////////////////////////////////////// +// senf::console::SimpleCommandOverload + +prefix_ void senf::console::SimpleCommandOverload::v_help(std::ostream & os) + const +{ + os << doc_; +} + +prefix_ void senf::console::SimpleCommandOverload::v_execute(std::ostream & os, + Arguments const & arguments) + const +{ + fn_(os, arguments); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "OverloadedCommand.mpp" + + +// 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: diff --git a/Console/OverloadedCommand.cci b/Console/OverloadedCommand.cci new file mode 100644 index 0000000..21add3b --- /dev/null +++ b/Console/OverloadedCommand.cci @@ -0,0 +1,126 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 non-template implementation */ + +//#include "OverloadedCommand.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// senf::console::CommandOverload + +prefix_ senf::console::CommandOverload::~CommandOverload() +{} + +prefix_ void senf::console::CommandOverload::operator()(std::ostream & os, + Arguments const & arguments) +{ + v_execute(os, arguments); +} + +prefix_ void senf::console::CommandOverload::help(std::ostream & os) +{ + v_help(os); +} + +prefix_ senf::console::OverloadedCommandNode & senf::console::CommandOverload::node() +{ + SENF_ASSERT( node_ ); + return *node_; +} + +prefix_ senf::console::CommandOverload::CommandOverload() + : node_(0) +{} + +/////////////////////////////////////////////////////////////////////////// +// senf::console::OverloadedCommandNode + +prefix_ senf::console::OverloadedCommandNode::ptr senf::console::OverloadedCommandNode::create() +{ + 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(shared_from_this()); +} + +prefix_ senf::console::OverloadedCommandNode::cptr senf::console::OverloadedCommandNode::thisptr() + const +{ + return boost::static_pointer_cast(shared_from_this()); +} + +prefix_ senf::console::OverloadedCommandNode & +senf::console::OverloadedCommandNode::doc(std::string const & doc) +{ + doc_ = doc; + return *this; +} + +prefix_ senf::console::OverloadedCommandNode::OverloadedCommandNode() +{} + +/////////////////////////////////////////////////////////////////////////// +// senf::console::SimpleCommandOverload + +prefix_ senf::console::SimpleCommandOverload::ptr +senf::console::SimpleCommandOverload::create(Function fn) +{ + return ptr(new SimpleCommandOverload(fn)); +} + +prefix_ senf::console::SimpleCommandOverload & +senf::console::SimpleCommandOverload::doc(std::string const & doc) +{ + doc_ = doc; + return *this; +} + +prefix_ senf::console::SimpleCommandOverload::SimpleCommandOverload(Function fn) + : fn_ (fn) +{} + +///////////////////////////////cci.e/////////////////////////////////////// +#undef prefix_ + + +// 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: diff --git a/Console/OverloadedCommand.hh b/Console/OverloadedCommand.hh new file mode 100644 index 0000000..a255eb5 --- /dev/null +++ b/Console/OverloadedCommand.hh @@ -0,0 +1,182 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 public header */ + +#ifndef HH_OverloadedCommand_ +#define HH_OverloadedCommand_ 1 + +// Custom includes +#include "Node.hh" +#include +#include "../Utils/intrusive_refcount.hh" + +//#include "OverloadedCommand.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { +namespace console { + + class OverloadedCommandNode; + + /** \brief + */ + class CommandOverload + : public senf::intrusive_refcount + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + typedef boost::intrusive_ptr ptr; + typedef CommandNode::Arguments Arguments; + + /////////////////////////////////////////////////////////////////////////// + + virtual ~CommandOverload(); + + void operator()(std::ostream & os, Arguments const & arguments); + void help(std::ostream & os); + + OverloadedCommandNode & node(); + + protected: + CommandOverload(); + +#ifndef DOXYGEN + private: +#endif + virtual void v_help(std::ostream & os) const = 0; + virtual void v_execute(std::ostream & os, Arguments const & arguments) const = 0; + + private: + OverloadedCommandNode * node_; + + friend class OverloadedCommandNode; + }; + + /** \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. + + \warning For this to work, the commands must do all syntax checking before doing any + operation + + \ingroup node_tree + */ + class OverloadedCommandNode + : public CommandNode + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + typedef boost::shared_ptr ptr; + typedef boost::shared_ptr cptr; + typedef boost::weak_ptr weak_ptr; + + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + static ptr create(); + + ///@} + /////////////////////////////////////////////////////////////////////////// + + void add(CommandOverload::ptr overload); + + ptr thisptr(); + cptr thisptr() const; + + OverloadedCommandNode & doc(std::string const & doc); + + protected: + + private: + OverloadedCommandNode(); + + virtual void v_help(std::ostream & output) const; + virtual void v_execute(std::ostream & output, Arguments const & arguments) const; + + typedef std::vector Overloads; + + Overloads overloads_; + std::string doc_; + }; + + /** \brief + */ + class SimpleCommandOverload + : public CommandOverload + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + typedef boost::intrusive_ptr ptr; + typedef boost::function Function; + + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + static SimpleCommandOverload::ptr create(Function fn); + + ///@} + /////////////////////////////////////////////////////////////////////////// + + SimpleCommandOverload & doc(std::string const & doc); + + protected: + + private: + SimpleCommandOverload(Function fn); + + virtual void v_help(std::ostream & os) const; + virtual void v_execute(std::ostream & os, Arguments const & arguments) const; + + Function fn_; + std::string doc_; + }; + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "OverloadedCommand.cci" +//#include "OverloadedCommand.ct" +//#include "OverloadedCommand.cti" +#endif + + +// 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: diff --git a/Console/ObjectDirectory.test.cc b/Console/OverloadedCommand.test.cc similarity index 52% rename from Console/ObjectDirectory.test.cc rename to Console/OverloadedCommand.test.cc index a8e99af..2879201 100644 --- a/Console/ObjectDirectory.test.cc +++ b/Console/OverloadedCommand.test.cc @@ -21,14 +21,14 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief ObjectDirectory.test unit tests */ + \brief OverloadedCommand.test unit tests */ -//#include "ObjectDirectory.test.hh" -//#include "ObjectDirectory.test.ih" +//#include "OverloadedCommand.test.hh" +//#include "OverloadedCommand.test.ih" // Custom includes #include -#include "ObjectDirectory.hh" +#include "OverloadedCommand.hh" #include #include @@ -37,31 +37,41 @@ ///////////////////////////////cc.p//////////////////////////////////////// namespace { - struct TestObject { - typedef TestObject Self; - - senf::console::ObjectDirectory dir; - TestObject() : dir(this) { - dir.add("member", &Self::member); - } - - void member(std::ostream & os, senf::console::CommandNode::Arguments const &) { - os << "member"; - } - }; -} -BOOST_AUTO_UNIT_TEST(objectDirectory) -{ + void fn1(std::ostream &, senf::console::CommandOverload::Arguments const &) + { + throw senf::console::SyntaxErrorException("fn1 error"); + } + + void fn2(std::ostream &, senf::console::CommandOverload::Arguments const &) + { + throw senf::console::SyntaxErrorException("fn2 error"); + } + + void fn3(std::ostream & os, senf::console::CommandOverload::Arguments const &) { - TestObject ob; - senf::console::root().add("ob",ob.dir); - std::stringstream ss; - senf::console::ParseCommandInfo info; - senf::console::root()["ob"]("member")(ss, info.arguments()); - BOOST_CHECK_EQUAL( ss.str(), "member" ); + os << "fn3\n"; } - BOOST_CHECK_THROW( senf::console::root()["ob"], senf::console::UnknownNodeNameException ); + +} + +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::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" ); + + cmd.unlink(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Console/ScopedDirectory.cci b/Console/ScopedDirectory.cci new file mode 100644 index 0000000..b6acd78 --- /dev/null +++ b/Console/ScopedDirectory.cci @@ -0,0 +1,109 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 ScopedDirectory inline non-template implementation */ + +//#include "ScopedDirectory.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// senf::console::ScopedDirectoryBase + +prefix_ senf::console::DirectoryNode & senf::console::ScopedDirectoryBase::node() + const +{ + return *node_; +} + +prefix_ senf::console::GenericNode::ptr +senf::console::ScopedDirectoryBase::remove(std::string const & name) +{ + return node().remove(name); +} + +prefix_ senf::console::DirectoryNode & +senf::console::ScopedDirectoryBase::operator[](std::string const & name) + const +{ + return node()[name]; +} + +prefix_ senf::console::CommandNode & +senf::console::ScopedDirectoryBase::operator()(std::string const & name) + const +{ + return node()(name); +} + +prefix_ senf::console::GenericNode & +senf::console::ScopedDirectoryBase::get(std::string const & name) + const +{ + return node().get(name); +} + +prefix_ senf::console::DirectoryNode & +senf::console::ScopedDirectoryBase::mkdir(std::string const & name) +{ + return node().mkdir(name); +} + +prefix_ senf::console::DirectoryNode::ChildrenRange +senf::console::ScopedDirectoryBase::children() + const +{ + return node().children(); +} + +prefix_ senf::console::DirectoryNode & +senf::console::ScopedDirectoryBase::doc(std::string const & doc) +{ + return node().doc(doc); +} + +prefix_ senf::console::ScopedDirectoryBase::ScopedDirectoryBase() + : node_ (DirectoryNode::create()) +{} + +prefix_ senf::console::ScopedDirectoryBase::~ScopedDirectoryBase() +{ + node_->unlink(); +} + +///////////////////////////////cci.e/////////////////////////////////////// +#undef prefix_ + + +// 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: diff --git a/Console/ObjectDirectory.cti b/Console/ScopedDirectory.cti similarity index 64% rename from Console/ObjectDirectory.cti rename to Console/ScopedDirectory.cti index c3f3e0d..87ce190 100644 --- a/Console/ObjectDirectory.cti +++ b/Console/ScopedDirectory.cti @@ -21,9 +21,9 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief ObjectDirectory inline template implementation */ + \brief ScopedDirectory inline template implementation */ -//#include "ObjectDirectory.ih" +//#include "ScopedDirectory.ih" // Custom includes #include @@ -45,85 +45,21 @@ senf::console::OwnerNodeCreateTraits::Creator::create(DirectoryNod } /////////////////////////////////////////////////////////////////////////// -// senf::console::ObjectDirectory +// senf::console::ScopedDirectory template -prefix_ senf::console::ObjectDirectory::ObjectDirectory(Owner * owner) - : node_ (DirectoryNode::create()), owner_ (owner) -{} - -template -prefix_ senf::console::ObjectDirectory::~ObjectDirectory() +prefix_ senf::console::ScopedDirectory::ScopedDirectory(Owner * owner) + : owner_ (owner) { - node_->unlink(); + SENF_ASSERT(owner_); } template template prefix_ typename senf::console::OwnerNodeCreateTraits::NodeType & -senf::console::ObjectDirectory::add(std::string const & name, Object const & ob) -{ - return OwnerNodeCreateTraits::Creator::create(*node_, *owner_, name, ob); -} - -template -prefix_ senf::console::GenericNode::ptr -senf::console::ObjectDirectory::remove(std::string const & name) -{ - return node().remove(name); -} - -template -prefix_ senf::console::DirectoryNode & -senf::console::ObjectDirectory::operator[](std::string const & name) - const -{ - return node()[name]; -} - -template -prefix_ senf::console::CommandNode & -senf::console::ObjectDirectory::operator()(std::string const & name) - const -{ - return node()(name); -} - -template -prefix_ senf::console::GenericNode & -senf::console::ObjectDirectory::get(std::string const & name) - const -{ - return node().get(name); -} - -template -prefix_ senf::console::DirectoryNode & -senf::console::ObjectDirectory::mkdir(std::string const & name) -{ - return node().mkdir(name); -} - -template -prefix_ senf::console::DirectoryNode::ChildrenRange -senf::console::ObjectDirectory::children() - const -{ - return node().children(); -} - -template -prefix_ senf::console::DirectoryNode & -senf::console::ObjectDirectory::doc(std::string const & doc) +senf::console::ScopedDirectory::add(std::string const & name, Object const & ob) { - return node.doc(doc); -} - -template -prefix_ senf::console::DirectoryNode & senf::console::ObjectDirectory::node() - const -{ - return *node_; + return OwnerNodeCreateTraits::Creator::create(node(), *owner_, name, ob); } template @@ -146,11 +82,21 @@ senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & n template prefix_ senf::console::DirectoryNode & senf::console:: senf_console_add_node(DirectoryNode & dir, std::string const & name, Node const & node, int, - typename boost::enable_if< boost::is_convertible >::type *) + typename boost::enable_if< boost::is_convertible >::type *) { return dir.add(name, node.node().thisptr()); } +/////////////////////////////////////////////////////////////////////////// +// senf::console::ScopedDirectory + +template +prefix_ typename senf::console::NodeCreateTraits::NodeType & +senf::console::ScopedDirectory::add(std::string const & name, Object const & ob) +{ + return node().add(name, ob); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Console/ObjectDirectory.hh b/Console/ScopedDirectory.hh similarity index 83% rename from Console/ObjectDirectory.hh rename to Console/ScopedDirectory.hh index 1845a06..cec50db 100644 --- a/Console/ObjectDirectory.hh +++ b/Console/ScopedDirectory.hh @@ -21,26 +21,26 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief ObjectDirectory public header */ + \brief ScopedDirectory public header */ -#ifndef HH_ObjectDirectory_ -#define HH_ObjectDirectory_ 1 +#ifndef HH_ScopedDirectory_ +#define HH_ScopedDirectory_ 1 // Custom includes #include #include #include "Node.hh" -//#include "ObjectDirectory.mpp" +//#include "ScopedDirectory.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { namespace console { - /** \brief Internal: Node creation helper traits (ObjectDirectory proxy) + /** \brief Internal: Node creation helper traits (ScopedDirectory proxy) This class is used like NodeCreateTraits to customize the child node creation. This trait - class is used however by the ObjectDirectory proxy. + class is used however by the ScopedDirectory proxy. */ template struct OwnerNodeCreateTraits @@ -60,13 +60,38 @@ namespace console { }; }; - /** \brief Internal: Marker base class for all ObjectDirectory proxies + /** \brief Internal: Marker base class for all ScopedDirectory proxies */ - struct ObjectDirectoryBase {}; + class ScopedDirectoryBase + { + public: + DirectoryNode & node() const; ///< Access the proxied DirectoryNode + + /////////////////////////////////////////////////////////////////////////// + ///\name Proxied members (see DirectoryNode) + ///\{ + + GenericNode::ptr remove(std::string const & name); + DirectoryNode & operator[](std::string const & name) const; + CommandNode & operator()(std::string const & name) const; + GenericNode & get(std::string const & name) const; + DirectoryNode & mkdir(std::string const & name); + DirectoryNode::ChildrenRange children() const; + DirectoryNode & doc(std::string const & doc); + + ///\} + + protected: + ScopedDirectoryBase(); + ~ScopedDirectoryBase(); + + private: + DirectoryNode::ptr node_; + }; /** \brief DirectoryNode member proxy - ObjectDirectory is used whenever a class wants to manage it's own directory. The class + ScopedDirectory is used whenever a class wants to manage it's own directory. The class allows to declare the directory as a public member object. This allows the user of the class to register the directory in the command tree. By using the proxy, the node is automatically detached from the tree (and thereby destroyed) when the object (and thereby the proxy) is @@ -76,7 +101,7 @@ namespace console { class MyClass { public: - ObjectDirectory configDir; + ScopedDirectory configDir; MyClass() : configDir(this) { @@ -85,9 +110,9 @@ namespace console { }; \endcode - The ObjectDirectory proxy implements 'add()' to add new children to the proxied + The ScopedDirectory proxy implements 'add()' to add new children to the proxied DirectoryNode. All add() variants supported by DirectoryNode are supported by - ObjectDirectory. + ScopedDirectory. \idea This proxy could be made obsolete by allowing to allocate node objects statically. This could be achieved by moving back to an intrusive_ptr implementation for @@ -98,8 +123,8 @@ namespace console { \ingroup node_tree */ - template - class ObjectDirectory : public ObjectDirectoryBase + template + class ScopedDirectory : public ScopedDirectoryBase { public: /////////////////////////////////////////////////////////////////////////// @@ -111,8 +136,7 @@ namespace console { ///\name Structors and default members ///@{ - ObjectDirectory(Owner * owner); - ~ObjectDirectory(); + ScopedDirectory(Owner * owner); ///@} /////////////////////////////////////////////////////////////////////////// @@ -127,29 +151,21 @@ namespace console { implementation just forwards the call to the proxied directory node. */ - DirectoryNode & node() const; ///< Access the proxied DirectoryNode - - /////////////////////////////////////////////////////////////////////////// - ///\name Proxied members (see DirectoryNode) - ///\{ - - GenericNode::ptr remove(std::string const & name); - DirectoryNode & operator[](std::string const & name) const; - CommandNode & operator()(std::string const & name) const; - GenericNode & get(std::string const & name) const; - DirectoryNode & mkdir(std::string const & name); - DirectoryNode::ChildrenRange children() const; - DirectoryNode & doc(std::string const & doc); - - ///\} - protected: private: - DirectoryNode::ptr node_; Owner * owner_; }; + template <> + class ScopedDirectory : public ScopedDirectoryBase + { + public: + template + typename NodeCreateTraits::NodeType & add(std::string const & name, + Object const & ob); + }; + #ifndef DOXYGEN template SimpleCommandNode & senf_console_add_node( @@ -163,15 +179,15 @@ namespace console { template DirectoryNode & senf_console_add_node( DirectoryNode & dir, std::string const & name, Node const & node, int, - typename boost::enable_if< boost::is_convertible >::type * = 0); + typename boost::enable_if< boost::is_convertible >::type * = 0); #endif }} ///////////////////////////////hh.e//////////////////////////////////////// -//#include "ObjectDirectory.cci" -//#include "ObjectDirectory.ct" -#include "ObjectDirectory.cti" +#include "ScopedDirectory.cci" +//#include "ScopedDirectory.ct" +#include "ScopedDirectory.cti" #endif diff --git a/Console/ScopedDirectory.test.cc b/Console/ScopedDirectory.test.cc new file mode 100644 index 0000000..4a3ce75 --- /dev/null +++ b/Console/ScopedDirectory.test.cc @@ -0,0 +1,135 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 ScopedDirectory.test unit tests */ + +//#include "ScopedDirectory.test.hh" +//#include "ScopedDirectory.test.ih" + +// Custom includes +#include +#include "ScopedDirectory.hh" +#include + +#include +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +namespace { + struct TestObject { + typedef TestObject Self; + + senf::console::ScopedDirectory dir; + TestObject() : dir(this) { + dir.add("member", &Self::member); + } + + void member(std::ostream & os, senf::console::CommandNode::Arguments const &) { + os << "member"; + } + }; +} + +BOOST_AUTO_UNIT_TEST(scopedDirectory) +{ + { + TestObject ob; + senf::console::root().add("ob",ob.dir); + std::stringstream ss; + senf::console::ParseCommandInfo info; + senf::console::root()["ob"]("member")(ss, info.arguments()); + BOOST_CHECK_EQUAL( ss.str(), "member" ); + } + BOOST_CHECK_THROW( senf::console::root()["ob"], senf::console::UnknownNodeNameException ); +} + +namespace { + void callback(std::ostream & os, senf::console::CommandNode::Arguments const &) { + os << "cb"; + } +} + +BOOST_AUTO_UNIT_TEST(scopedDirectoryVoid) +{ + { + senf::console::ScopedDirectory<> dir; + senf::console::root().add("dir", dir); + dir.add("cb", &callback); + std::stringstream ss; + senf::console::ParseCommandInfo info; + senf::console::root()["dir"]("cb")(ss, info.arguments()); + BOOST_CHECK_EQUAL( ss.str(), "cb" ); + } + BOOST_CHECK_THROW( senf::console::root()["dir"], + senf::console::UnknownNodeNameException ); +} + +namespace { + template + struct select1st { + typedef T result_type; + template result_type operator()(U const & u) const { return u.first; } + }; +} + +BOOST_AUTO_UNIT_TEST(scopedDirectoryBase) +{ + { + senf::console::ScopedDirectory<> dir; + senf::console::root().add("dir", dir); + dir.mkdir("foo"); + dir.add("cb", &callback); + BOOST_CHECK( &dir["foo"] == &dir.get("foo") ); + BOOST_CHECK( &dir("cb") == &dir.get("cb") ); + + char const * const children[] = { "cb", "foo" }; + BOOST_CHECK_EQUAL_COLLECTIONS( + boost::make_transform_iterator(dir.children().begin(), + select1st()), + boost::make_transform_iterator(dir.children().end(), + select1st()), + children, + children+sizeof(children)/sizeof(children[0]) ); + + dir.doc("dir"); + std::stringstream ss; + dir.node().help(ss); + BOOST_CHECK_EQUAL( ss.str(), "dir\n" ); + } +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// 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: diff --git a/Console/testServer.cc b/Console/testServer.cc index dc40117..b7d5124 100644 --- a/Console/testServer.cc +++ b/Console/testServer.cc @@ -30,7 +30,7 @@ #include #include "Server.hh" #include "Node.hh" -#include "ObjectDirectory.hh" +#include "ScopedDirectory.hh" #include "../Scheduler/Scheduler.hh" #include "../Utils/Logger/SenfLog.hh" @@ -55,7 +55,7 @@ namespace { struct TestObject { - senf::console::ObjectDirectory dir; + senf::console::ScopedDirectory dir; TestObject() : dir(this) { dir.add("blub", &TestObject::blub) diff --git a/HowTos/NewPacket/Mainpage.dox b/HowTos/NewPacket/Mainpage.dox index bd659ab..e519e91 100644 --- a/HowTos/NewPacket/Mainpage.dox +++ b/HowTos/NewPacket/Mainpage.dox @@ -805,9 +805,6 @@ (senf::VoidPacketParser) (GREPacketParser_OptFields) ); - typedef version__t version_t; - version_t::value_type version() const { return version_(); } - bool valid() const { return version() == 0 && reserved0_5bits_() == 0; } typedef GREPacketParser_OptFields::checksum_t checksum_t; diff --git a/doclib/senf.css b/doclib/senf.css index fe51388..1783cc1 100644 --- a/doclib/senf.css +++ b/doclib/senf.css @@ -513,7 +513,7 @@ p.commalist { } #autotoc { - width: 20em; + width: 30em; background-color: #F5F5F5; border: 1px solid #CCC; padding: 0 1em;