X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FExecutor.cc;h=3533a0e5061462985b8cdf108602d7ed87aa05aa;hb=456ee576285b76aa46240f8001f426757810dcc1;hp=7e1676551ef2c34f1861e48ab5fa0e871ed229ab;hpb=9ff18548815d10140e83fba6ed2d573fe556c346;p=senf.git diff --git a/Console/Executor.cc b/Console/Executor.cc index 7e16765..3533a0e 100644 --- a/Console/Executor.cc +++ b/Console/Executor.cc @@ -46,42 +46,52 @@ namespace { /////////////////////////////////////////////////////////////////////////// // 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 )); - ///\fixme Whenever checking cwd_.expired(), we also need to check, wether - /// the node is still connected to the root. - if (cwd_.expired()) - cwd_ = root().thisptr(); + if (cwd_.expired() || ! cwd().active()) + cwd_ = root_; try { switch(command.builtin()) { - case ParseCommandInfo::NoBuiltin : - traverseToCommand(command.commandPath())(output, command.arguments()); + case ParseCommandInfo::NoBuiltin : { + GenericNode & node ( traverseCommand(command.commandPath()) ); + DirectoryNode * dir ( dynamic_cast(&node) ); + if ( dir ) { + if (autocd_ && command.tokens().empty()) { + 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()) { + if (oldCwd_.expired() || ! oldCwd_.lock()->active()) { oldCwd_ = cwd_; - cwd_ = root().thisptr(); + cwd_ = root_; } else swap(cwd_, oldCwd_); } else { oldCwd_ = cwd_; - cwd_ = traverseTo(command.arguments().begin()[0]).thisptr(); + cwd_ = traverseDirectory(*command.arguments().begin()).thisptr(); } } break; case ParseCommandInfo::BuiltinLS : { - DirectoryNode const & dir ( - command.arguments().empty() ? cwd() : traverseTo(command.arguments().begin()[0])); + DirectoryNode const & dir ( command.arguments() + ? traverseDirectory(*command.arguments().begin()) + : cwd() ); for (DirectoryNode::child_iterator i (dir.children().begin()); i != dir.children().end(); ++i) { output << i->first; @@ -95,7 +105,7 @@ prefix_ bool senf::console::Executor::operator()(ParseCommandInfo const & comman case ParseCommandInfo::BuiltinPUSHD : dirstack_.push_back(cwd_); if ( command.arguments() ) - cwd_ = traverseTo(command.arguments().begin()[0]).thisptr(); + cwd_ = traverseDirectory(*command.arguments().begin()).thisptr(); break; case ParseCommandInfo::BuiltinPOPD : @@ -107,49 +117,76 @@ prefix_ bool senf::console::Executor::operator()(ParseCommandInfo const & comman case ParseCommandInfo::BuiltinEXIT : throw ExitException(); + + case ParseCommandInfo::BuiltinHELP : + GenericNode const & node (command.arguments() + ? traverseNode(*command.arguments().begin()) + : cwd()); + output << prettyName(typeid(node)) << " at " << node.path() << "\n\n"; + node.help(output); + output << std::flush; + break; + } } + catch (InvalidPathException &) { + output << "invalid path" << std::endl; + } catch (InvalidDirectoryException &) { output << "invalid directory" << std::endl; } catch (InvalidCommandException &) { output << "invalid command" << std::endl; } - return true; + catch (IgnoreCommandException &) {} } -prefix_ senf::console::DirectoryNode & -senf::console::Executor::traverseTo (ParseCommandInfo::argument_value_type const & path) +prefix_ senf::console::GenericNode & +senf::console::Executor::traverseNode(ParseCommandInfo::TokensRange 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())))); + return traverse( + cwd(), + boost::make_iterator_range( + boost::make_transform_iterator(path.begin(), TraverseTokens()), + boost::make_transform_iterator(path.end(), TraverseTokens())) ); } catch (std::bad_cast &) { - throw InvalidDirectoryException(); + throw InvalidPathException(); } catch (UnknownNodeNameException &) { - throw InvalidDirectoryException(); + throw InvalidPathException(); } } -prefix_ senf::console::CommandNode & -senf::console::Executor::traverseToCommand(ParseCommandInfo::CommandPathRange const & path) +prefix_ senf::console::GenericNode & +senf::console::Executor::traverseCommand(ParseCommandInfo::CommandPathRange const & path) { try { - return dynamic_cast( cwd().traverse(path) ); + return traverse(cwd(), path); } catch (std::bad_cast &) { - throw InvalidCommandException(); + throw InvalidPathException(); } catch (UnknownNodeNameException &) { - throw InvalidCommandException(); - } + throw InvalidPathException(); + } } - + +prefix_ senf::console::DirectoryNode & +senf::console::Executor::traverseDirectory(ParseCommandInfo::TokensRange 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"