Utils: Add unit-test and documentation for type_traits.hh
[senf.git] / Console / Node.cc
index 964eb22..4886b77 100644 (file)
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
+prefix_ senf::console::DirectoryNode & senf::console::root()
+{
+    static DirectoryNode::ptr rootNode(new DirectoryNode());
+    return *rootNode;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::GenericNode
+
+prefix_ std::string senf::console::GenericNode::path()
+    const
+{
+    std::string path (name());
+    ptr node (parent());
+    while (node) {
+        path = node->name() + "/" + path;
+        node = node->parent();
+    }
+    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);
+    node->parent_ = 0;
+    node->name_.clear();
+    return node;
+}
+
+prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node)
+{
+    BOOST_ASSERT( ! node->parent() );
+    if (node->name().empty()) {
+        node->name("unnamed");
+        SENF_LOG((senf::log::MESSAGE)("Adding 'unnamed' node"));
+    }
     if (children_.find(node->name()) != children_.end()) {
-        if (! uniquify)
-            throw DuplicateNodeNameException() << ": '" << node->name() << "'";
         unsigned suffix (0);
         std::string newName;
         do {
             ++suffix;
-            newName = node->name() + boost::lexical_cast<std::string>(suffix);
+            newName = node->name() + "-" + boost::lexical_cast<std::string>(suffix);
         } while (children_.find(newName) != children_.end());
-        name(*node, newName);
+        SENF_LOG((senf::log::MESSAGE)("Uniquifying node '" << node->name() << "' to '" 
+                                      << newName << "'"));
+        node->name(newName);
     }
     children_.insert(std::make_pair(node->name(),node));
+    node->parent_ = this;
 }
 
 prefix_ senf::console::GenericNode &
-senf::console::DirectoryNode::lookup(std::string const & name)
+senf::console::DirectoryNode::get(std::string const & name)
     const
 {
     ChildMap::const_iterator i (children_.find(name));
@@ -61,6 +110,37 @@ senf::console::DirectoryNode::lookup(std::string const & name)
     return *(i->second);
 }
 
+prefix_ void senf::console::DirectoryNode::v_help(std::ostream & output)
+    const
+{
+    output << doc_ << "\n";
+}
+
+///////////////////////////////////////////////////////////////////////////
+// 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)
+    const
+{
+    output << doc_ << "\n";
+}
+
+prefix_ void senf::console::SimpleCommandNode::v_execute(std::ostream & output,
+                                                         ParseCommandInfo const & command)
+    const
+{
+    fn_(output, command);
+}
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 //#include "Node.mpp"