From: g0dil Date: Mon, 28 Apr 2008 23:13:49 +0000 (+0000) Subject: Console: Add console routing to testServer example X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=706fe01937df3649e40aed24b75c3d28fc4fa007;p=senf.git Console: Add console routing to testServer example Console: Remove backtrace from syntax error messages Console: auto-cd when specifying a directory as command git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@826 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Console/Executor.cc b/Console/Executor.cc index 5e4b6f2..da8aa49 100644 --- a/Console/Executor.cc +++ b/Console/Executor.cc @@ -56,9 +56,17 @@ prefix_ void senf::console::Executor::execute(std::ostream & output, try { switch(command.builtin()) { - case ParseCommandInfo::NoBuiltin : - traverseCommand(command.commandPath())(output, command); + case ParseCommandInfo::NoBuiltin : { + GenericNode & node ( traverseCommand(command.commandPath()) ); + DirectoryNode * dir ( dynamic_cast(&node) ); + if ( dir ) { + oldCwd_ = cwd_; + cwd_ = dir->thisptr(); + } else { + dynamic_cast(node)(output, command); + } break; + } case ParseCommandInfo::BuiltinCD : if ( command.arguments() ) { @@ -146,34 +154,34 @@ senf::console::Executor::traverseNode(ParseCommandInfo::argument_value_type cons } } -prefix_ senf::console::DirectoryNode & -senf::console::Executor::traverseDirectory(ParseCommandInfo::argument_value_type const & path) +prefix_ senf::console::GenericNode & +senf::console::Executor::traverseCommand(ParseCommandInfo::CommandPathRange const & path) { try { - return dynamic_cast( traverseNode(path) ); + return cwd().traverse(path); } catch (std::bad_cast &) { - throw InvalidDirectoryException(); + throw InvalidPathException(); } - catch (InvalidPathException &) { - throw InvalidDirectoryException(); + catch (UnknownNodeNameException &) { + throw InvalidPathException(); } } -prefix_ senf::console::CommandNode & -senf::console::Executor::traverseCommand(ParseCommandInfo::CommandPathRange const & path) +prefix_ senf::console::DirectoryNode & +senf::console::Executor::traverseDirectory(ParseCommandInfo::argument_value_type const & path) { try { - return dynamic_cast( cwd().traverse(path) ); + return dynamic_cast( traverseNode(path) ); } catch (std::bad_cast &) { - throw InvalidCommandException(); + throw InvalidDirectoryException(); + } + catch (InvalidPathException &) { + throw InvalidDirectoryException(); } - catch (UnknownNodeNameException &) { - throw InvalidCommandException(); - } } - + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Executor.mpp" diff --git a/Console/Executor.hh b/Console/Executor.hh index 81dafd9..441c3d7 100644 --- a/Console/Executor.hh +++ b/Console/Executor.hh @@ -90,8 +90,8 @@ namespace console { private: GenericNode & traverseNode(ParseCommandInfo::argument_value_type const & path); + GenericNode & traverseCommand(ParseCommandInfo::CommandPathRange const & path); DirectoryNode & traverseDirectory(ParseCommandInfo::argument_value_type const & path); - CommandNode & traverseCommand(ParseCommandInfo::CommandPathRange const & path); struct InvalidPathException {}; struct InvalidDirectoryException {}; diff --git a/Console/Node.cci b/Console/Node.cci index 6f24e9c..c0d76bc 100644 --- a/Console/Node.cci +++ b/Console/Node.cci @@ -170,9 +170,19 @@ prefix_ senf::console::DirectoryNode::cptr senf::console::DirectoryNode::thisptr // senf::console::SyntaxErrorException prefix_ senf::console::SyntaxErrorException::SyntaxErrorException(std::string const & msg) - : Exception(msg) + : message_(msg) {} +prefix_ senf::console::SyntaxErrorException::~SyntaxErrorException() + throw() +{} + +prefix_ std::string const & senf::console::SyntaxErrorException::message() + const +{ + return message_; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::CommandNode diff --git a/Console/Node.hh b/Console/Node.hh index 6a2732c..a93c23c 100644 --- a/Console/Node.hh +++ b/Console/Node.hh @@ -518,11 +518,16 @@ namespace console { All errors while parsing the arguments of a command must be signaled by throwing an instance of SyntaxErrorException. This is important, so command overloading works. */ - struct SyntaxErrorException : public senf::Exception + struct SyntaxErrorException : public std::exception { explicit SyntaxErrorException(std::string const & msg = ""); + virtual ~SyntaxErrorException() throw(); virtual char const * what() const throw(); + std::string const & message() const; + + private: + std::string message_; }; /** \brief Config/console tree command node diff --git a/Console/Readline.cc b/Console/Readline.cc index 43da447..8d796e6 100644 --- a/Console/Readline.cc +++ b/Console/Readline.cc @@ -59,8 +59,13 @@ /////////////////////////////////////////////////////////////////////////// // senf::console::detail::ReadlineClientReader -extern int readline_echoing_p; -extern int _rl_bell_preference; +extern "C" { + extern int readline_echoing_p; + extern int _rl_bell_preference; + + void _rl_erase_entire_line(); +} + namespace { @@ -164,10 +169,14 @@ prefix_ void senf::console::detail::ReadlineClientReader::callback(std::string l } prefix_ void senf::console::detail::ReadlineClientReader::v_disablePrompt() -{} +{ + _rl_erase_entire_line(); +} prefix_ void senf::console::detail::ReadlineClientReader::v_enablePrompt() -{} +{ + rl_forced_update_display(); +} prefix_ void senf::console::detail::ReadlineClientReader::v_translate(std::string & data) { diff --git a/Console/Readline.hh b/Console/Readline.hh index 7ac5741..7a348ef 100644 --- a/Console/Readline.hh +++ b/Console/Readline.hh @@ -78,6 +78,11 @@ namespace detail { char promptBuffer_[1024]; SchedulerBinding schedBinding_; bool terminate_; + + char * savedLineBuffer_; + int savedPoint_; + int savedEnd_; + int savedMark_; }; /** \brief Internal: Safe GNU readline based ClientReader implementation diff --git a/Console/Server.cci b/Console/Server.cci index 8e0d434..573773d 100644 --- a/Console/Server.cci +++ b/Console/Server.cci @@ -37,6 +37,12 @@ prefix_ senf::console::detail::NonblockingSocketSink::NonblockingSocketSink(Clie : client_ (client) {} +prefix_ senf::console::Client & senf::console::detail::NonblockingSocketSink::client() + const +{ + return client_; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::Server @@ -129,6 +135,11 @@ prefix_ std::string senf::console::Client::promptString() return name_ + ":" + executor_.cwd().path() + "$ "; } +prefix_ senf::console::Client & senf::console::Client::get(std::ostream & os) +{ + return dynamic_cast(os)->client(); +} + prefix_ senf::console::Client::ClientHandle senf::console::Client::handle() const { diff --git a/Console/Server.hh b/Console/Server.hh index abc70b7..8d9b30a 100644 --- a/Console/Server.hh +++ b/Console/Server.hh @@ -137,6 +137,8 @@ namespace console { std::ostream & stream(); std::string promptString() const; + static Client & get(std::ostream & os); + protected: private: diff --git a/Console/Server.ih b/Console/Server.ih index bffdacb..eabef7e 100644 --- a/Console/Server.ih +++ b/Console/Server.ih @@ -55,6 +55,8 @@ namespace detail { NonblockingSocketSink(Client & client); std::streamsize write(const char * s, std::streamsize n); + + Client & client() const; private: Client & client_; diff --git a/Console/testServer.cc b/Console/testServer.cc index 70b8d34..bf41384 100644 --- a/Console/testServer.cc +++ b/Console/testServer.cc @@ -69,6 +69,11 @@ void shutdownServer() throw senf::console::Executor::ExitException(); } +void enableLogging(std::ostream & os) +{ + senf::console::Client::get(os).route(); +} + int main(int, char **) { ::signal(SIGPIPE, SIG_IGN); @@ -77,10 +82,17 @@ int main(int, char **) senf::console::root() .doc("This is the console test application"); senf::console::root() + .mkdir("console") + .doc("Console settings"); + senf::console::root() .mkdir("test") - .doc("Network related settings"); + .doc("Test functions"); senf::console::root() .mkdir("server"); + + senf::console::root()["console"] + .add("showlog", &enableLogging) + .doc("Enable display of log messages on the current console"); senf::console::root()["server"] .add("shutdown", &shutdownServer) .doc("Terminate server application"); @@ -89,7 +101,7 @@ int main(int, char **) .doc("Example of a function utilizing manual argument parsing"); TestObject test; - senf::console::root() + senf::console::root()["test"] .add("testob", test.dir) .doc("Example of an instance directory");