{
SENF_LOG(( "Executing: " << command ));
- ///\fixme Whenever checking cwd_.expired(), we also need to check, wether
- /// the node is still connected to the root.
- if (cwd_.expired())
+ if (cwd_.expired() || ! cwd().active())
cwd_ = root().thisptr();
try {
if ( command.arguments() ) {
if (command.arguments().begin()->size() == 1
&& command.arguments().begin()->begin()->value() == "-") {
- if (oldCwd_.expired()) {
+ if (oldCwd_.expired() || ! oldCwd_.lock()->active()) {
oldCwd_ = cwd_;
cwd_ = root().thisptr();
} else
case ParseCommandInfo::BuiltinEXIT :
throw ExitException();
+
+ case ParseCommandInfo::BuiltinHELP :
+ try {
+ GenericNode & node (
+ command.arguments()
+ ? cwd().traverse(
+ boost::make_iterator_range(
+ boost::make_transform_iterator(command.arguments().begin()[0].begin(), TraverseTokens()),
+ boost::make_transform_iterator(command.arguments().begin()[0].end(), TraverseTokens())))
+ : cwd() );
+ node.help(output);
+ output << std::flush;
+ }
+ catch (UnknownNodeNameException &) {
+ output << "invalid path" << std::endl;
+ }
+ break;
}
}
catch (InvalidDirectoryException &) {
prefix_ senf::console::DirectoryNode & senf::console::root()
{
- static DirectoryNode::ptr rootNode(new DirectoryNode(""));
+ static DirectoryNode::ptr rootNode(new DirectoryNode());
return *rootNode;
}
return path.empty() ? "/" : path;
}
+prefix_ bool senf::console::GenericNode::active()
+ const
+{
+ cptr node (thisptr());
+ while (node->parent())
+ node = node->parent();
+ return node == root().thisptr();
+}
+
///////////////////////////////////////////////////////////////////////////
//senf::console::DirectoryNode
-prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node, bool uniquify)
+prefix_ senf::console::GenericNode::ptr
+senf::console::DirectoryNode::remove(std::string const & name)
+{
+ ChildMap::iterator i (children_.find(name));
+ if (i == children_.end())
+ throw UnknownNodeNameException() << ": '" << name << "'";
+ GenericNode::ptr node (i->second);
+ children_.erase(i);
+ return node;
+}
+
+prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node)
{
BOOST_ASSERT( ! node->parent() );
if (children_.find(node->name()) != children_.end()) {
- if (! uniquify)
- throw DuplicateNodeNameException() << ": '" << node->name() << "'";
unsigned suffix (0);
std::string newName;
do {
return *(i->second);
}
+prefix_ void senf::console::DirectoryNode::v_help(std::ostream & output)
+ const
+{
+ output << doc_ << "\n";
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::SimpleCommandNode
+
+prefix_ void senf::console::SimpleCommandNode::v_help(std::ostream & output)
+ const
+{
+ output << doc_ << "\n";
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "Node.mpp"
return name_;
}
-prefix_ senf::console::GenericNode::GenericNode(std::string const & name)
- : name_ (name), parent_ (0)
-{
- ///\fixme Provide a default name if 'name' is empty ?
-}
+prefix_ senf::console::GenericNode::GenericNode()
+ : parent_ (0)
+{}
prefix_ void senf::console::GenericNode::name(std::string const & name)
{
parent_ ? parent_->shared_from_this() : ptr() );
}
+prefix_ senf::console::GenericNode::ptr senf::console::GenericNode::unlink()
+{
+ SENF_ASSERT( parent() );
+ return parent()->remove(name());
+}
+
+prefix_ void senf::console::GenericNode::help(std::ostream & output)
+ const
+{
+ v_help(output);
+}
+
prefix_ senf::console::GenericNode::ptr senf::console::GenericNode::thisptr()
{
return shared_from_this();
///////////////////////////////////////////////////////////////////////////
// senf::console::DirectoryNode
-prefix_ senf::console::GenericNode &
-senf::console::DirectoryNode::add(std::auto_ptr<GenericNode> node, bool uniquify)
+prefix_ std::auto_ptr<senf::console::DirectoryNode>
+senf::console::DirectoryNode::create()
{
- GenericNode::ptr p (node.release());
- add(p, uniquify);
- return *p;
+ return std::auto_ptr<DirectoryNode>(new DirectoryNode());
}
prefix_ senf::console::DirectoryNode &
prefix_ senf::console::DirectoryNode &
senf::console::DirectoryNode::mkdir(std::string const & name)
{
- return static_cast<DirectoryNode &>(
- add(std::auto_ptr<GenericNode>(new DirectoryNode(name))));
+ std::auto_ptr<DirectoryNode> node (create());
+ return add(name, node);
}
prefix_ senf::console::DirectoryNode::ChildrenRange senf::console::DirectoryNode::children()
return boost::make_iterator_range(children_.begin(), children_.end());
}
-prefix_ senf::console::DirectoryNode::DirectoryNode(std::string const & name)
- : GenericNode(name)
+prefix_ senf::console::DirectoryNode::DirectoryNode()
{}
+prefix_ senf::console::DirectoryNode &
+senf::console::DirectoryNode::doc(std::string const & doc)
+{
+ doc_ = doc;
+ return *this;
+}
+
prefix_ senf::console::DirectoryNode::ptr senf::console::DirectoryNode::thisptr()
{
return boost::static_pointer_cast<DirectoryNode>(shared_from_this());
///////////////////////////////////////////////////////////////////////////
// senf::console::CommandNode
-prefix_ senf::console::CommandNode::CommandNode(std::string const & name)
- : GenericNode(name)
-{}
-
prefix_ senf::console::CommandNode::ptr senf::console::CommandNode::thisptr()
{
return boost::static_pointer_cast<CommandNode>(shared_from_this());
return boost::static_pointer_cast<CommandNode const>(shared_from_this());
}
+prefix_ senf::console::CommandNode::CommandNode()
+{}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::SimpleCommandNode
+
+prefix_ void senf::console::SimpleCommandNode::operator()(std::ostream & output,
+ Arguments const & arguments)
+{
+ fn_(output, arguments);
+}
+
+prefix_ senf::console::SimpleCommandNode::SimpleCommandNode(Function const & fn)
+ : fn_ (fn)
+{}
+
+prefix_ std::auto_ptr<senf::console::SimpleCommandNode>
+senf::console::SimpleCommandNode::create(Function const & fn)
+{
+ return std::auto_ptr<SimpleCommandNode>(new SimpleCommandNode(fn));
+}
+
+prefix_ senf::console::SimpleCommandNode &
+senf::console::SimpleCommandNode::doc(std::string const & doc)
+{
+ doc_ = doc;
+ return *this;
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
--- /dev/null
+// $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 Node inline template implementation */
+
+//#include "Node.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::NodeCreateTraits<Object>::Creator
+
+template <class Object>
+prefix_ typename senf::console::NodeCreateTraits<Object>::NodeType &
+senf::console::NodeCreateTraits<Object>::Creator::create(DirectoryNode & node,
+ std::string const & name,
+ Object const & ob)
+{
+ return senf_console_add_node(node, name, ob, 0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::DirectoryNode
+
+template <class NodeType>
+prefix_ NodeType & senf::console::DirectoryNode::add(std::string const & name,
+ std::auto_ptr<NodeType> node)
+{
+ GenericNode::ptr p (node);
+ p->name(name);
+ add(p);
+ return static_cast<NodeType &>(*p);
+}
+
+template <class NodeType>
+prefix_ NodeType & senf::console::DirectoryNode::add(std::string const & name,
+ boost::shared_ptr<NodeType> node)
+{
+ SENF_ASSERT( ! node->parent() );
+ node->name(name);
+ add(node);
+ return *node;
+}
+
+template <class Object>
+prefix_ typename senf::console::NodeCreateTraits<Object>::NodeType &
+senf::console::DirectoryNode::add(std::string const & name, Object const & ob)
+{
+ return NodeCreateTraits<Object>::Creator::create(*this, name, ob);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::SimpleCommandNode
+
+template <class Function>
+prefix_ senf::console::SimpleCommandNode & senf::console::
+senf_console_add_node(DirectoryNode & node, std::string const & name, Function const & fn, ...)
+{
+ return node.add(name, SimpleCommandNode::create(fn));
+}
+
+///////////////////////////////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:
#include <boost/enable_shared_from_this.hpp>
#include <boost/utility.hpp>
#include <boost/range/iterator_range.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/type_traits/remove_reference.hpp>
#include "../Utils/Exception.hh"
+#include "../Utils/mpl.hh"
#include "Parse.hh"
//#include "Node.mpp"
///////////////////////////////hh.p////////////////////////////////////////
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
namespace senf {
namespace console {
std::string const & name() const;
boost::shared_ptr<DirectoryNode> parent() const;
- bool managed() const;
std::string path() const;
+ ptr unlink();
+
+ bool active() const;
+
+ void help(std::ostream & output) const;
+
ptr thisptr();
cptr thisptr() const;
protected:
- explicit GenericNode(std::string const & name);
+ GenericNode();
void name(std::string const & name);
static void name(GenericNode & node, std::string const & name);
void parent(DirectoryNode * parent);
private:
+ virtual void v_help(std::ostream & output) const = 0;
+
std::string name_;
DirectoryNode * parent_;
friend class DirectoryNode;
};
+ class SimpleCommandNode;
+
+ template <class Object>
+ struct NodeCreateTraits
+ {
+ typedef BOOST_TYPEOF_TPL( senf_console_add_node(
+ * static_cast<DirectoryNode *>(0),
+ * static_cast<std::string const *>(0),
+ * static_cast<Object const *>(0),
+ 0) ) result_type;
+
+ typedef typename boost::remove_reference<result_type>::type NodeType;
+
+ struct Creator {
+ static NodeType & create(DirectoryNode & node, std::string const & name,
+ Object const & ob);
+ };
+ };
+
/** \brief
+ ///\fixme Provide a default name for added nodes if 'name' is empty ?
*/
class DirectoryNode : public GenericNode
{
typedef ChildMap::const_iterator child_iterator;
///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///\{
+
+ static std::auto_ptr<DirectoryNode> create();
+
+ ///\}
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Children
+ ///\{
+
+ template <class NodeType>
+ NodeType & add(std::string const & name, std::auto_ptr<NodeType> node);
+
+ template <class NodeType>
+ NodeType & add(std::string const & name, boost::shared_ptr<NodeType> node);
- GenericNode & add(std::auto_ptr<GenericNode> node, bool uniquify = true);
+ template <class Object>
+ typename NodeCreateTraits<Object>::NodeType & add (std::string const & name,
+ Object const & ob);
+
+ GenericNode::ptr remove(std::string const & name);
DirectoryNode & operator[](std::string const & name) const;
CommandNode & operator()(std::string const & name) const;
ChildrenRange children() const;
+ ///\}
+ ///////////////////////////////////////////////////////////////////////////
+
template <class ForwardRange>
GenericNode & traverse(ForwardRange const & range);
+ DirectoryNode & doc(std::string const & doc);
+
ptr thisptr();
cptr thisptr() const;
protected:
- explicit DirectoryNode(std::string const & name);
+ DirectoryNode();
private:
- void add(GenericNode::ptr node, bool uniquify);
+ void add(GenericNode::ptr node);
+ virtual void v_help(std::ostream & output) const;
ChildMap children_;
+ std::string doc_;
friend DirectoryNode & root();
};
- struct DuplicateNodeNameException : public senf::Exception
- { DuplicateNodeNameException() : senf::Exception("Duplicate node name") {}};
+ BOOST_TYPEOF_REGISTER_TYPE(DirectoryNode);
struct UnknownNodeNameException : public senf::Exception
{ UnknownNodeNameException() : senf::Exception("Unknown node name") {}};
+ // We need this specialization since we cannot passe auto_ptr via const & !!
+ template <class Type>
+ struct NodeCreateTraits< std::auto_ptr<Type> >
+ {};
+
+ template <class Type>
+ struct NodeCreateTraits< boost::shared_ptr<Type> >
+ {};
+
/** \brief
*/
class CommandNode : public GenericNode
typedef boost::shared_ptr<CommandNode const> cptr;
typedef boost::weak_ptr<CommandNode> weak_ptr;
+ typedef ParseCommandInfo::ArgumentsRange Arguments;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ virtual void operator()(std::ostream & output, Arguments const & arguments) = 0;
+
+ ptr thisptr();
+ cptr thisptr() const;
+
+ protected:
+ CommandNode();
+
+ private:
+ };
+
+ /** \brief
+ */
+ class SimpleCommandNode : public CommandNode
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ typedef boost::function<void (std::ostream &, Arguments const &)> Function;
+
///////////////////////////////////////////////////////////////////////////
- virtual void operator()(std::ostream & output,
- ParseCommandInfo::ArgumentsRange const & arguments) = 0;
+ virtual void operator()(std::ostream & output, Arguments const & arguments);
ptr thisptr();
cptr thisptr() const;
+ static std::auto_ptr<SimpleCommandNode> create(Function const & fn);
+
+ SimpleCommandNode & doc(std::string const & doc);
+
protected:
- explicit CommandNode(std::string const & name);
+ SimpleCommandNode(Function const & fn);
private:
+ virtual void v_help(std::ostream & output) const;
+ Function fn_;
+ std::string doc_;
};
+ template <class Function>
+ SimpleCommandNode & senf_console_add_node(DirectoryNode & node, std::string const & name,
+ Function const & fn, ...);
+
+ BOOST_TYPEOF_REGISTER_TYPE(SimpleCommandNode);
+
DirectoryNode & root();
}}
///////////////////////////////hh.e////////////////////////////////////////
#include "Node.cci"
#include "Node.ct"
-//#include "Node.cti"
+#include "Node.cti"
#endif
\f
--- /dev/null
+// $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 ObjectDirectory inline template implementation */
+
+//#include "ObjectDirectory.ih"
+
+// Custom includes
+#include <boost/bind.hpp>
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::OwnerNodeCreateTraits<Owner,Object>::Creator
+
+template <class Owner, class Object>
+prefix_ typename senf::console::OwnerNodeCreateTraits<Owner,Object>::NodeType &
+senf::console::OwnerNodeCreateTraits<Owner,Object>::Creator::create(DirectoryNode & node,
+ Owner & owner,
+ std::string const & name,
+ Object const & ob)
+{
+ return senf_console_add_node(node, owner, name, ob);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ObjectDirectory<Owner>
+
+template <class Owner>
+prefix_ senf::console::ObjectDirectory<Owner>::ObjectDirectory(Owner * owner)
+ : node_ (DirectoryNode::create().release()), owner_ (owner)
+{}
+
+template <class Owner>
+prefix_ senf::console::ObjectDirectory<Owner>::~ObjectDirectory()
+{
+ node_->unlink();
+}
+
+template <class Owner>
+template <class Object>
+prefix_ typename senf::console::OwnerNodeCreateTraits<Owner, Object>::NodeType &
+senf::console::ObjectDirectory<Owner>::add(std::string const & name, Object const & ob)
+{
+ return OwnerNodeCreateTraits<Owner, Object>::Creator::create(*node_, *owner_, name, ob);
+}
+
+template <class Owner>
+prefix_ senf::console::DirectoryNode & senf::console::ObjectDirectory<Owner>::node()
+ const
+{
+ return *node_;
+}
+
+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)
+{
+ return node.add(name,fn);
+}
+
+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 & output,
+ CommandNode::Arguments const & arguments))
+{
+ return node.add(name, boost::bind(fn,boost::ref(owner),_1,_2));
+}
+
+template <class Node>
+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<Node*, ObjectDirectoryBase*> >::type *)
+{
+ return dir.add(name, node.node().thisptr());
+}
+
+///////////////////////////////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:
--- /dev/null
+// $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 ObjectDirectory public header */
+
+#ifndef HH_ObjectDirectory_
+#define HH_ObjectDirectory_ 1
+
+// Custom includes
+#include <boost/utility.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include "Node.hh"
+
+//#include "ObjectDirectory.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+
+ template <class Owner, class Object>
+ struct OwnerNodeCreateTraits
+ {
+ typedef BOOST_TYPEOF_TPL( senf_console_add_node(
+ * static_cast<DirectoryNode *>(0),
+ * static_cast<Owner *>(0),
+ * static_cast<std::string const *>(0),
+ * static_cast<Object const *>(0)) ) result_type;
+
+ typedef typename boost::remove_reference<result_type>::type NodeType;
+
+ struct Creator {
+ static NodeType & create(DirectoryNode & node, Owner & owner,
+ std::string const & name, Object const & ob);
+ };
+ };
+
+ struct ObjectDirectoryBase {};
+
+ /** \brief
+ */
+ template <class Owner>
+ class ObjectDirectory : public ObjectDirectoryBase
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ typedef Owner owner;
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
+ ObjectDirectory(Owner * owner);
+ ~ObjectDirectory();
+
+ ///@}
+ ///////////////////////////////////////////////////////////////////////////
+
+ template <class Object>
+ typename OwnerNodeCreateTraits<Owner, Object>::NodeType & add(std::string const & name,
+ Object const & ob);
+
+ DirectoryNode & node() const;
+
+ protected:
+
+ private:
+ static SimpleCommandNode & create(DirectoryNode & node, Owner * owner,
+ std::string const & name,
+ SimpleCommandNode::Function const & fn);
+
+ DirectoryNode::ptr node_;
+ Owner * owner_;
+ };
+
+ template <class Owner, class Function>
+ SimpleCommandNode & senf_console_add_node(
+ 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 & output, CommandNode::Arguments const & arguments));
+
+ template <class Node>
+ DirectoryNode & senf_console_add_node(
+ DirectoryNode & dir, std::string const & name, Node const & node, int,
+ typename boost::enable_if< boost::is_convertible<Node*, ObjectDirectoryBase*> >::type * = 0);
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "ObjectDirectory.cci"
+//#include "ObjectDirectory.ct"
+#include "ObjectDirectory.cti"
+#endif
+
+\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:
--- /dev/null
+// $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 ObjectDirectory.test unit tests */
+
+//#include "ObjectDirectory.test.hh"
+//#include "ObjectDirectory.test.ih"
+
+// Custom includes
+#include "ObjectDirectory.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(ownerDirectory)
+{}
+
+///////////////////////////////cc.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:
ParserAccess::setBuiltin(info_, ParseCommandInfo::BuiltinEXIT);
ParserAccess::finalize(info_); cb_(info_); }
+ void builtin_help(std::vector<std::string> & path)
+ { ParserAccess::init(info_);
+ ParserAccess::setBuiltin(info_, ParseCommandInfo::BuiltinHELP);
+ setBuiltinPathArg(path);
+ ParserAccess::finalize(info_); cb_(info_); }
+
void setBuiltinPathArg(std::vector<std::string> & path)
{
ParserAccess::startArgument(info_);
if (info.builtin() == ParseCommandInfo::NoBuiltin)
stream << senf::stringJoin(info.commandPath(), "/");
else {
- char const * builtins[] = { "", "cd", "ls", "pushd", "popd", "exit" };
+ char const * builtins[] = { "", "cd", "ls", "pushd", "popd", "exit", "help" };
stream << "builtin-" << builtins[info.builtin()];
}
BuiltinLS,
BuiltinPUSHD,
BuiltinPOPD,
- BuiltinEXIT };
+ BuiltinEXIT,
+ BuiltinHELP };
BuiltinCommand builtin() const;
CommandPathRange commandPath() const;
>> path
>> eps_p [ self.dispatch(&PD::builtin_cd,
boost::ref(self.context.path)) ]
- | keyword_p("ls")
+ | keyword_p("ls")
>> ! path
>> eps_p [ self.dispatch(&PD::builtin_ls,
boost::ref(self.context.path)) ]
| keyword_p("exit") [ self.dispatch(&PD::builtin_exit) ]
+
+ | keyword_p("help")
+ >> ! path
+ >> eps_p [ self.dispatch(&PD::builtin_help,
+ boost::ref(self.context.path)) ]
;
block
{ os_ << "builtin_cd( " << senf::stringJoin(path, "/") << " )\n"; }
void builtin_exit()
{ os_ << "builtin_exit()\n"; }
+ void builtin_help(std::vector<std::string> const & path)
+ { os_ << "builtin_help( " << senf::stringJoin(path, "/") << " )\n"; }
};
}
return;
}
- ///\fixme Fix Client::clientData implementation
- /// Remove the 'dup' needed here so we don't close the same fd twice (see Client constructor)
- /// Make output non-blocking
- /// Don't register a new ReadHelper every round
-
std::string data (tail_ + helper->data());
tail_ = helper->tail();
boost::trim(data); // Gets rid of superfluous \r or \n characters
class Client;
/** \brief
+ ///\fixme Use special non-blocking streambuf
*/
class Server
: boost::noncopyable
};
/** \brief
+
+ \fixme Fix Client::clientData implementation
+ Remove the 'dup' needed here so we don't close the same fd twice (see Client constructor)
+ Make output non-blocking
+ Don't register a new ReadHelper every round
*/
class Client
: public senf::intrusive_refcount
#include <iostream>
#include "Server.hh"
#include "Node.hh"
+#include "ObjectDirectory.hh"
#include "../Scheduler/Scheduler.hh"
#include "../Utils/Logger/SenfLog.hh"
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- struct MyCommand : public senf::console::CommandNode
+
+ void fn(std::ostream & output,
+ senf::console::CommandNode::Arguments const & arguments) {
+ senf::console::CommandNode::Arguments::iterator i (arguments.begin());
+ senf::console::CommandNode::Arguments::iterator i_end (arguments.end());
+ for (; i != i_end; ++i) {
+ senf::console::CommandNode::Arguments::value_type::iterator j (i->begin());
+ senf::console::CommandNode::Arguments::value_type::iterator j_end (i->end());
+ for (; j != j_end; ++j)
+ output << j->value() << ' ';
+ }
+ output << "\n";
+ }
+
+ struct TestObject
{
- MyCommand(std::string name) : senf::console::CommandNode(name) {}
- void operator()(std::ostream & output,
- senf::console::ParseCommandInfo::ArgumentsRange const & arguments) {
- senf::console::ParseCommandInfo::argument_iterator i (arguments.begin());
- senf::console::ParseCommandInfo::argument_iterator i_end (arguments.end());
- for (; i != i_end; ++i) {
- senf::console::ParseCommandInfo::token_iterator j (i->begin());
- senf::console::ParseCommandInfo::token_iterator j_end (i->end());
- for (; j != j_end; ++j)
- output << j->value() << ' ';
- }
- output << "\n";
+ senf::console::ObjectDirectory<TestObject> dir;
+
+ TestObject() : dir(this) {
+ dir.add("blub", &TestObject::blub)
+ .doc("Example of a member function");
+ }
+
+ void blub(std::ostream & output, senf::console::CommandNode::Arguments const & args) {
+ output << "blub\n";
}
};
+
}
int main(int, char const **)
{
senf::log::ConsoleTarget::instance().route< senf::SenfLog, senf::log::NOTICE >();
- senf::console::root().mkdir("network").mkdir("eth0");
+ senf::console::root().doc("This is the console test application");
+ senf::console::root().mkdir("network")
+ .doc("Network related settings");
+ senf::console::root()["network"].mkdir("eth0")
+ .doc("Ethernet device eth0");
senf::console::root().mkdir("server");
+ senf::console::root()["network"].add("route", &fn)
+ .doc("Example of a directly registered function");
- senf::console::root()["network"].add(
- std::auto_ptr<senf::console::GenericNode>(new MyCommand("route")));
+ TestObject test;
+ senf::console::root().add("testob", test.dir)
+ .doc("Example of an instance directory");
senf::console::Server::start( senf::INet4SocketAddress("127.0.0.1:23232") )
.name("testServer");