X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FNode.cc;h=42086bb05ed568ba87b6b9a3cb0c68627dfa0a96;hb=9e7071473642404359c8b7a88c78fe02f00baf16;hp=f21ab663d86249d8bcb6bc8c46db46b5eecf7486;hpb=9c0078ac0054789badff2a987364ed0448b080ef;p=senf.git diff --git a/Console/Node.cc b/Console/Node.cc index f21ab66..42086bb 100644 --- a/Console/Node.cc +++ b/Console/Node.cc @@ -24,7 +24,7 @@ \brief Node non-inline non-template implementation */ #include "Node.hh" -//#include "Node.ih" +#include "Node.ih" // Custom includes @@ -53,6 +53,23 @@ prefix_ std::string senf::console::GenericNode::path() return path.empty() ? "/" : path; } +prefix_ std::string senf::console::GenericNode::path(DirectoryNode const & root) + const +{ + std::string path; + cptr node (thisptr()); + while (node && node != root.thisptr()) { + if (! path.empty()) + path = node->name() + "/" + path; + else + path = node->name(); + node = node->parent(); + } + if (path.empty() || path[0] != '/') + path = "/" + path; + return path; +} + prefix_ bool senf::console::GenericNode::active() const { @@ -62,6 +79,25 @@ prefix_ bool senf::console::GenericNode::active() return node == root().thisptr(); } +prefix_ bool senf::console::GenericNode::isChildOf(DirectoryNode & parent) + const +{ + cptr node (thisptr()); + while (node && node != parent.thisptr()) + node = node->parent(); + return node; +} + +/////////////////////////////////////////////////////////////////////////// +// senf::console::LinkNode + +prefix_ void senf::console::LinkNode::v_help(std::ostream & os) + const +{ + os << "link to "; + follow().help(os); +} + /////////////////////////////////////////////////////////////////////////// //senf::console::DirectoryNode @@ -73,27 +109,35 @@ senf::console::DirectoryNode::remove(std::string const & name) 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()) { unsigned suffix (0); std::string newName; do { ++suffix; - newName = node->name() + boost::lexical_cast(suffix); + newName = node->name() + "-" + boost::lexical_cast(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::get(std::string const & name) +senf::console::DirectoryNode::getLink(std::string const & name) const { ChildMap::const_iterator i (children_.find(name)); @@ -109,6 +153,62 @@ prefix_ void senf::console::DirectoryNode::v_help(std::ostream & output) } /////////////////////////////////////////////////////////////////////////// +// senf::console::detail::NodeTraverser + +prefix_ void senf::console::detail::NodeTraverser::operator()(std::string const & name) +{ + if (! init_) { + init_ = true; + if (name == std::string("")) { + dir_ = root_.thisptr(); + return; + } + } + if (! elt_.empty()) { + if (elt_ == "..") { + dir_ = dir_->parent(); + if (! dir_ || ! dir_->isChildOf(root_)) + dir_ = root_.thisptr(); + } + else if (elt_ != "" && elt_ != ".") { + if (! dir_->hasChild(elt_) && autocomplete_) { + DirectoryNode::ChildrenRange completions (dir_->completions(elt_)); + if (completions.size() == 1) + elt_ = completions.begin()->first; + } + // Why does g++ give an error on this line ???? : + // dir = dynamic_cast( dir->get(name) ).thisptr(); + DirectoryNode & d (dynamic_cast( dir_->get(elt_) )); + dir_ = d.thisptr(); + } + } + elt_ = name; +} + +prefix_ senf::console::GenericNode & senf::console::detail::NodeTraverser::node() +{ + if (elt_ != "" && elt_ != ".") { + if (! dir_->hasChild(elt_) && autocomplete_) { + DirectoryNode::ChildrenRange completions (dir_->completions(elt_)); + if (completions.size() == 1) + elt_ = completions.begin()->first; + } + return dir_->get(elt_); + } + else + return * dir_; +} + +/////////////////////////////////////////////////////////////////////////// +// 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) @@ -117,6 +217,13 @@ prefix_ void senf::console::SimpleCommandNode::v_help(std::ostream & output) 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"