X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FExecutor.cc;h=b808a09b08b24b98d39141251ea7176781e96797;hb=9c0078ac0054789badff2a987364ed0448b080ef;hp=0a9285a0ca64426dcf2e019e3cdfa3a01a32ab7a;hpb=826e50343096b75247521f6593cb78eb8c01615b;p=senf.git diff --git a/Console/Executor.cc b/Console/Executor.cc index 0a9285a..b808a09 100644 --- a/Console/Executor.cc +++ b/Console/Executor.cc @@ -32,17 +32,139 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +namespace { + + struct TraverseTokens { + typedef std::string const & result_type; + result_type operator()(senf::console::ArgumentToken const & token) const { + return token.value(); + } + }; + +} + /////////////////////////////////////////////////////////////////////////// // senf::console::Executor prefix_ bool senf::console::Executor::operator()(ParseCommandInfo const & command, std::ostream & output) { -# warning Implement Executor::operator() - SENF_LOG(( "Executing '" << command.commandPath() << "'" )); + SENF_LOG(( "Executing: " << command )); + + if (cwd_.expired() || ! cwd().active()) + cwd_ = root().thisptr(); + + try { + switch(command.builtin()) { + case ParseCommandInfo::NoBuiltin : + traverseToCommand(command.commandPath())(output, command.arguments()); + break; + + case ParseCommandInfo::BuiltinCD : + if ( command.arguments() ) { + if (command.arguments().begin()->size() == 1 + && command.arguments().begin()->begin()->value() == "-") { + if (oldCwd_.expired() || ! oldCwd_.lock()->active()) { + oldCwd_ = cwd_; + cwd_ = root().thisptr(); + } else + swap(cwd_, oldCwd_); + } + else { + oldCwd_ = cwd_; + cwd_ = traverseTo(command.arguments().begin()[0]).thisptr(); + } + } + break; + + case ParseCommandInfo::BuiltinLS : { + DirectoryNode const & dir ( + command.arguments().empty() ? cwd() : traverseTo(command.arguments().begin()[0])); + for (DirectoryNode::child_iterator i (dir.children().begin()); + i != dir.children().end(); ++i) { + output << i->first; + if (boost::dynamic_pointer_cast(i->second)) + output << "/"; + output << "\n"; + } + break; + } + + case ParseCommandInfo::BuiltinPUSHD : + dirstack_.push_back(cwd_); + if ( command.arguments() ) + cwd_ = traverseTo(command.arguments().begin()[0]).thisptr(); + break; + + case ParseCommandInfo::BuiltinPOPD : + if (! dirstack_.empty()) { + cwd_ = dirstack_.back(); + dirstack_.pop_back(); + } + break; + + 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 &) { + output << "invalid directory" << std::endl; + } + catch (InvalidCommandException &) { + output << "invalid command" << std::endl; + } return true; } +prefix_ senf::console::DirectoryNode & +senf::console::Executor::traverseTo (ParseCommandInfo::argument_value_type const & path) +{ + try { + return dynamic_cast( + cwd().traverse( + boost::make_iterator_range( + boost::make_transform_iterator(path.begin(), TraverseTokens()), + boost::make_transform_iterator(path.end(), TraverseTokens())))); + } + catch (std::bad_cast &) { + throw InvalidDirectoryException(); + } + catch (UnknownNodeNameException &) { + throw InvalidDirectoryException(); + } +} + +prefix_ senf::console::CommandNode & +senf::console::Executor::traverseToCommand(ParseCommandInfo::CommandPathRange const & path) +{ + try { + return dynamic_cast( cwd().traverse(path) ); + } + catch (std::bad_cast &) { + throw InvalidCommandException(); + } + catch (UnknownNodeNameException &) { + throw InvalidCommandException(); + } +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Executor.mpp"