X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FExecutor.cc;h=a7db590ddb29f3a7e6ad9ed676629905522acc52;hb=1b1d76302a5d61e918ef71f1c8e11f80ac1262e2;hp=43fc6d24c4124542d64944c004d88f981998fc47;hpb=31fb20bd535cd2d65595a7d37bd100ff16f13df8;p=senf.git diff --git a/Console/Executor.cc b/Console/Executor.cc index 43fc6d2..a7db590 100644 --- a/Console/Executor.cc +++ b/Console/Executor.cc @@ -32,106 +32,160 @@ #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) +prefix_ void senf::console::Executor::execute(std::ostream & output, + ParseCommandInfo const & command) { SENF_LOG(( "Executing: " << command )); - if (cwd_.expired()) - cwd_ = boost::static_pointer_cast( - root().shared_from_this()); - - switch(command.builtin()) { - case ParseCommandInfo::NoBuiltin : - break; - - case ParseCommandInfo::BuiltinCD : - if ( command.arguments() && - ! chdir(command.arguments().begin()[0]) ) - output << "invalid directory\n"; - break; - - case ParseCommandInfo::BuiltinLS : - for (DirectoryNode::child_iterator i (cwd().children().begin()); - i != cwd().children().end(); ++i) { - output << i->first; - try { - (void) cwd()(i->first); + if (cwd_.expired() || ! cwd().active()) + cwd_ = root().thisptr(); + + try { + switch(command.builtin()) { + case ParseCommandInfo::NoBuiltin : { + GenericNode & node ( traverseCommand(command.commandPath()) ); + DirectoryNode * dir ( dynamic_cast(&node) ); + if ( dir ) { + if (autocd_) { + oldCwd_ = cwd_; + cwd_ = dir->thisptr(); + } else + throw InvalidCommandException(); + } else { + dynamic_cast(node)(output, command); + } + 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_ = traverseDirectory(command.arguments().begin()[0]).thisptr(); + } } - catch (std::bad_cast &) { - output << "/"; + break; + + case ParseCommandInfo::BuiltinLS : { + DirectoryNode const & dir ( command.arguments() + ? traverseDirectory(command.arguments().begin()[0]) + : cwd() ); + 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"; } - output << "\n"; + break; } - break; - - case ParseCommandInfo::BuiltinPUSHD : - dirstack_.push_back(cwd_); - if ( command.arguments() - && ! chdir(command.arguments().begin()[0]) ) - output << "invalid directory\n"; - break; - - case ParseCommandInfo::BuiltinPOPD : - if (! dirstack_.empty()) { - cwd_ = dirstack_.back(); - dirstack_.pop_back(); + + case ParseCommandInfo::BuiltinPUSHD : + dirstack_.push_back(cwd_); + if ( command.arguments() ) + cwd_ = traverseDirectory(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 : + GenericNode const & node (command.arguments() + ? traverseNode(command.arguments().begin()[0]) + : cwd()); + output << prettyName(typeid(node)) << " at " << node.path() << "\n\n"; + node.help(output); + output << std::flush; + break; + } - break; + } + catch (InvalidPathException &) { + output << "invalid path" << std::endl; + } + catch (InvalidDirectoryException &) { + output << "invalid directory" << std::endl; + } + catch (InvalidCommandException &) { + output << "invalid command" << std::endl; + } +} - case ParseCommandInfo::BuiltinEXIT : - throw ExitException(); +prefix_ senf::console::GenericNode & +senf::console::Executor::traverseNode(ParseCommandInfo::argument_value_type const & path) +{ + try { + return cwd().traverse( + boost::make_iterator_range( + boost::make_transform_iterator(path.begin(), TraverseTokens()), + boost::make_transform_iterator(path.end(), TraverseTokens())), + autocomplete_); + } + catch (std::bad_cast &) { + throw InvalidPathException(); + } + catch (UnknownNodeNameException &) { + throw InvalidPathException(); } - return true; } -prefix_ bool senf::console::Executor::chdir(ParseCommandInfo::argument_value_type const & path) +prefix_ senf::console::GenericNode & +senf::console::Executor::traverseCommand(ParseCommandInfo::CommandPathRange const & path) { - if (path.size() == 1 && path.begin()->value() == "-") { - if (oldCwd_.expired()) { - oldCwd_ = cwd_; - cwd_ = boost::static_pointer_cast( - root().shared_from_this()); - } else - swap(cwd_, oldCwd_); + try { + return cwd().traverse(path, autocomplete_); } - else { - try { - DirectoryNode::ptr dir (cwd_.lock()); - ParseCommandInfo::token_iterator i (path.begin()); - ParseCommandInfo::token_iterator const i_end (path.end()); - if (i != i_end && i->value().empty()) { - dir = boost::static_pointer_cast( - root().shared_from_this()); - ++ i; - } - for (; i != i_end; ++i) { - if (i->value() == "..") { - dir = dir->parent(); - if (! dir) - dir = boost::static_pointer_cast( - root().shared_from_this()); - } - else if (! i->value().empty() && i->value() != ".") - dir = boost::static_pointer_cast( - (*dir)[i->value()].shared_from_this()); - } - oldCwd_ = cwd_; - cwd_ = dir; - } - catch (std::bad_cast &) { - return false; - } - catch (UnknownNodeNameException &) { - return false; - } + catch (std::bad_cast &) { + throw InvalidPathException(); + } + catch (UnknownNodeNameException &) { + throw InvalidPathException(); } - return true; } - + +prefix_ senf::console::DirectoryNode & +senf::console::Executor::traverseDirectory(ParseCommandInfo::argument_value_type const & path) +{ + try { + return dynamic_cast( traverseNode(path) ); + } + catch (std::bad_cast &) { + throw InvalidDirectoryException(); + } + catch (InvalidPathException &) { + throw InvalidDirectoryException(); + } +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Executor.mpp"