env.Append(
CPPPATH = [ '#/include' ],
CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ] + INLINE_OPTS,
- LIBS = [ 'readline', 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
+ LIBS = [ 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
'$BOOSTFSLIB' ],
TEST_EXTRA_LIBS = [ ],
DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief LineEditor non-inline non-template implementation */
+
+#include "LineEditor.hh"
+//#include "LineEditor.ih"
+
+// Custom includes
+#include "../Logger/SenfLog.hh"
+
+//#include "LineEditor.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::LineEditorSwitcher
+
+prefix_ senf::console::detail::LineEditorSwitcher::LineEditorSwitcher(Client & client)
+ : ClientReader(client),
+ reader_ (new LineEditorClientReader(client, *this))
+{}
+
+prefix_ void senf::console::detail::LineEditorSwitcher::editorSetupFailed()
+{
+ // We need to delete the old reader *before* creating the new one such that all old scheduler
+ // events are removed before installing the new ones.
+ reader_.reset(0);
+ reader_.reset(new DumbClientReader(client()));
+}
+
+prefix_ void senf::console::detail::LineEditorSwitcher::v_disablePrompt()
+{
+ reader_->disablePrompt();
+}
+
+prefix_ void senf::console::detail::LineEditorSwitcher::v_enablePrompt()
+{
+ reader_->enablePrompt();
+}
+
+prefix_ void senf::console::detail::LineEditorSwitcher::v_write(std::string const & data)
+{
+ reader_->write(data);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::LineEditorClientReader
+
+prefix_ senf::console::detail::LineEditorClientReader::
+LineEditorClientReader(Client & client, LineEditorSwitcher & switcher)
+ : term::BaseTelnetProtocol(client.handle()), ClientReader(client),
+ editor_ (*this, senf::membind(&LineEditorClientReader::executeLine, this)),
+ switcher_ (&switcher)
+{
+ editor_.prompt(promptString());
+ editor_.defineKey(senf::term::KeyParser::Ctrl('D'),
+ senf::membind(&LineEditorClientReader::deleteCharOrExit, this));
+}
+
+prefix_ void senf::console::detail::LineEditorClientReader::v_setupFailed()
+{
+ // Commits suicide
+ switcher_->editorSetupFailed();
+}
+
+prefix_ void senf::console::detail::LineEditorClientReader::v_eof()
+{
+ stopClient();
+}
+
+prefix_ void senf::console::detail::LineEditorClientReader::v_disablePrompt()
+{
+ editor_.hide();
+}
+
+prefix_ void senf::console::detail::LineEditorClientReader::v_enablePrompt()
+{
+ editor_.show();
+}
+
+prefix_ void senf::console::detail::LineEditorClientReader::v_write(std::string const & data)
+{
+ BaseTelnetProtocol::write(data);
+}
+
+prefix_ void
+senf::console::detail::LineEditorClientReader::executeLine(std::string const & text)
+{
+ handleInput(text);
+ stream() << std::flush;
+ editor_.prompt(promptString());
+ editor_.show();
+}
+
+prefix_ void
+senf::console::detail::LineEditorClientReader::deleteCharOrExit(term::LineEditor & editor)
+{
+ if (editor.text().empty())
+ ClientReader::handle().facet<TCPSocketProtocol>().shutdown(TCPSocketProtocol::ShutRD);
+ else
+ term::bindings::deleteChar(editor);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "LineEditor.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief LineEditor public header */
+
+#ifndef HH_SENF_Utils_Console_LineEditor_
+#define HH_SENF_Utils_Console_LineEditor_ 1
+
+// Custom includes
+#include <boost/scoped_ptr.hpp>
+#include "../Termlib/TelnetTerminal.hh"
+#include "../Termlib/Editor.hh"
+#include "Server.hh"
+
+//#include "LineEditor.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+namespace detail {
+
+ class LineEditorSwitcher
+ : public ClientReader
+ {
+ public:
+ explicit LineEditorSwitcher(Client & client);
+
+ void editorSetupFailed();
+
+ private:
+ virtual void v_disablePrompt();
+ virtual void v_enablePrompt();
+ virtual void v_write(std::string const & data);
+
+ boost::scoped_ptr<ClientReader> reader_;
+ };
+
+ class LineEditorClientReader
+ : public ClientReader, public term::TelnetTerminal
+ {
+ public:
+ explicit LineEditorClientReader(Client & client, LineEditorSwitcher & switcher);
+
+ private:
+ // TelnetTerminal API implementation
+ virtual void v_setupFailed();
+ virtual void v_eof();
+
+ // ClientReader API implementation
+ virtual void v_disablePrompt();
+ virtual void v_enablePrompt();
+ virtual void v_write(std::string const & data);
+
+ // Editor callbacks
+ void executeLine(std::string const & text);
+ void deleteCharOrExit(term::LineEditor & editor);
+
+ term::LineEditor editor_;
+ LineEditorSwitcher * switcher_;
+ };
+
+}}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "LineEditor.cci"
+//#include "LineEditor.ct"
+//#include "LineEditor.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2008
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// Stefan Bund <g0dil@berlios.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-/** \file
- \brief Readline non-inline non-template implementation */
-
-#include "Readline.hh"
-//#include "Readline.ih"
-
-// Custom includes
-#include <stdio.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-#include <boost/algorithm/string/trim.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include "../../Utils/membind.hh"
-
-//#include "Readline.mpp"
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
-
-//
-// Readline integration is a bit awkward. There are several things to it:
-//
-// - Readline uses global variables for all state. Therefore, we can use readline only for one
-// console.
-// - We need to make readline to read from the socket handle instead of some input stream. We can
-// do this by setting a custom rl_getc_function.
-// - We need to make readline to write to the NonblockingSocketOStream. This is possible in glibc
-// by using a 'cookie stream'.
-// - We need to correctly handle the terminal mode settings. Currently we unconditionally
-// initialize the remote telnet by sending a fixed telnet option string and ignoring any otpions
-// sent back to us.
-// - We need to make sure, readline never uses stderr -> we must disable beeping
-// - There are places, where readline calls read_key unconditionally even when NOT prompted by the
-// callback that another key is available. One such place is completion. (The 'show all
-// completions (y/n)?' question). For now, we disable completion support.
-//
-
-///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::ReadlineClientReader
-
-extern "C" {
- extern int readline_echoing_p;
- extern int _rl_bell_preference;
-
- void _rl_erase_entire_line();
-}
-
-
-namespace {
-
- int readline_getc_function(FILE *)
- {
- if (senf::console::detail::ReadlineClientReader::active())
- return senf::console::detail::ReadlineClientReader::instance().getc();
- else
- return -1;
- }
-
- void readline_callback(char * input)
- {
- if (senf::console::detail::ReadlineClientReader::active()) {
- if (input)
- return senf::console::detail::ReadlineClientReader::instance().callback(
- std::string(input) );
- else // input == 0 -> EOF (or Ctrl-D)
- senf::console::detail::ReadlineClientReader::instance().eof();
- }
- }
-
- ssize_t readline_cookie_write_function(void * cookie, char const * buffer, size_t size)
- {
- if (senf::console::detail::ReadlineClientReader::active() && buffer)
- senf::console::detail::ReadlineClientReader::instance().write(
- std::string(buffer, size));
- return size;
- }
-
- void readline_prep_term(int meta)
- {
- readline_echoing_p = 1;
- }
-
- void readline_deprep_term()
- {}
-
- int restart_line(int count, int key)
- {
- rl_kill_full_line(count, key);
- rl_crlf();
- rl_forced_update_display();
- return 0;
- }
-
-}
-
-prefix_ senf::console::detail::ReadlineClientReader::ReadlineClientReader(Client & client)
- : ClientReader(client), ch_ (-1), skipChars_ (0),
- readevent_ ( "senf::console::detail::ReadlineClientReader", senf::membind(&ReadlineClientReader::charEvent, this),
- client.handle(), scheduler::FdEvent::EV_READ, false ),
- terminate_ (false)
-{
- if (instance_ != 0)
- throw DuplicateReaderException();
- instance_ = this;
-
- cookie_io_functions_t cookie_io = { 0, &readline_cookie_write_function, 0, 0 };
- rl_outstream = fopencookie(0, "a", cookie_io);
- if (rl_outstream == 0)
- SENF_THROW_SYSTEM_EXCEPTION("");
- if (setvbuf(rl_outstream, 0, _IONBF, BUFSIZ) < 0)
- SENF_THROW_SYSTEM_EXCEPTION("");
- rl_instream = rl_outstream;
- rl_terminal_name = "vt100";
- strncpy(nameBuffer_, client.name().c_str(), 128);
- nameBuffer_[127] = 0;
- rl_readline_name = nameBuffer_;
- rl_prep_term_function = &readline_prep_term;
- rl_deprep_term_function = &readline_deprep_term;
- rl_getc_function = &readline_getc_function;
- rl_bind_key('\t', &rl_insert);
- rl_bind_key('\x03', &restart_line);
- using_history();
-
- // Don't ask me, where I found this ...
- static char options[] = { 0xFF, 0xFB, 0x01, // IAC WILL ECHO
- 0xFF, 0xFE, 0x22, // IAC DONT LINEMODE
- 0xFF, 0xFB, 0x03, // IAC WILL SGA
- 0x00 };
- handle().write(options, options+sizeof(options));
- handle().write(std::string("(readline support enabled)\r\n"));
-
- strncpy(promptBuffer_, promptString().c_str(), 1024);
- promptBuffer_[1023] = 0;
- rl_callback_handler_install(promptBuffer_, &readline_callback);
-
- _rl_bell_preference = 0; // Set this *after* the config file has been read
-
- readevent_.enable();
-}
-
-prefix_ senf::console::detail::ReadlineClientReader::~ReadlineClientReader()
-{
- rl_callback_handler_remove();
- fclose(rl_outstream);
- rl_outstream = 0;
- rl_instream = 0;
- instance_ = 0;
-}
-
-prefix_ void senf::console::detail::ReadlineClientReader::callback(std::string line)
-{
- boost::trim(line);
- if (!line.empty())
- add_history(line.c_str());
- handleInput(line);
- stream() << std::flush;
- strncpy(promptBuffer_, promptString().c_str(), 1024);
- promptBuffer_[1023] = 0;
- rl_set_prompt(promptBuffer_);
-}
-
-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)
-{
- boost::replace_all(data, "\n", "\r\n");
- boost::replace_all(data, "\r", "\r\0");
- boost::replace_all(data, "\xff", "\xff\xff");
-}
-
-prefix_ void senf::console::detail::ReadlineClientReader::charEvent(int event)
-{
- char ch;
- if (event != scheduler::FdEvent::EV_READ || handle().read(&ch, &ch+1) <= &ch) {
- stopClient();
- return;
- }
- ch_ = static_cast<unsigned char>(ch);
-
- if (skipChars_ > 0)
- --skipChars_;
- else if (ch_ == 0xff)
- skipChars_ = 2;
- else if (ch_ != 0)
- rl_callback_read_char();
-
- if (terminate_)
- stopClient();
-}
-
-senf::console::detail::ReadlineClientReader *
- senf::console::detail::ReadlineClientReader::instance_ (0);
-
-///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::SafeReadlineClientReader
-
-prefix_ void senf::console::detail::SafeReadlineClientReader::v_disablePrompt()
-{
- reader_->disablePrompt();
-}
-
-prefix_ void senf::console::detail::SafeReadlineClientReader::v_enablePrompt()
-{
- reader_->enablePrompt();
-}
-
-prefix_ void senf::console::detail::SafeReadlineClientReader::v_translate(std::string & data)
-{
- reader_->translate(data);
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
-//#include "Readline.mpp"
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// comment-column: 40
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// End:
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2008
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// Stefan Bund <g0dil@berlios.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-/** \file
- \brief Readline inline non-template implementation */
-
-//#include "Readline.ih"
-
-// Custom includes
-
-#define prefix_ inline
-///////////////////////////////cci.p///////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::ReadlineClientReader
-
-prefix_ bool senf::console::detail::ReadlineClientReader::active()
-{
- return instance_ != 0;
-}
-
-prefix_ senf::console::detail::ReadlineClientReader &
-senf::console::detail::ReadlineClientReader::instance()
-{
- return *instance_;
-}
-
-prefix_ int senf::console::detail::ReadlineClientReader::getc()
-{
- char ch (ch_);
- ch_ = -1;
- return ch;
-}
-
-prefix_ void senf::console::detail::ReadlineClientReader::write(std::string text)
-{
- try {
- translate(text);
- handle().write(text);
- } catch (SystemException &) {
- ;
- }
-}
-
-prefix_ void senf::console::detail::ReadlineClientReader::terminate()
-{
- terminate_ = true;
-}
-
-prefix_ void senf::console::detail::ReadlineClientReader::eof()
-{
- stream() << '\n' << std::flush;
- stopClient();
-}
-
-///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::SafeReadlineClientReader
-
-prefix_
-senf::console::detail::SafeReadlineClientReader::SafeReadlineClientReader(Client & client)
- : ClientReader (client),
- reader_ ( ReadlineClientReader::active()
- ? static_cast<ClientReader*>(new DumbClientReader(client))
- : static_cast<ClientReader*>(new ReadlineClientReader(client)) )
-{}
-
-///////////////////////////////cci.e///////////////////////////////////////
-#undef prefix_
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// comment-column: 40
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// End:
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2008
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// Stefan Bund <g0dil@berlios.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-/** \file
- \brief Readline public header */
-
-#ifndef HH_SENF_Scheduler_Console_Readline_
-#define HH_SENF_Scheduler_Console_Readline_ 1
-
-// Custom includes
-#include <boost/scoped_ptr.hpp>
-#include "Server.hh"
-#include "../../Utils/Exception.hh"
-#include "../../Scheduler/Scheduler.hh"
-
-//#include "Readline.mpp"
-///////////////////////////////hh.p////////////////////////////////////////
-
-namespace senf {
-namespace console {
-namespace detail {
-
-#ifndef DOXYGEN
-
- /** \brief Internal: GNU readline based ClientReader implementation
-
- This implementation of the ClientReader interface uses GNU readline library to provide a
- rich editing environment for console sessions. Since an application can only use readline
- once, only one ReadlineReader can be allocated at any time.
- */
- class ReadlineClientReader
- : public ClientReader
- {
- public:
- ReadlineClientReader(Client & client);
- ~ReadlineClientReader();
-
- static bool active();
- static ReadlineClientReader & instance();
-
- struct DuplicateReaderException : public Exception
- { DuplicateReaderException() : Exception("duplicate readline instantiation") {} };
-
- int getc();
- void callback(std::string line);
- void write(std::string text);
- void terminate();
- void eof();
-
- private:
- virtual void v_disablePrompt();
- virtual void v_enablePrompt();
- virtual void v_translate(std::string & data);
-
- void charEvent(int event);
-
- static ReadlineClientReader * instance_;
- int ch_;
- unsigned skipChars_;
- char nameBuffer_[256];
- char promptBuffer_[1024];
- scheduler::FdEvent readevent_;
- bool terminate_;
-
- char * savedLineBuffer_;
- int savedPoint_;
- int savedEnd_;
- int savedMark_;
- };
-
- /** \brief Internal: Safe GNU readline based ClientReader implementation
-
- This implementation of the ClientReader interface forwards all functionality to either
- ReadlineClientReader or DumbClientReader. A RadlineClientReader is used, if none is active,
- otherwise a DumbClientReader is allocated. Using this ClientReader implementation, the first
- console client will have readline functionality enabled, all further will have it disabled.
- */
- class SafeReadlineClientReader
- : public ClientReader
- {
- public:
- SafeReadlineClientReader(Client & client);
-
- private:
- virtual void v_disablePrompt();
- virtual void v_enablePrompt();
- virtual void v_translate(std::string & data);
-
- boost::scoped_ptr<ClientReader> reader_;
- };
-
-#endif
-
-}}}
-
-///////////////////////////////hh.e////////////////////////////////////////
-#include "Readline.cci"
-//#include "Readline.ct"
-//#include "Readline.cti"
-#endif
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// comment-column: 40
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// End:
#include "../../Utils/senfassert.hh"
#include "../../Utils/membind.hh"
#include "../../Utils/Logger/SenfLog.hh"
-#include "Readline.hh"
+#include "LineEditor.hh"
//#include "Server.mpp"
#define prefix_
try {
if (client_.handle().writeable()) {
std::string data (s, n);
- client_.translate(data);
- client_.handle().write( data );
+ client_.write(data);
}
}
catch (SystemException & ex) {
prefix_ void senf::console::detail::DumbClientReader::showPrompt()
{
std::string prompt (promptString());
+ prompt += " ";
stream() << std::flush;
handle().write(prompt);
showPrompt();
}
-prefix_ void senf::console::detail::DumbClientReader::v_translate(std::string & data)
-{}
+prefix_ void senf::console::detail::DumbClientReader::v_write(std::string const & data)
+{
+ handle().write(data);
+}
///////////////////////////////////////////////////////////////////////////
// senf::console::detail::NoninteractiveClientReader
prefix_ void senf::console::detail::NoninteractiveClientReader::v_enablePrompt()
{}
-prefix_ void senf::console::detail::NoninteractiveClientReader::v_translate(std::string & data)
-{}
+prefix_ void senf::console::detail::NoninteractiveClientReader::v_write(std::string const & data)
+{
+ handle().write(data);
+}
prefix_ void
senf::console::detail::NoninteractiveClientReader::newData(int event)
readevent_.disable();
timer_.disable();
mode_ = Server::Interactive;
- reader_.reset(new detail::SafeReadlineClientReader (*this));
+ reader_.reset(new detail::LineEditorSwitcher (*this));
executor_.autocd(true).autocomplete(true);
}
reader_.reset(new detail::NoninteractiveClientReader(*this));
}
-prefix_ void senf::console::Client::translate(std::string & data)
-{
- reader_->translate(data);
-}
-
prefix_ std::string::size_type senf::console::Client::handleInput(std::string data,
bool incremental)
{
prefix_ std::string senf::console::Client::promptString()
const
{
- return name_ + ":" + executor_.cwdPath() + "$ ";
+ return name_ + ":" + executor_.cwdPath() + "$";
}
prefix_ senf::console::DirectoryNode & senf::console::Client::root()
return mode_;
}
+prefix_ void senf::console::Client::write(std::string const & data)
+ const
+{
+ reader_->write(data);
+}
+
prefix_ senf::console::Client & senf::console::Client::get(std::ostream & os)
{
return dynamic_cast<detail::NonblockingSocketOStream&>(os)->client();
v_enablePrompt();
}
-prefix_ void senf::console::detail::ClientReader::translate(std::string & data)
+prefix_ void senf::console::detail::ClientReader::write(std::string const & data)
{
- v_translate(data);
+ v_write(data);
}
prefix_ senf::console::detail::ClientReader::ClientReader(Client & client)
std::string promptString() const;
DirectoryNode & root() const;
Server::Mode mode() const;
+ void write(std::string const & data) const;
static Client & get(std::ostream & os);
void setInteractive();
void setNoninteractive();
- void translate(std::string & data);
size_t handleInput(std::string input, bool incremental = false);
virtual void v_write(senf::log::time_type timestamp, std::string const & stream,
std::string const & area, unsigned level,
void disablePrompt();
void enablePrompt();
- void translate(std::string & data);
+ void write(std::string const & data);
protected:
ClientReader(Client & client);
private:
virtual void v_disablePrompt() = 0;
virtual void v_enablePrompt() = 0;
- virtual void v_translate(std::string & data) = 0;
+ virtual void v_write(std::string const & data) = 0;
Client & client_;
};
private:
virtual void v_disablePrompt();
virtual void v_enablePrompt();
- virtual void v_translate(std::string & data);
+ virtual void v_write(std::string const & data);
void clientData(senf::ReadHelper<ClientHandle>::ptr helper);
void showPrompt();
private:
virtual void v_disablePrompt();
virtual void v_enablePrompt();
- virtual void v_translate(std::string & data);
+ virtual void v_write(std::string const & data);
void newData(int event);
delete this;
}
- virtual void executeLine(std::string const & text)
+ void executeLine(std::string const & text)
{
SENF_LOG(("Execute line: " << text));
editor_.show();
# c) check for a local SENF, set options accordingly and update that SENF if needed
def SetupForSENF(env):
- env.Append( LIBS = [ 'senf', 'readline', 'rt', '$BOOSTREGEXLIB',
+ env.Append( LIBS = [ 'senf', 'rt', '$BOOSTREGEXLIB',
'$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
'$BOOSTFSLIB' ],
BOOSTREGEXLIB = 'boost_regex',