Utils: Document new utilities
[senf.git] / Console / Node.cci
index 5f824bd..242881f 100644 (file)
@@ -23,7 +23,7 @@
 /** \file
     \brief Node inline non-template implementation */
 
-//#include "Node.ih"
+#include "Node.ih"
 
 // Custom includes
 #include "../Utils/senfassert.hh"
@@ -84,6 +84,57 @@ prefix_ senf::console::GenericNode::cptr senf::console::GenericNode::thisptr()
     return shared_from_this();
 }
 
+prefix_ bool senf::console::GenericNode::operator==(GenericNode & other)
+    const
+{
+    return this == & other;
+}
+
+prefix_ bool senf::console::GenericNode::operator!=(GenericNode & other)
+    const
+{
+    return this != & other;
+}
+
+prefix_ bool senf::console::GenericNode::isDirectory()
+    const
+{
+    return dynamic_cast<DirectoryNode const *>(this);
+}
+
+prefix_ bool senf::console::GenericNode::isLink()
+    const
+{
+    return dynamic_cast<LinkNode const *>(this);
+}
+
+prefix_ bool senf::console::GenericNode::isCommand()
+    const
+{
+    return dynamic_cast<CommandNode const *>(this);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::LinkNode
+
+prefix_ senf::console::LinkNode::ptr senf::console::LinkNode::create(GenericNode & node)
+{
+    GenericNode::ptr p (node.thisptr());
+    while ( p->isLink() )
+        p = dynamic_cast<LinkNode&>(*p).follow().thisptr();
+    return ptr(new LinkNode(*p));
+}
+
+prefix_ senf::console::GenericNode & senf::console::LinkNode::follow()
+    const
+{
+    return *node_;
+}
+
+prefix_ senf::console::LinkNode::LinkNode(GenericNode & node)
+    : node_ (node.thisptr())
+{}
+
 ///////////////////////////////////////////////////////////////////////////
 // senf::console::DirectoryNode
 
@@ -92,18 +143,55 @@ prefix_ senf::console::DirectoryNode::ptr senf::console::DirectoryNode::create()
     return ptr(new DirectoryNode());
 }
 
+prefix_ bool senf::console::DirectoryNode::hasChild(std::string const & name)
+    const
+{
+    ChildMap::const_iterator i (children_.find(name));
+    return i != children_.end();
+}
+
+prefix_ senf::console::GenericNode &
+senf::console::DirectoryNode::get(std::string const & name)
+    const
+{
+    GenericNode & node (getLink(name));
+    return node.isLink()
+        ? dynamic_cast<LinkNode&>(node).follow()
+        : node;
+}
+
+prefix_ senf::console::DirectoryNode &
+senf::console::DirectoryNode::getDirectory(std::string const & name)
+    const
+{
+    try {
+        return dynamic_cast<DirectoryNode&>(get(name));
+    }
+    SENF_WRAP_EXC(std::bad_cast)
+}
+
 prefix_ senf::console::DirectoryNode &
 senf::console::DirectoryNode::operator[](std::string const & name)
     const
 {
-    return dynamic_cast<DirectoryNode&>(get(name));
+    return getDirectory(name);
+}
+
+prefix_ senf::console::CommandNode &
+senf::console::DirectoryNode::getCommand(std::string const & name)
+    const
+{
+    try {
+        return dynamic_cast<CommandNode&>(get(name));
+    }
+    SENF_WRAP_EXC(std::bad_cast)
 }
 
 prefix_ senf::console::CommandNode &
 senf::console::DirectoryNode::operator()(std::string const & name)
     const
 {
-    return dynamic_cast<CommandNode&>(get(name));
+    return getCommand(name);
 }
 
 prefix_ senf::console::DirectoryNode &
@@ -118,6 +206,19 @@ prefix_ senf::console::DirectoryNode::ChildrenRange senf::console::DirectoryNode
     return boost::make_iterator_range(children_.begin(), children_.end());
 }
 
+prefix_ senf::console::DirectoryNode::ChildrenRange
+senf::console::DirectoryNode::completions(std::string const & s)
+    const
+{
+    return boost::make_iterator_range(children_.lower_bound(s),
+                                      children_.lower_bound(s + "\xff"));
+}
+
+prefix_ void senf::console::DirectoryNode::link(std::string const & name, GenericNode & target)
+{
+    add(name, LinkNode::create(target));
+}
+
 prefix_ senf::console::DirectoryNode::DirectoryNode()
 {}
 
@@ -140,12 +241,31 @@ prefix_ senf::console::DirectoryNode::cptr senf::console::DirectoryNode::thisptr
 }
 
 ///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::NodeTraverser
+
+prefix_ senf::console::detail::NodeTraverser::NodeTraverser(DirectoryNode & root,
+                                                            DirectoryNode & dir,
+                                                            bool autocomplete)
+    : root_ (root), dir_ (dir.thisptr()), autocomplete_ (autocomplete), init_ (false)
+{}
+
+///////////////////////////////////////////////////////////////////////////
 // senf::console::SyntaxErrorException
 
 prefix_ senf::console::SyntaxErrorException::SyntaxErrorException(std::string const & msg)
-    : Exception(msg)
+    : message_(msg)
+{}
+
+prefix_ senf::console::SyntaxErrorException::~SyntaxErrorException()
+    throw()
 {}
 
+prefix_ std::string const & senf::console::SyntaxErrorException::message()
+    const
+{
+    return message_;
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // senf::console::CommandNode
 
@@ -163,11 +283,18 @@ prefix_ senf::console::CommandNode::cptr senf::console::CommandNode::thisptr()
 prefix_ senf::console::CommandNode::CommandNode()
 {}
 
+prefix_ void senf::console::CommandNode::execute(std::ostream & output,
+                                                 ParseCommandInfo const & command)
+    const
+{
+    v_execute(output, command);
+}
+
 prefix_ void senf::console::CommandNode::operator()(std::ostream & output,
-                                                    Arguments const & arguments)
+                                                    ParseCommandInfo const & command)
     const
 {
-    v_execute(output, arguments);
+    execute(output, command);
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -201,6 +328,17 @@ prefix_ senf::console::SimpleCommandNode::cptr senf::console::SimpleCommandNode:
     return boost::static_pointer_cast<SimpleCommandNode const>(shared_from_this());
 }
 
+#ifndef DOXYGEN
+
+prefix_ senf::console::SimpleCommandNode &
+senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
+                                     SimpleCommandNode::Function fn, int)
+{
+    return node.add(name, SimpleCommandNode::create(fn));
+}
+
+#endif
+
 ///////////////////////////////cci.e///////////////////////////////////////
 #undef prefix_