Console: Add console routing to testServer example
g0dil [Mon, 28 Apr 2008 23:13:49 +0000 (23:13 +0000)]
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

Console/Executor.cc
Console/Executor.hh
Console/Node.cci
Console/Node.hh
Console/Readline.cc
Console/Readline.hh
Console/Server.cci
Console/Server.hh
Console/Server.ih
Console/testServer.cc

index 5e4b6f2..da8aa49 100644 (file)
@@ -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<DirectoryNode*>(&node) );
+            if ( dir ) {
+                oldCwd_ = cwd_;
+                cwd_ = dir->thisptr();
+            } else {
+                dynamic_cast<CommandNode &>(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<DirectoryNode&>( 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<CommandNode &>( cwd().traverse(path) );
+        return dynamic_cast<DirectoryNode&>( 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"
index 81dafd9..441c3d7 100644 (file)
@@ -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 {};
index 6f24e9c..c0d76bc 100644 (file)
@@ -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
 
index 6a2732c..a93c23c 100644 (file)
@@ -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
index 43da447..8d796e6 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // 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)
 {
index 7ac5741..7a348ef 100644 (file)
@@ -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
index 8e0d434..573773d 100644 (file)
@@ -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<detail::NonblockingSocketOStream&>(os)->client();
+}
+
 prefix_ senf::console::Client::ClientHandle senf::console::Client::handle()
     const
 {
index abc70b7..8d9b30a 100644 (file)
@@ -137,6 +137,8 @@ namespace console {
         std::ostream & stream();
         std::string promptString() const;
 
+        static Client & get(std::ostream & os);
+
     protected:
         
     private:
index bffdacb..eabef7e 100644 (file)
@@ -55,6 +55,8 @@ namespace detail {
 
         NonblockingSocketSink(Client & client);
         std::streamsize write(const char * s, std::streamsize n);
+
+        Client & client() const;
         
     private:
         Client & client_;
index 70b8d34..bf41384 100644 (file)
@@ -69,6 +69,11 @@ void shutdownServer()
     throw senf::console::Executor::ExitException();
 }
 
+void enableLogging(std::ostream & os)
+{
+    senf::console::Client::get(os).route<senf::SenfLog,senf::log::NOTICE>();
+}
+
 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");