Utils: Fix hexump() of nevative values
g0dil [Mon, 5 Jan 2009 23:27:01 +0000 (23:27 +0000)]
Utils/Console: Move telnet functionality to Utils/Termlib
Utils/Termlib: Implement terminfo readier
Utils/Termlib: Implement terminfo based keycode parser

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1036 270642c3-0616-0410-b53a-bc976706d245

19 files changed:
SConstruct
Socket/Protocols/Raw/MACAddress.hh
Utils/Console/SConscript
Utils/Termlib/Doxyfile [new file with mode: 0644]
Utils/Termlib/SConscript [new file with mode: 0644]
Utils/Termlib/Telnet.cc [moved from Utils/Console/Telnet.cc with 75% similarity]
Utils/Termlib/Telnet.cci [moved from Utils/Console/Telnet.cci with 62% similarity]
Utils/Termlib/Telnet.cti [moved from Utils/Console/Telnet.cti with 93% similarity]
Utils/Termlib/Telnet.hh [moved from Utils/Console/Telnet.hh with 97% similarity]
Utils/Termlib/Telnet.test.cc [copied from Utils/Console/Telnet.test.cc with 100% similarity]
Utils/Termlib/TelnetTerminal.cc [new file with mode: 0644]
Utils/Termlib/TelnetTerminal.hh [new file with mode: 0644]
Utils/Termlib/Terminfo.cc [new file with mode: 0644]
Utils/Termlib/Terminfo.hh [new file with mode: 0644]
Utils/Termlib/Terminfo.test.cc [new file with mode: 0644]
Utils/Termlib/main.test.cc [moved from Utils/Console/Telnet.test.cc with 88% similarity]
Utils/Termlib/telnetServer.cc [moved from Utils/Console/telnetServer.cc with 81% similarity]
Utils/hexdump.cc
Utils/hexdump.ih

index a898d6c..376a87d 100644 (file)
@@ -118,8 +118,9 @@ INLINE_OPTS = [ '-finline-limit=5000' ]
 env.Append(
    CPPPATH = [ '#/include' ],
    CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ] + INLINE_OPTS,
-   LIBS = [ 'readline', 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB' ],
-   TEST_EXTRA_LIBS = [ '$BOOSTFSLIB' ],
+   LIBS = [ 'readline', 'rt', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
+            '$BOOSTFSLIB' ],
+   TEST_EXTRA_LIBS = [ ],
    DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
    DOXY_HTML_XSL = '#/doclib/html-munge.xsl',
    ENV = { 'TODAY' : str(datetime.date.today()),
index 4281efd..3b1e94c 100644 (file)
@@ -67,14 +67,7 @@ namespace senf {
             INet6Address(0x2001u,0xDB8u,0x1u,0x0u,0x001Au,0x2BFFu,0xFE3Cu,0x3D5Fu).id())
         \endcode
 
-        Since MACAddress is based on \c boo Ziel, aber nur ein paar davon sind standardkomform.
-
-Der aktuelle C++ Standard unterstützt drei verschiedene Möglichkeiten eine Zahl in einen String umzuwandeln. Diese Möglichkeiten sind:
-
-    * sprintf
-    * std::strstream
-    * std::stringstream
-        st::array, you can access the raw data bytes of the
+        Since MACAddress is based on \c boost::array, you can access the raw data bytes of the
         address using \c begin(), \c end() or \c operator[]:
         \code
         MACAddress mac = ...;
index a231c94..c54f55c 100644 (file)
@@ -5,11 +5,10 @@ import SENFSCons
 
 ###########################################################################
 
-sources, includes = SENFSCons.Glob(env, exclude=['testServer.cc', 'telnetServer.cc'])
+sources, includes = SENFSCons.Glob(env, exclude=['testServer.cc'])
 
 SENFSCons.StandardTargets(env)
 SENFSCons.Lib(env, sources)
 SENFSCons.Doxygen(env)
 SENFSCons.InstallIncludeFiles(env, includes)
 SENFSCons.Binary(env, "testServer", ['testServer.cc'])
-SENFSCons.Binary(env, "telnetServer", ['telnetServer.cc'])
diff --git a/Utils/Termlib/Doxyfile b/Utils/Termlib/Doxyfile
new file mode 100644 (file)
index 0000000..b7b820c
--- /dev/null
@@ -0,0 +1,12 @@
+@INCLUDE = "$(TOPDIR)/doclib/Doxyfile.global"
+
+PROJECT_NAME = libTermlib
+GENERATE_TAGFILE = doc/Console.tag
+EXAMPLE_PATH = .
+EXCLUDE = telnetServer.cc
+
+TAGFILES = \
+    "$(TOPDIR)/Socket/doc/Socket.tag" \
+    "$(TOPDIR)/Scheduler/doc/Scheduler.tag" \
+    "$(TOPDIR)/Utils/doc/Utils.tag" \
+    "$(TOPDIR)/Utils/Logger/doc/Logger.tag"
diff --git a/Utils/Termlib/SConscript b/Utils/Termlib/SConscript
new file mode 100644 (file)
index 0000000..7fe6526
--- /dev/null
@@ -0,0 +1,14 @@
+# -*- python -*-
+
+Import('env')
+import SENFSCons
+
+###########################################################################
+
+sources, includes = SENFSCons.Glob(env, exclude=[ 'telnetServer.cc'])
+
+SENFSCons.StandardTargets(env)
+SENFSCons.Lib(env, sources)
+SENFSCons.Doxygen(env)
+SENFSCons.InstallIncludeFiles(env, includes)
+SENFSCons.Binary(env, "telnetServer", ['telnetServer.cc'])
similarity index 75%
rename from Utils/Console/Telnet.cc
rename to Utils/Termlib/Telnet.cc
index acf32ce..b32747a 100644 (file)
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-prefix_ senf::console::detail::BaseTelnetProtocol::BaseTelnetProtocol(Handle handle)
+prefix_ senf::term::BaseTelnetProtocol::BaseTelnetProtocol(Handle handle)
     : handle_ (handle), charState_ (NORMAL), command_ (CMD_NONE), option_ (0),
-      inputEvent_ ("senf::console::detail::BaseTelnetProtocol::input",
+      inputEvent_ ("senf::term::BaseTelnetProtocol::input",
                    senf::membind(&BaseTelnetProtocol::readHandler, this), handle, 
                    senf::scheduler::FdEvent::EV_READ),
-      outputEvent_ ("senf::console::detail::BaseTelnetProtocol::output",
+      outputEvent_ ("senf::term::BaseTelnetProtocol::output",
                     senf::membind(&BaseTelnetProtocol::writeHandler, this), handle,
                     senf::scheduler::FdEvent::EV_WRITE, false),
       pendingRequests_ (0u),
       requestTimeout_ (ClockService::milliseconds(DEFAULT_REQUEST_TIMEOUT_MS)),
-      timeout_ ("senf::console::detail::BaseTelnetProtocol::timeout",
+      timeout_ ("senf::term::BaseTelnetProtocol::timeout",
                 senf::membind(&BaseTelnetProtocol::timeout, this))
 {}
 
-prefix_ senf::console::detail::BaseTelnetProtocol::BaseTelnetProtocol()
+prefix_ senf::term::BaseTelnetProtocol::BaseTelnetProtocol()
     : handle_ (), charState_ (NORMAL), command_ (CMD_NONE), option_ (0),
-      inputEvent_ ("senf::console::detail::BaseTelnetProtocol::input", 0),
-      outputEvent_ ("senf::console::detail::BaseTelnetProtocol::output", 0),
+      inputEvent_ ("senf::term::BaseTelnetProtocol::input", 0),
+      outputEvent_ ("senf::term::BaseTelnetProtocol::output", 0),
       pendingRequests_ (0u),
       requestTimeout_ (ClockService::milliseconds(DEFAULT_REQUEST_TIMEOUT_MS)),
-      timeout_ ("senf::console::detail::BaseTelnetProtocol::timeout", 0)
+      timeout_ ("senf::term::BaseTelnetProtocol::timeout", 0)
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::write(std::string const & s)
+prefix_ void senf::term::BaseTelnetProtocol::write(std::string const & s)
 {
     for (std::string::const_iterator i (s.begin()); i != s.end(); ++i)
         write(*i);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::write(char c)
+prefix_ void senf::term::BaseTelnetProtocol::write(char c)
 {
     switch (c) {
     case '\r':
@@ -85,7 +85,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::write(char c)
 }
 
 prefix_ void
-senf::console::detail::BaseTelnetProtocol::sendOptionParameters(option_type option,
+senf::term::BaseTelnetProtocol::sendOptionParameters(option_type option,
                                                                 std::string const & data)
 {
     transmit(CMD_IAC);
@@ -102,31 +102,31 @@ senf::console::detail::BaseTelnetProtocol::sendOptionParameters(option_type opti
     transmit(CMD_SE);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleNOP()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleNOP()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleBRK()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleBRK()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleIP()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleIP()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleAO()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleAO()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleAYT()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleAYT()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleEC()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleEC()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleEL()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleEL()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::v_handleGA()
+prefix_ void senf::term::BaseTelnetProtocol::v_handleGA()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleChar(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleChar(char c)
 {
     switch (charState_) {
     case NORMAL:
@@ -153,7 +153,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::handleChar(char c)
     }
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleNormalChar(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleNormalChar(char c)
 {
     switch (c) {
     case '\r':
@@ -168,7 +168,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::handleNormalChar(char c)
     }
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleCommand(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleCommand(char c)
 {
     switch (c) {
     case CMD_SE:
@@ -211,14 +211,14 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::handleCommand(char c)
     }
 }        
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleOption(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleOption(char c)
 {
     option_ = c;
     processCommand();
     charState_ = NORMAL;
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleCR(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleCR(char c)
 {
     switch (c) {
     case '\0':
@@ -237,14 +237,14 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::handleCR(char c)
     }
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleSBOption(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleSBOption(char c)
 {
     option_ = c;
     charState_ = SB_DATA;
     data_.clear();
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleSBData(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleSBData(char c)
 {
     if (c == '\xff')
         charState_ = SB_IAC_SEEN;
@@ -252,7 +252,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::handleSBData(char c)
         data_.push_back(c);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::handleSBIAC(char c)
+prefix_ void senf::term::BaseTelnetProtocol::handleSBIAC(char c)
 {
     switch (c) {
     case CMD_IAC:
@@ -270,7 +270,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::handleSBIAC(char c)
     }
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::processCommand()
+prefix_ void senf::term::BaseTelnetProtocol::processCommand()
 {
     switch (command_) {
     case CMD_NONE:
@@ -320,13 +320,13 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::processCommand()
     }
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::transmit(char c)
+prefix_ void senf::term::BaseTelnetProtocol::transmit(char c)
 {
     sendQueue_.push_back(c);
     outputEvent_.enable();
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::readHandler(int state)
+prefix_ void senf::term::BaseTelnetProtocol::readHandler(int state)
 {
     if (state != senf::scheduler::FdEvent::EV_READ || handle_.eof()) {
         inputEvent_.disable();
@@ -339,7 +339,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::readHandler(int state)
         handleChar(*i);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::writeHandler(int state)
+prefix_ void senf::term::BaseTelnetProtocol::writeHandler(int state)
 { 
     if (state != senf::scheduler::FdEvent::EV_WRITE) {
         outputEvent_.disable();
@@ -353,7 +353,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::writeHandler(int state)
         outputEvent_.disable();
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::timeout()
+prefix_ void senf::term::BaseTelnetProtocol::timeout()
 {
     if (pendingRequests_ > 0u) {
         pendingRequests_ = 0u;
@@ -361,8 +361,8 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::timeout()
     }
 }
 
-prefix_ senf::console::detail::BaseTelnetProtocol::OptInfo &
-senf::console::detail::BaseTelnetProtocol::getOption(bool local, option_type option)
+prefix_ senf::term::BaseTelnetProtocol::OptInfo &
+senf::term::BaseTelnetProtocol::getOption(bool local, option_type option)
 {
     OptionsMap::iterator i (options_.find(std::make_pair(local, option)));
     if (i == options_.end())
@@ -371,7 +371,7 @@ senf::console::detail::BaseTelnetProtocol::getOption(bool local, option_type opt
     return i->second;
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::request(OptInfo & info, bool enabled)
+prefix_ void senf::term::BaseTelnetProtocol::request(OptInfo & info, bool enabled)
 {
     info.wantState = enabled ? OptInfo::WANTED : OptInfo::DISABLED;
     if (enabled != info.enabled) {
@@ -383,7 +383,7 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::request(OptInfo & info,
     }
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::response(OptInfo & info, bool enabled)
+prefix_ void senf::term::BaseTelnetProtocol::response(OptInfo & info, bool enabled)
 {
     bool decrementCount (false);
 
@@ -417,12 +417,12 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::response(OptInfo & info,
             i->second->v_init();
     }
     if (decrementCount)
-        // This call must be AFTER calling v_init since v_init might increment the request count.
+        // This call must be AFTER calling v_init since v_init might increment the request count
         // and v_setupComplete() might be called prematurely.
         decrementRequestCounter();
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::decrementRequestCounter()
+prefix_ void senf::term::BaseTelnetProtocol::decrementRequestCounter()
 {
     if (pendingRequests_ > 0u) {
         -- pendingRequests_;
@@ -434,19 +434,19 @@ prefix_ void senf::console::detail::BaseTelnetProtocol::decrementRequestCounter(
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::telnethandler::TerminalType
+// senf::term::telnethandler::TerminalType
 
-prefix_ senf::console::detail::telnethandler::TerminalType::TerminalType()
+prefix_ senf::term::telnethandler::TerminalType::TerminalType()
 {
     registerHandler(this);
 }
 
-prefix_ void senf::console::detail::telnethandler::TerminalType::nextTerminalType()
+prefix_ void senf::term::telnethandler::TerminalType::nextTerminalType()
 {
     sendOptionParameters(telnetopt::TERMINAL_TYPE, "\x01");
 }
 
-prefix_ void senf::console::detail::telnethandler::TerminalType::
+prefix_ void senf::term::telnethandler::TerminalType::
 v_handleOptionParameters(std::string const & data)
 {
     if (data.size() <= 0)
@@ -457,28 +457,28 @@ v_handleOptionParameters(std::string const & data)
     }
 }
 
-prefix_ void senf::console::detail::telnethandler::TerminalType::v_init()
+prefix_ void senf::term::telnethandler::TerminalType::v_init()
 {
     nextTerminalType();
     incrementRequestCounter();
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::telnethandler::NAWS
+// senf::term::telnethandler::NAWS
 
-prefix_ senf::console::detail::telnethandler::NAWS::NAWS()
+prefix_ senf::term::telnethandler::NAWS::NAWS()
     : width_ (0u), height_ (0u)
 {
     registerHandler(this);
 }
 
-prefix_ void senf::console::detail::telnethandler::NAWS::v_init()
+prefix_ void senf::term::telnethandler::NAWS::v_init()
 {
     incrementRequestCounter();
 }
 
 prefix_ void
-senf::console::detail::telnethandler::NAWS::v_handleOptionParameters(std::string const & data)
+senf::term::telnethandler::NAWS::v_handleOptionParameters(std::string const & data)
 {
     if (data.size() != 4)
         return;
similarity index 62%
rename from Utils/Console/Telnet.cci
rename to Utils/Termlib/Telnet.cci
index 7dc6f2a..ed7d902 100644 (file)
 ///////////////////////////////cci.p///////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::BaseTelnetProtocol::OptInfo
+// senf::term::BaseTelnetProtocol::OptInfo
 
-prefix_ senf::console::detail::BaseTelnetProtocol::OptInfo::OptInfo()
+prefix_ senf::term::BaseTelnetProtocol::OptInfo::OptInfo()
     : local (false), option (0u), wantState (DISABLED), optionState (NONE), enabled (false)
 {}
 
-prefix_ senf::console::detail::BaseTelnetProtocol::OptInfo::OptInfo(bool l, option_type o)
+prefix_ senf::term::BaseTelnetProtocol::OptInfo::OptInfo(bool l, option_type o)
     : local (l), option (o), wantState (DISABLED), optionState (NONE), enabled (false)
 {}
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::BaseTelnetProtocol::TelnetHandler
+// senf::term::BaseTelnetProtocol::TelnetHandler
 
-prefix_ senf::console::detail::BaseTelnetProtocol::TelnetHandler::~TelnetHandler()
+prefix_ senf::term::BaseTelnetProtocol::TelnetHandler::~TelnetHandler()
 {}
 
-prefix_ std::string const & senf::console::detail::telnethandler::TerminalType::terminalType()
+prefix_ std::string const & senf::term::telnethandler::TerminalType::terminalType()
     const
 {
     return type_;
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::telnethandler::NAWS
+// senf::term::telnethandler::NAWS
 
-prefix_ unsigned senf::console::detail::telnethandler::NAWS::width()
+prefix_ unsigned senf::term::telnethandler::NAWS::width()
     const
 {
     return width_;
 }
 
-prefix_ unsigned senf::console::detail::telnethandler::NAWS::height()
+prefix_ unsigned senf::term::telnethandler::NAWS::height()
     const
 {
     return height_;
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::BaseTelnetProtocol
+// senf::term::BaseTelnetProtocol
 
-prefix_ senf::console::detail::BaseTelnetProtocol::~BaseTelnetProtocol()
+prefix_ senf::term::BaseTelnetProtocol::~BaseTelnetProtocol()
 {}
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::incrementRequestCounter()
+prefix_ void senf::term::BaseTelnetProtocol::incrementRequestCounter()
 {
     ++ pendingRequests_;
     timeout_.timeout(senf::scheduler::eventTime() + requestTimeout_);
 }
 
-prefix_ bool senf::console::detail::BaseTelnetProtocol::requestsPending()
+prefix_ bool senf::term::BaseTelnetProtocol::requestsPending()
 {
     return pendingRequests_ > 0u;
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendNOP()
+prefix_ void senf::term::BaseTelnetProtocol::sendNOP()
 {
     transmit(CMD_IAC);
     transmit(CMD_NOP);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendBRK()
+prefix_ void senf::term::BaseTelnetProtocol::sendBRK()
 {
     transmit(CMD_IAC);
     transmit(CMD_BRK);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendIP()
+prefix_ void senf::term::BaseTelnetProtocol::sendIP()
 {
     transmit(CMD_IAC);
     transmit(CMD_IP);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendAO()
+prefix_ void senf::term::BaseTelnetProtocol::sendAO()
 {
     transmit(CMD_IAC);
     transmit(CMD_AO);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendAYT()
+prefix_ void senf::term::BaseTelnetProtocol::sendAYT()
 {
     transmit(CMD_IAC);
     transmit(CMD_AYT);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendEC()
+prefix_ void senf::term::BaseTelnetProtocol::sendEC()
 {
     transmit(CMD_IAC);
     transmit(CMD_EC);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendEL()
+prefix_ void senf::term::BaseTelnetProtocol::sendEL()
 {
     transmit(CMD_IAC);
     transmit(CMD_EL);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::sendGA()
+prefix_ void senf::term::BaseTelnetProtocol::sendGA()
 {
     transmit(CMD_IAC);
     transmit(CMD_GA);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::requestLocalOption(option_type option,
+prefix_ void senf::term::BaseTelnetProtocol::requestLocalOption(option_type option,
                                                                            bool enabled)
 {
     request(getOption(true, option), enabled);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::acceptLocalOption(option_type option,
+prefix_ void senf::term::BaseTelnetProtocol::acceptLocalOption(option_type option,
                                                                           bool enabled)
 {
     getOption(true, option).wantState = OptInfo::ACCEPTED;
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::requestPeerOption(option_type option,
+prefix_ void senf::term::BaseTelnetProtocol::requestPeerOption(option_type option,
                                                                           bool enabled)
 {
     request(getOption(false, option), enabled);
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::acceptPeerOption(option_type option,
+prefix_ void senf::term::BaseTelnetProtocol::acceptPeerOption(option_type option,
                                                                          bool enabled)
 {
     getOption(false, option).wantState = OptInfo::ACCEPTED;
 }
 
-prefix_ void senf::console::detail::BaseTelnetProtocol::emit(char c)
+prefix_ void senf::term::BaseTelnetProtocol::emit(char c)
 {
     v_charReceived(c);
 }
similarity index 93%
rename from Utils/Console/Telnet.cti
rename to Utils/Termlib/Telnet.cti
index 42b50a6..e50e845 100644 (file)
 ///////////////////////////////cti.p///////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::detail::BaseTelnetProtocol
+// senf::term::BaseTelnetProtocol
 
 template <class Handler>
-prefix_ void senf::console::detail::BaseTelnetProtocol::registerHandler(Handler * h,
+prefix_ void senf::term::BaseTelnetProtocol::registerHandler(Handler * h,
                                                                         bool request)
 {
     handlers_.insert(std::make_pair(Handler::OPTION_CODE, h));
similarity index 97%
rename from Utils/Console/Telnet.hh
rename to Utils/Termlib/Telnet.hh
index d813474..c50f87b 100644 (file)
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
-namespace console {
-namespace detail {
+namespace term {
 
     /** \brief  Telnet server
 
         \see 
-            <a href="http://tools.ietf.org/html/rfc854>RFC 854</a> The Telnet protocol \n
-            <a href="http://tools.ietf.org/html/rfc854>RFC 855</a> Telnet option specifications
+            <a href="http://tools.ietf.org/html/rfc854">RFC 854</a> The Telnet protocol \n
+            <a href="http://tools.ietf.org/html/rfc854">RFC 855</a> Telnet option specifications
 
         \todo SYNCH handling
      */
@@ -95,8 +94,6 @@ namespace detail {
         void decrementRequestCounter();
         bool requestsPending();
 
-    private:
-
 #ifndef DOXYGEN
     private:
 #endif
@@ -271,7 +268,7 @@ namespace telnethandler {
     
 }
 
-}}}
+}}
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "Telnet.cci"
diff --git a/Utils/Termlib/TelnetTerminal.cc b/Utils/Termlib/TelnetTerminal.cc
new file mode 100644 (file)
index 0000000..1c244ba
--- /dev/null
@@ -0,0 +1,94 @@
+// $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 TelnetTerminal non-inline non-template implementation */
+
+#include "TelnetTerminal.hh"
+//#include "TelnetTerminal.ih"
+
+// Custom includes
+#include <senf/Utils/membind.hh>
+
+//#include "TelnetTerminal.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ senf::term::TelnetTerminal::TelnetTerminal()
+    : keyTimeout_ (senf::ClockService::milliseconds(DEFAULT_KEY_TIMEOUT_MS)),
+      timer_ ("senf::term::TelnetTerminal::keySequenceTimeout", 
+              senf::membind(&TelnetTerminal::keySequenceTimeout, this))
+{
+    requestPeerOption(telnetopt::SUPPRESS_GO_AHEAD);
+    requestLocalOption(telnetopt::SUPPRESS_GO_AHEAD);
+    requestLocalOption(telnetopt::ECHO);
+}
+
+prefix_ void senf::term::TelnetTerminal::v_setupComplete()
+{
+    tifo_.load(terminalType());
+    keyParser_.load(tifo_);
+}
+
+prefix_ void senf::term::TelnetTerminal::v_charReceived(char c)
+{
+    inputBuffer_ += c;
+    timer_.timeout(senf::scheduler::eventTime() + keyTimeout_);
+    processKeys();
+}
+
+prefix_ void senf::term::TelnetTerminal::keySequenceTimeout()
+{
+    while (!inputBuffer_.empty()) {
+        processKeys();
+        v_keyReceived(keycode_t(inputBuffer_[0]));
+        inputBuffer_.erase(0, 1);
+    }
+}
+
+prefix_ void senf::term::TelnetTerminal::processKeys()
+{
+    do {
+        std::pair<senf::term::KeyParser::keycode_t, std::string::size_type> result
+            (keyParser_.lookup(inputBuffer_));
+        if (result.first == senf::term::KeyParser::Incomplete)
+            return;
+        v_keyReceived(result.first);
+        inputBuffer_.erase(0, result.second);
+    } while (! inputBuffer_.empty());
+    timer_.disable();
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "TelnetTerminal.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:
diff --git a/Utils/Termlib/TelnetTerminal.hh b/Utils/Termlib/TelnetTerminal.hh
new file mode 100644 (file)
index 0000000..0514c63
--- /dev/null
@@ -0,0 +1,85 @@
+// $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 TelnetTerminal public header */
+
+#ifndef HH_SENF_Utils_Termlib_TelnetTerminal_
+#define HH_SENF_Utils_Termlib_TelnetTerminal_ 1
+
+// Custom includes
+#include <senf/Scheduler/TimerEvent.hh>
+#include <senf/Scheduler/ClockService.hh>
+#include "Telnet.hh"
+#include "Terminfo.hh"
+
+//#include "TelnetTerminal.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace term {
+
+    class TelnetTerminal
+        : public telnethandler::TerminalType,
+          public telnethandler::NAWS
+    {
+    public:
+        typedef KeyParser::keycode_t keycode_t;
+
+        static unsigned const DEFAULT_KEY_TIMEOUT_MS = 500u;
+
+        TelnetTerminal();
+
+    protected:
+        virtual void v_setupComplete();
+
+    private:
+        virtual void v_keyReceived(keycode_t key) = 0;
+
+        virtual void v_charReceived(char c);
+        void keySequenceTimeout();
+        void processKeys();
+
+        senf::term::Terminfo tifo_;
+        senf::term::KeyParser keyParser_;
+        std::string inputBuffer_;
+        senf::ClockService::clock_type keyTimeout_;
+        senf::scheduler::TimerEvent timer_;
+    };
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "TelnetTerminal.cci"
+//#include "TelnetTerminal.ct"
+//#include "TelnetTerminal.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:
diff --git a/Utils/Termlib/Terminfo.cc b/Utils/Termlib/Terminfo.cc
new file mode 100644 (file)
index 0000000..1a7c50f
--- /dev/null
@@ -0,0 +1,473 @@
+// $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 Terminfo non-inline non-template implementation */
+
+#include "Terminfo.hh"
+//#include "Terminfo.ih"
+
+// Custom includes
+#include <fstream>
+#include <iomanip>
+#include <boost/filesystem/operations.hpp>
+#include <senf/config.hh>
+#include <senf/Utils/hexdump.hh>
+#include <unistd.h>
+#include <string.h>
+
+//#include "Terminfo.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+char const * const senf::term::Terminfo::properties::BooleanNames [] = {
+    "AutoLeftMargin", "AutoRightMargin", "NoEscCtlc", "CeolStandoutGlitch", "EatNewlineGlitch",
+    "EraseOverstrike", "GenericType", "HardCopy", "HasMetaKey", "HasStatusLine", "InsertNullGlitch",
+    "MemoryAbove", "MemoryBelow", "MoveInsertMode", "MoveStandoutMode", "OverStrike",
+    "StatusLineEscOk", "DestTabsMagicSmso", "TildeGlitch", "TransparentUnderline", "XonXoff",
+    "NeedsXonXoff", "PrtrSilent", "HardCursor", "NonRevRmcup", "NoPadChar", "NonDestScrollRegion",
+    "CanChange", "BackColorErase", "HueLightnessSaturation", "ColAddrGlitch", "CrCancelsMicroMode",
+    "HasPrintWheel", "RowAddrGlitch", "SemiAutoRightMargin", "CpiChangesRes", "LpiChangesRes",
+    "BackspacesWithBs", "CrtNoScrolling", "NoCorrectlyWorkingCr", "GnuHasMetaKey",
+    "LinefeedIsNewline", "HasHardwareTabs", "ReturnDoesClrEol" };
+
+char const * const senf::term::Terminfo::properties::NumericNames[] = {
+    "Columns", "InitTabs", "Lines", "LinesOfMemory", "MagicCookieGlitch", "PaddingBaudRate",
+    "VirtualTerminal", "WidthStatusLine", "NumLabels", "LabelHeight", "LabelWidth", "MaxAttributes",
+    "MaximumWindows", "MaxColors", "MaxPairs", "NoColorVideo", "BufferCapacity", "DotVertSpacing",
+    "DotHorzSpacing", "MaxMicroAddress", "MaxMicroJump", "MicroColSize", "MicroLineSize",
+    "NumberOfPins", "OutputResChar", "OutputResLine", "OutputResHorzInch", "OutputResVertInch",
+    "PrintRate", "WideCharSize", "Buttons", "BitImageEntwining", "BitImageType",
+    "MagicCookieGlitchUl", "CarriageReturnDelay", "NewLineDelay", "BackspaceDelay",
+    "HorizontalTabDelay", "NumberOfFunctionKeys" };
+
+char const * const senf::term::Terminfo::properties::StringNames[] = {
+     "BackTab", "Bell", "CarriageReturn", "ChangeScrollRegion", "ClearAllTabs", "ClearScreen",
+     "ClrEol", "ClrEos", "ColumnAddress", "CommandCharacter", "CursorAddress", "CursorDown",
+     "CursorHome", "CursorInvisible", "CursorLeft", "CursorMemAddress", "CursorNormal",
+     "CursorRight", "CursorToLl", "CursorUp", "CursorVisible", "DeleteCharacter", "DeleteLine",
+     "DisStatusLine", "DownHalfLine", "EnterAltCharsetMode", "EnterBlinkMode", "EnterBoldMode",
+     "EnterCaMode", "EnterDeleteMode", "EnterDimMode", "EnterInsertMode", "EnterSecureMode",
+     "EnterProtectedMode", "EnterReverseMode", "EnterStandoutMode", "EnterUnderlineMode",
+     "EraseChars", "ExitAltCharsetMode", "ExitAttributeMode", "ExitCaMode", "ExitDeleteMode",
+     "ExitInsertMode", "ExitStandoutMode", "ExitUnderlineMode", "FlashScreen", "FormFeed",
+     "FromStatusLine", "Init1string", "Init2string", "Init3string", "InitFile", "InsertCharacter",
+     "InsertLine", "InsertPadding", "KeyBackspace", "KeyCatab", "KeyClear", "KeyCtab", "KeyDc",
+     "KeyDl", "KeyDown", "KeyEic", "KeyEol", "KeyEos", "KeyF0", "KeyF1", "KeyF10", "KeyF2", "KeyF3",
+     "KeyF4", "KeyF5", "KeyF6", "KeyF7", "KeyF8", "KeyF9", "KeyHome", "KeyIc", "KeyIl", "KeyLeft",
+     "KeyLl", "KeyNpage", "KeyPpage", "KeyRight", "KeySf", "KeySr", "KeyStab", "KeyUp",
+     "KeypadLocal", "KeypadXmit", "LabF0", "LabF1", "LabF10", "LabF2", "LabF3", "LabF4", "LabF5",
+     "LabF6", "LabF7", "LabF8", "LabF9", "MetaOff", "MetaOn", "Newline", "PadChar", "ParmDch",
+     "ParmDeleteLine", "ParmDownCursor", "ParmIch", "ParmIndex", "ParmInsertLine", "ParmLeftCursor",
+     "ParmRightCursor", "ParmRindex", "ParmUpCursor", "PkeyKey", "PkeyLocal", "PkeyXmit",
+     "PrintScreen", "PrtrOff", "PrtrOn", "RepeatChar", "Reset1string", "Reset2string",
+     "Reset3string", "ResetFile", "RestoreCursor", "RowAddress", "SaveCursor", "ScrollForward",
+     "ScrollReverse", "SetAttributes", "SetTab", "SetWindow", "Tab", "ToStatusLine", "UnderlineChar",
+     "UpHalfLine", "InitProg", "KeyA1", "KeyA3", "KeyB2", "KeyC1", "KeyC3", "PrtrNon", "CharPadding",
+     "AcsChars", "PlabNorm", "KeyBtab", "EnterXonMode", "ExitXonMode", "EnterAmMode", "ExitAmMode",
+     "XonCharacter", "XoffCharacter", "EnaAcs", "LabelOn", "LabelOff", "KeyBeg", "KeyCancel",
+     "KeyClose", "KeyCommand", "KeyCopy", "KeyCreate", "KeyEnd", "KeyEnter", "KeyExit", "KeyFind",
+     "KeyHelp", "KeyMark", "KeyMessage", "KeyMove", "KeyNext", "KeyOpen", "KeyOptions",
+     "KeyPrevious", "KeyPrint", "KeyRedo", "KeyReference", "KeyRefresh", "KeyReplace", "KeyRestart",
+     "KeyResume", "KeySave", "KeySuspend", "KeyUndo", "KeySbeg", "KeyScancel", "KeyScommand",
+     "KeyScopy", "KeyScreate", "KeySdc", "KeySdl", "KeySelect", "KeySend", "KeySeol", "KeySexit",
+     "KeySfind", "KeyShelp", "KeyShome", "KeySic", "KeySleft", "KeySmessage", "KeySmove", "KeySnext",
+     "KeySoptions", "KeySprevious", "KeySprint", "KeySredo", "KeySreplace", "KeySright", "KeySrsume",
+     "KeySsave", "KeySsuspend", "KeySundo", "ReqForInput", "KeyF11", "KeyF12", "KeyF13", "KeyF14",
+     "KeyF15", "KeyF16", "KeyF17", "KeyF18", "KeyF19", "KeyF20", "KeyF21", "KeyF22", "KeyF23",
+     "KeyF24", "KeyF25", "KeyF26", "KeyF27", "KeyF28", "KeyF29", "KeyF30", "KeyF31", "KeyF32",
+     "KeyF33", "KeyF34", "KeyF35", "KeyF36", "KeyF37", "KeyF38", "KeyF39", "KeyF40", "KeyF41",
+     "KeyF42", "KeyF43", "KeyF44", "KeyF45", "KeyF46", "KeyF47", "KeyF48", "KeyF49", "KeyF50",
+     "KeyF51", "KeyF52", "KeyF53", "KeyF54", "KeyF55", "KeyF56", "KeyF57", "KeyF58", "KeyF59",
+     "KeyF60", "KeyF61", "KeyF62", "KeyF63", "ClrBol", "ClearMargins", "SetLeftMargin",
+     "SetRightMargin", "LabelFormat", "SetClock", "DisplayClock", "RemoveClock", "CreateWindow",
+     "GotoWindow", "Hangup", "DialPhone", "QuickDial", "Tone", "Pulse", "FlashHook", "FixedPause",
+     "WaitTone", "User0", "User1", "User2", "User3", "User4", "User5", "User6", "User7", "User8",
+     "User9", "OrigPair", "OrigColors", "InitializeColor", "InitializePair", "SetColorPair",
+     "SetForeground", "SetBackground", "ChangeCharPitch", "ChangeLinePitch", "ChangeResHorz",
+     "ChangeResVert", "DefineChar", "EnterDoublewideMode", "EnterDraftQuality", "EnterItalicsMode",
+     "EnterLeftwardMode", "EnterMicroMode", "EnterNearLetterQuality", "EnterNormalQuality",
+     "EnterShadowMode", "EnterSubscriptMode", "EnterSuperscriptMode", "EnterUpwardMode",
+     "ExitDoublewideMode", "ExitItalicsMode", "ExitLeftwardMode", "ExitMicroMode", "ExitShadowMode",
+     "ExitSubscriptMode", "ExitSuperscriptMode", "ExitUpwardMode", "MicroColumnAddress", "MicroDown",
+     "MicroLeft", "MicroRight", "MicroRowAddress", "MicroUp", "OrderOfPins", "ParmDownMicro",
+     "ParmLeftMicro", "ParmRightMicro", "ParmUpMicro", "SelectCharSet", "SetBottomMargin",
+     "SetBottomMarginParm", "SetLeftMarginParm", "SetRightMarginParm", "SetTopMargin",
+     "SetTopMarginParm", "StartBitImage", "StartCharSetDef", "StopBitImage", "StopCharSetDef",
+     "SubscriptCharacters", "SuperscriptCharacters", "TheseCauseCr", "ZeroMotion", "CharSetNames",
+     "KeyMouse", "MouseInfo", "ReqMousePos", "GetMouse", "SetAForeground", "SetABackground",
+     "PkeyPlab", "DeviceType", "CodeSetInit", "Set0DesSeq", "Set1DesSeq", "Set2DesSeq", "Set3DesSeq",
+     "SetLrMargin", "SetTbMargin", "BitImageRepeat", "BitImageNewline", "BitImageCarriageReturn",
+     "ColorNames", "DefineBitImageRegion", "EndBitImageRegion", "SetColorBand", "SetPageLength",
+     "DisplayPcChar", "EnterPcCharsetMode", "ExitPcCharsetMode", "EnterScancodeMode",
+     "ExitScancodeMode", "PcTermOptions", "ScancodeEscape", "AltScancodeEsc",
+     "EnterHorizontalHlMode", "EnterLeftHlMode", "EnterLowHlMode", "EnterRightHlMode",
+     "EnterTopHlMode", "EnterVerticalHlMode", "SetAAttributes", "SetPglenInch", "TermcapInit2",
+     "TermcapReset", "LinefeedIfNotLf", "BackspaceIfNotBs", "OtherNonFunctionKeys", "ArrowKeyMap",
+     "AcsUlcorner", "AcsLlcorner", "AcsUrcorner", "AcsLrcorner", "AcsLtee", "AcsRtee", "AcsBtee",
+     "AcsTtee", "AcsHline", "AcsVline", "AcsPlus", "MemoryLock", "MemoryUnlock", "BoxChars1" };
+
+///////////////////////////////////////////////////////////////////////////
+// senf::term::Terminfo
+
+prefix_ senf::term::Terminfo::Terminfo()
+{}
+
+prefix_ senf::term::Terminfo::Terminfo(std::string const & term)
+{
+    load(term);
+}
+
+prefix_ void senf::term::Terminfo::load(std::string const & term)
+{
+    std::string filename (findTerminfo(term));
+    std::ifstream is (filename.c_str());
+    if (!is)
+        throw InvalidTerminfoException();
+    load(is);
+}
+
+prefix_ bool senf::term::Terminfo::getFlag(properties::Boolean p)
+    const
+{
+    if (BoolVec::size_type(p) >= booleans_.size())
+        return false;
+    return booleans_[p];
+}
+
+prefix_ senf::term::Terminfo::number_t senf::term::Terminfo::getNumber(properties::Numeric p)
+    const
+{
+    if (NumberVec::size_type(p) >= numbers_.size())
+        return NoValue;
+    return numbers_[p];
+}
+
+prefix_ senf::term::Terminfo::string_t senf::term::Terminfo::getString(properties::String p)
+    const
+{
+    if (StringVec::size_type(p) >= strings_.size())
+        return 0;
+    return strings_[p];
+}
+
+ prefix_ void senf::term::Terminfo::dump(std::ostream & os)
+     const
+ {
+     os << "Terminfo entry: " << name_ << "\n";
+     os << "Booleans: " << booleans_.size() << "\n";
+     os << "Numbers: " << numbers_.size() << "\n";
+     os << "Strings: " << strings_.size() << "\n";
+     os << "String pool size: " << stringPool_.size() << "\n";
+
+     {
+         os << "Flags:\n";
+         unsigned n (0);
+         BoolVec::const_iterator i (booleans_.begin());
+         BoolVec::const_iterator const i_end (booleans_.end());
+         for (; i != i_end; ++i, ++n)
+             if (*i && n < sizeof(properties::BooleanNames)/sizeof(properties::BooleanNames[0]))
+                 os << "    " << properties::BooleanNames[n] << "\n";
+     }
+
+     {
+         os << "Numbers:\n";
+         unsigned n (0);
+         NumberVec::const_iterator i (numbers_.begin());
+         NumberVec::const_iterator const i_end (numbers_.end());
+         for (; i != i_end; ++i, ++n)
+             if (*i != NoValue 
+                 && n < sizeof(properties::NumericNames)/sizeof(properties::NumericNames[0]))
+                 os << "    " << properties::NumericNames[n] << " = " << *i << "\n";
+     }
+
+     {
+         os << "Strings:\n";
+         unsigned n (0);
+         StringVec::const_iterator i (strings_.begin());
+         StringVec::const_iterator const i_end (strings_.end());
+         for (; i != i_end; ++i, ++n)
+             if (*i && n < sizeof(properties::StringNames)/sizeof(properties::StringNames[0])) {
+                 os << "    " << std::setw(32) << properties::StringNames[n] << " = ";
+                 hexdump(*i, *i + strlen(*i), os, 32);
+             }
+     }
+
+}
+
+prefix_ std::string senf::term::Terminfo::findTerminfo(std::string const & name)
+{
+    boost::filesystem::path subdir (name.substr(0,1)); subdir /= name;
+    boost::filesystem::path tientry, tipath;
+
+    {
+        char const * tivar (::getenv("TERMINFO"));
+        if (tivar) {
+            tipath = tivar;
+            tientry = tipath / subdir;
+            if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
+        }
+    }
+
+    tipath = "/etc/terminfo";
+    tientry = tipath / subdir;
+    if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
+
+    tipath = "/lib/terminfo";
+    tientry = tipath / subdir;
+    if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
+
+    tipath = "/usr/share/terminfo";
+    tientry = tipath / subdir;
+    if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
+
+    return "";
+}
+
+namespace {
+
+    boost::uint16_t const TerminfoMagic = 0x011A;
+
+    struct TerminfoHeader {
+        boost::uint16_t magic;
+        boost::uint16_t namesSz;
+        boost::uint16_t nBooleans;
+        boost::uint16_t nNumbers;
+        boost::uint16_t nStrings;
+        boost::uint16_t stringPoolSz;
+    };
+
+}
+
+prefix_ void senf::term::Terminfo::load(std::istream & is)
+{
+    TerminfoHeader h;
+    is.read(static_cast<char*>(static_cast<void*>(&h)), sizeof(h));
+    if (h.magic != TerminfoMagic)
+        throw InvalidTerminfoException();
+
+    name_.resize(h.namesSz);
+    is.read(&(name_[0]), name_.size());
+    {
+        std::string::size_type n (name_.find('\0'));
+        if (n != std::string::npos)
+            name_.erase(n);
+    }
+
+    booleans_.resize(h.nBooleans);
+    for (BoolVec::iterator i (booleans_.begin()); i != booleans_.end(); ++i) {
+        char v;
+        is.read(&v, sizeof(v));
+        *i = v;
+    }
+    if (booleans_.size() & 1)
+        is.ignore(1u);
+    
+    numbers_.resize(h.nNumbers);
+    for (NumberVec::iterator i (numbers_.begin()); i != numbers_.end(); ++i) {
+        number_t v;
+        is.read(static_cast<char*>(static_cast<void*>(&v)), sizeof(v));
+        *i = v;
+    }
+
+    typedef std::vector<number_t> OffsetVec;
+    OffsetVec offsets;
+    offsets.resize (h.nStrings);
+    for (OffsetVec::iterator i (offsets.begin()); i != offsets.end(); ++i) {
+        number_t v;
+        is.read(static_cast<char*>(static_cast<void*>(&v)), sizeof(v));
+        *i = v;
+    }
+    
+    stringPool_.resize(h.stringPoolSz);
+    is.read(&(stringPool_[0]), stringPool_.size());
+
+    strings_.resize(offsets.size());
+    StringVec::iterator j (strings_.begin());
+    for (OffsetVec::iterator i (offsets.begin()); i != offsets.end(); ++i, ++j)
+        if (*i != NoValue)
+            *j = &(stringPool_[0]) + *i;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::term::KeyParser
+
+char const * const senf::term::KeyParser::KeyNames[] = {
+    "Esc", "Backspace", "Backtab", "Begin", "CATab", "CTab", "Cancel", "Center", "Clear",
+    "ClearToEOL", "ClearToEOS", "Close", "Command", "Copy", "Create", "Delete", "DeleteLine",
+    "Down", "DownLeft", "DownRight", "End", "Enter", "Exit", "F0", "F1", "F2", "F3", "F4", "F5",
+    "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "F19",
+    "F20", "F21", "F22", "F23", "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", "F32",
+    "F33", "F34", "F35", "F36", "F37", "F38", "F39", "F40", "F41", "F42", "F43", "F44", "F45",
+    "F46", "F47", "F48", "F49", "F50", "F51", "F52", "F53", "F54", "F55", "F56", "F57", "F58",
+    "F59", "F60", "F61", "F62", "F63", "Find", "Help", "Home", "Insert", "InsertLine", "Left",
+    "Mark", "Message", "Mouse", "Move", "Next", "Open", "Options", "PageDown", "PageUp", "Previous",
+    "Print", "Redo", "Reference", "Refresh", "Replace", "Restart", "Resume", "Right", "Save",
+    "Select", "ShiftBegin", "ShiftCancel", "ShiftCommand", "ShiftCopy", "ShiftCreate",
+    "ShiftDelete", "ShiftDeleteLine", "ShiftEnd", "ShiftClearToEOL", "ShiftExit", "ShiftFind",
+    "ShiftHelp", "ShiftHome", "ShiftInsert", "ShiftLeft", "ShiftMessage", "ShiftMove", "ShiftNext",
+    "ShiftOptions", "ShiftPrevious", "ShiftPrint", "ShiftRedo", "ShiftReplace", "ShiftResume",
+    "ShiftRight", "ShiftSave", "ShiftSuspend", "ShiftTab", "ShiftUndo", "Suspend", "Undo", "Up",
+    "UpLeft", "UpRight" };
+
+prefix_ senf::term::KeyParser::KeyParser()
+{}
+
+prefix_ senf::term::KeyParser::KeyParser(Terminfo const & ti)
+{
+    load(ti);
+}
+
+prefix_ void senf::term::KeyParser::load(Terminfo const & ti)
+{
+    static Terminfo::properties::String keyStrings [] = {
+        Terminfo::properties::KeyCommand, Terminfo::properties::KeyBackspace,
+        Terminfo::properties::KeyBtab, Terminfo::properties::KeyBeg, Terminfo::properties::KeyCatab,
+        Terminfo::properties::KeyCtab, Terminfo::properties::KeyCancel, Terminfo::properties::KeyB2,
+        Terminfo::properties::KeyClear, Terminfo::properties::KeyEol, Terminfo::properties::KeyEos,
+        Terminfo::properties::KeyClose, Terminfo::properties::KeyCommand,
+        Terminfo::properties::KeyCopy, Terminfo::properties::KeyCreate, Terminfo::properties::KeyDc,
+        Terminfo::properties::KeyDl, Terminfo::properties::KeyDown, Terminfo::properties::KeyC1,
+        Terminfo::properties::KeyC3, Terminfo::properties::KeyEnd, Terminfo::properties::KeyEnter,
+        Terminfo::properties::KeyExit, Terminfo::properties::KeyF0, Terminfo::properties::KeyF1,
+        Terminfo::properties::KeyF2, Terminfo::properties::KeyF3, Terminfo::properties::KeyF4,
+        Terminfo::properties::KeyF5, Terminfo::properties::KeyF6, Terminfo::properties::KeyF7,
+        Terminfo::properties::KeyF8, Terminfo::properties::KeyF9, Terminfo::properties::KeyF10,
+        Terminfo::properties::KeyF11, Terminfo::properties::KeyF12, Terminfo::properties::KeyF13,
+        Terminfo::properties::KeyF14, Terminfo::properties::KeyF15, Terminfo::properties::KeyF16,
+        Terminfo::properties::KeyF17, Terminfo::properties::KeyF18, Terminfo::properties::KeyF19,
+        Terminfo::properties::KeyF20, Terminfo::properties::KeyF21, Terminfo::properties::KeyF22,
+        Terminfo::properties::KeyF23, Terminfo::properties::KeyF24, Terminfo::properties::KeyF25,
+        Terminfo::properties::KeyF26, Terminfo::properties::KeyF27, Terminfo::properties::KeyF28,
+        Terminfo::properties::KeyF29, Terminfo::properties::KeyF30, Terminfo::properties::KeyF31,
+        Terminfo::properties::KeyF32, Terminfo::properties::KeyF33, Terminfo::properties::KeyF34,
+        Terminfo::properties::KeyF35, Terminfo::properties::KeyF36, Terminfo::properties::KeyF37,
+        Terminfo::properties::KeyF38, Terminfo::properties::KeyF39, Terminfo::properties::KeyF40,
+        Terminfo::properties::KeyF41, Terminfo::properties::KeyF42, Terminfo::properties::KeyF43,
+        Terminfo::properties::KeyF44, Terminfo::properties::KeyF45, Terminfo::properties::KeyF46,
+        Terminfo::properties::KeyF47, Terminfo::properties::KeyF48, Terminfo::properties::KeyF49,
+        Terminfo::properties::KeyF50, Terminfo::properties::KeyF51, Terminfo::properties::KeyF52,
+        Terminfo::properties::KeyF53, Terminfo::properties::KeyF54, Terminfo::properties::KeyF55,
+        Terminfo::properties::KeyF56, Terminfo::properties::KeyF57, Terminfo::properties::KeyF58,
+        Terminfo::properties::KeyF59, Terminfo::properties::KeyF60, Terminfo::properties::KeyF61,
+        Terminfo::properties::KeyF62, Terminfo::properties::KeyF63, Terminfo::properties::KeyFind,
+        Terminfo::properties::KeyHelp, Terminfo::properties::KeyHome, Terminfo::properties::KeyIc,
+        Terminfo::properties::KeyIl, Terminfo::properties::KeyLeft, Terminfo::properties::KeyMark,
+        Terminfo::properties::KeyMessage, Terminfo::properties::KeyMouse,
+        Terminfo::properties::KeyMove, Terminfo::properties::KeyNext, Terminfo::properties::KeyOpen,
+        Terminfo::properties::KeyOptions, Terminfo::properties::KeyNpage,
+        Terminfo::properties::KeyPpage, Terminfo::properties::KeyPrevious,
+        Terminfo::properties::KeyPrint, Terminfo::properties::KeyRedo,
+        Terminfo::properties::KeyReference, Terminfo::properties::KeyRefresh,
+        Terminfo::properties::KeyReplace, Terminfo::properties::KeyRestart,
+        Terminfo::properties::KeyResume, Terminfo::properties::KeyRight,
+        Terminfo::properties::KeySave, Terminfo::properties::KeySelect,
+        Terminfo::properties::KeySbeg, Terminfo::properties::KeyScancel,
+        Terminfo::properties::KeyScommand, Terminfo::properties::KeyScopy,
+        Terminfo::properties::KeyScreate, Terminfo::properties::KeySdc,
+        Terminfo::properties::KeySdl, Terminfo::properties::KeySend, Terminfo::properties::KeySeol,
+        Terminfo::properties::KeySexit, Terminfo::properties::KeySfind,
+        Terminfo::properties::KeyShelp, Terminfo::properties::KeyShome,
+        Terminfo::properties::KeySic, Terminfo::properties::KeySleft,
+        Terminfo::properties::KeySmessage, Terminfo::properties::KeySmove,
+        Terminfo::properties::KeySnext, Terminfo::properties::KeySoptions,
+        Terminfo::properties::KeySprevious, Terminfo::properties::KeySprint,
+        Terminfo::properties::KeySredo, Terminfo::properties::KeySreplace,
+        Terminfo::properties::KeySrsume, Terminfo::properties::KeySright,
+        Terminfo::properties::KeySsave, Terminfo::properties::KeySsuspend,
+        Terminfo::properties::KeyStab, Terminfo::properties::KeySundo,
+        Terminfo::properties::KeySuspend, Terminfo::properties::KeyUndo,
+        Terminfo::properties::KeyUp, Terminfo::properties::KeyA1, Terminfo::properties::KeyA3 };
+
+    table_.clear();
+    for (unsigned i (0); i < sizeof(keyStrings)/sizeof(keyStrings[0]); ++i) {
+        char const * key (ti.getString(keyStrings[i]));
+        if (key)
+            table_.insert(std::make_pair(key, KeyCode(i+First)));
+    }
+}
+
+prefix_ std::pair<senf::term::KeyParser::keycode_t, std::string::size_type>
+senf::term::KeyParser::lookup(std::string const & key)
+    const
+{
+    if (key.empty())
+        return std::make_pair(KeyCode(0), 0);
+
+    // There are several cases: 
+    // a) 'key' is an incomplete key sequence. In this case, 'key' will precede all completions in
+    //    the key table. The first possible completion is found by 'upper_bound'
+    // b) 'key' is a complete key sequence. This is the key sequence *preceding* the 'upper_bound'
+    // c) 'key' is a complete key sequence with additional trailing characters. In this case, 'key'
+    //    will follow the correct entry in the key table. Again, the correct key sequence is
+    //    the one preceding the 'upper_bound'
+
+    Keytable::const_iterator i (table_.upper_bound(key));
+    if (i != table_.end() && i->first.substr(0, key.size()) == key)
+        return std::make_pair(Incomplete, key.size());
+    if (i == table_.begin())
+        return std::make_pair(keycode_t(key[0]), 1);
+    --i;
+    if (key.substr(0, i->first.size()) == i->first)
+        return std::make_pair(i->second, i->first.size());
+    return std::make_pair(keycode_t(key[0]), 1);
+}
+
+prefix_ std::string senf::term::KeyParser::describe(keycode_t key)
+{
+    if (key < keycode_t(' '))
+        return "^" + std::string(1, '@' + key);
+    if (key < 256)
+        return std::string(1, char(key));
+    if (key >= keycode_t(First) && key < keycode_t(First + sizeof(KeyNames) / sizeof(KeyNames[0])))
+        return std::string(KeyNames[key-First]);
+    else
+        return "<" + boost::lexical_cast<std::string>(unsigned(key)) + ">";
+}
+
+prefix_ void senf::term::KeyParser::dump(std::ostream & os)
+    const
+{
+    os << "Keytable:\n";
+    for (Keytable::const_iterator i (table_.begin()); i != table_.end(); ++i) {
+        unsigned index (i->second - First);
+        if (index < sizeof(KeyNames)/sizeof(KeyNames[0])) {
+            std::cout << "    " << std::setw(32) << KeyNames[index] << ": ";
+            hexdump(i->first.begin(), i->first.end(), os);
+        }
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Terminfo.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:
diff --git a/Utils/Termlib/Terminfo.hh b/Utils/Termlib/Terminfo.hh
new file mode 100644 (file)
index 0000000..c34a568
--- /dev/null
@@ -0,0 +1,253 @@
+// $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 Terminfo public header */
+
+#ifndef HH_SENF_Utils_Termlib_Terminfo_
+#define HH_SENF_Utils_Termlib_Terminfo_ 1
+
+// Custom includes
+#include <string>
+#include <vector>
+#include <map>
+#include <iostream>
+#include <boost/cstdint.hpp>
+#include <boost/array.hpp>
+#include <senf/Utils/Exception.hh>
+
+//#include "Terminfo.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace term {
+
+    class Terminfo
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        enum Color {
+            Black, Red, Green, Brown, Blue, Magenta, Cyan, LightGray, DarkGray, LightRed,
+            LightGreen, Yellow, LightBlue, Pink, LightCyan, White,
+            Preserve, LastColor = Preserve };
+
+        enum Attribute {
+            Standout, Underline, Reverse, Blink, HalfBright, Bold, Invisible, Protect, AltCharset,
+            Italic, Substript, Superscript, LastAttribute };
+
+        enum { NoValue = -1 };
+
+        struct properties
+        {
+            enum Boolean {
+                AutoLeftMargin, AutoRightMargin, NoEscCtlc, CeolStandoutGlitch, EatNewlineGlitch,
+                EraseOverstrike, GenericType, HardCopy, HasMetaKey, HasStatusLine, InsertNullGlitch,
+                MemoryAbove, MemoryBelow, MoveInsertMode, MoveStandoutMode, OverStrike,
+                StatusLineEscOk, DestTabsMagicSmso, TildeGlitch, TransparentUnderline, XonXoff,
+                NeedsXonXoff, PrtrSilent, HardCursor, NonRevRmcup, NoPadChar, NonDestScrollRegion,
+                CanChange, BackColorErase, HueLightnessSaturation, ColAddrGlitch,
+                CrCancelsMicroMode, HasPrintWheel, RowAddrGlitch, SemiAutoRightMargin,
+                CpiChangesRes, LpiChangesRes, BackspacesWithBs, CrtNoScrolling,
+                NoCorrectlyWorkingCr, GnuHasMetaKey, LinefeedIsNewline, HasHardwareTabs,
+                ReturnDoesClrEol };
+            
+            static char const * const BooleanNames[];
+
+            enum Numeric {
+                Columns, InitTabs, Lines, LinesOfMemory, MagicCookieGlitch, PaddingBaudRate,
+                VirtualTerminal, WidthStatusLine, NumLabels, LabelHeight, LabelWidth, MaxAttributes,
+                MaximumWindows, MaxColors, MaxPairs, NoColorVideo, BufferCapacity, DotVertSpacing,
+                DotHorzSpacing, MaxMicroAddress, MaxMicroJump, MicroColSize, MicroLineSize,
+                NumberOfPins, OutputResChar, OutputResLine, OutputResHorzInch, OutputResVertInch,
+                PrintRate, WideCharSize, Buttons, BitImageEntwining, BitImageType,
+                MagicCookieGlitchUl, CarriageReturnDelay, NewLineDelay, BackspaceDelay,
+                HorizontalTabDelay, NumberOfFunctionKeys };
+
+            static char const * const NumericNames[];
+            
+            enum String {
+                BackTab, Bell, CarriageReturn, ChangeScrollRegion, ClearAllTabs, ClearScreen,
+                ClrEol, ClrEos, ColumnAddress, CommandCharacter, CursorAddress, CursorDown,
+                CursorHome, CursorInvisible, CursorLeft, CursorMemAddress, CursorNormal,
+                CursorRight, CursorToLl, CursorUp, CursorVisible, DeleteCharacter, DeleteLine,
+                DisStatusLine, DownHalfLine, EnterAltCharsetMode, EnterBlinkMode, EnterBoldMode,
+                EnterCaMode, EnterDeleteMode, EnterDimMode, EnterInsertMode, EnterSecureMode,
+                EnterProtectedMode, EnterReverseMode, EnterStandoutMode, EnterUnderlineMode,
+                EraseChars, ExitAltCharsetMode, ExitAttributeMode, ExitCaMode, ExitDeleteMode,
+                ExitInsertMode, ExitStandoutMode, ExitUnderlineMode, FlashScreen, FormFeed,
+                FromStatusLine, Init1string, Init2string, Init3string, InitFile, InsertCharacter,
+                InsertLine, InsertPadding, KeyBackspace, KeyCatab, KeyClear, KeyCtab, KeyDc, KeyDl,
+                KeyDown, KeyEic, KeyEol, KeyEos, KeyF0, KeyF1, KeyF10, KeyF2, KeyF3, KeyF4, KeyF5,
+                KeyF6, KeyF7, KeyF8, KeyF9, KeyHome, KeyIc, KeyIl, KeyLeft, KeyLl, KeyNpage,
+                KeyPpage, KeyRight, KeySf, KeySr, KeyStab, KeyUp, KeypadLocal, KeypadXmit, LabF0,
+                LabF1, LabF10, LabF2, LabF3, LabF4, LabF5, LabF6, LabF7, LabF8, LabF9, MetaOff,
+                MetaOn, Newline, PadChar, ParmDch, ParmDeleteLine, ParmDownCursor, ParmIch,
+                ParmIndex, ParmInsertLine, ParmLeftCursor, ParmRightCursor, ParmRindex,
+                ParmUpCursor, PkeyKey, PkeyLocal, PkeyXmit, PrintScreen, PrtrOff, PrtrOn,
+                RepeatChar, Reset1string, Reset2string, Reset3string, ResetFile, RestoreCursor,
+                RowAddress, SaveCursor, ScrollForward, ScrollReverse, SetAttributes, SetTab,
+                SetWindow, Tab, ToStatusLine, UnderlineChar, UpHalfLine, InitProg, KeyA1, KeyA3,
+                KeyB2, KeyC1, KeyC3, PrtrNon, CharPadding, AcsChars, PlabNorm, KeyBtab,
+                EnterXonMode, ExitXonMode, EnterAmMode, ExitAmMode, XonCharacter, XoffCharacter,
+                EnaAcs, LabelOn, LabelOff, KeyBeg, KeyCancel, KeyClose, KeyCommand, KeyCopy,
+                KeyCreate, KeyEnd, KeyEnter, KeyExit, KeyFind, KeyHelp, KeyMark, KeyMessage,
+                KeyMove, KeyNext, KeyOpen, KeyOptions, KeyPrevious, KeyPrint, KeyRedo, KeyReference,
+                KeyRefresh, KeyReplace, KeyRestart, KeyResume, KeySave, KeySuspend, KeyUndo,
+                KeySbeg, KeyScancel, KeyScommand, KeyScopy, KeyScreate, KeySdc, KeySdl, KeySelect,
+                KeySend, KeySeol, KeySexit, KeySfind, KeyShelp, KeyShome, KeySic, KeySleft,
+                KeySmessage, KeySmove, KeySnext, KeySoptions, KeySprevious, KeySprint, KeySredo,
+                KeySreplace, KeySright, KeySrsume, KeySsave, KeySsuspend, KeySundo, ReqForInput,
+                KeyF11, KeyF12, KeyF13, KeyF14, KeyF15, KeyF16, KeyF17, KeyF18, KeyF19, KeyF20,
+                KeyF21, KeyF22, KeyF23, KeyF24, KeyF25, KeyF26, KeyF27, KeyF28, KeyF29, KeyF30,
+                KeyF31, KeyF32, KeyF33, KeyF34, KeyF35, KeyF36, KeyF37, KeyF38, KeyF39, KeyF40,
+                KeyF41, KeyF42, KeyF43, KeyF44, KeyF45, KeyF46, KeyF47, KeyF48, KeyF49, KeyF50,
+                KeyF51, KeyF52, KeyF53, KeyF54, KeyF55, KeyF56, KeyF57, KeyF58, KeyF59, KeyF60,
+                KeyF61, KeyF62, KeyF63, ClrBol, ClearMargins, SetLeftMargin, SetRightMargin,
+                LabelFormat, SetClock, DisplayClock, RemoveClock, CreateWindow, GotoWindow, Hangup,
+                DialPhone, QuickDial, Tone, Pulse, FlashHook, FixedPause, WaitTone, User0, User1,
+                User2, User3, User4, User5, User6, User7, User8, User9, OrigPair, OrigColors,
+                InitializeColor, InitializePair, SetColorPair, SetForeground, SetBackground,
+                ChangeCharPitch, ChangeLinePitch, ChangeResHorz, ChangeResVert, DefineChar,
+                EnterDoublewideMode, EnterDraftQuality, EnterItalicsMode, EnterLeftwardMode,
+                EnterMicroMode, EnterNearLetterQuality, EnterNormalQuality, EnterShadowMode,
+                EnterSubscriptMode, EnterSuperscriptMode, EnterUpwardMode, ExitDoublewideMode,
+                ExitItalicsMode, ExitLeftwardMode, ExitMicroMode, ExitShadowMode, ExitSubscriptMode,
+                ExitSuperscriptMode, ExitUpwardMode, MicroColumnAddress, MicroDown, MicroLeft,
+                MicroRight, MicroRowAddress, MicroUp, OrderOfPins, ParmDownMicro, ParmLeftMicro,
+                ParmRightMicro, ParmUpMicro, SelectCharSet, SetBottomMargin, SetBottomMarginParm,
+                SetLeftMarginParm, SetRightMarginParm, SetTopMargin, SetTopMarginParm,
+                StartBitImage, StartCharSetDef, StopBitImage, StopCharSetDef, SubscriptCharacters,
+                SuperscriptCharacters, TheseCauseCr, ZeroMotion, CharSetNames, KeyMouse, MouseInfo,
+                ReqMousePos, GetMouse, SetAForeground, SetABackground, PkeyPlab, DeviceType,
+                CodeSetInit, Set0DesSeq, Set1DesSeq, Set2DesSeq, Set3DesSeq, SetLrMargin,
+                SetTbMargin, BitImageRepeat, BitImageNewline, BitImageCarriageReturn, ColorNames,
+                DefineBitImageRegion, EndBitImageRegion, SetColorBand, SetPageLength, DisplayPcChar,
+                EnterPcCharsetMode, ExitPcCharsetMode, EnterScancodeMode, ExitScancodeMode,
+                PcTermOptions, ScancodeEscape, AltScancodeEsc, EnterHorizontalHlMode,
+                EnterLeftHlMode, EnterLowHlMode, EnterRightHlMode, EnterTopHlMode,
+                EnterVerticalHlMode, SetAAttributes, SetPglenInch, TermcapInit2, TermcapReset,
+                LinefeedIfNotLf, BackspaceIfNotBs, OtherNonFunctionKeys, ArrowKeyMap, AcsUlcorner,
+                AcsLlcorner, AcsUrcorner, AcsLrcorner, AcsLtee, AcsRtee, AcsBtee, AcsTtee, AcsHline,
+                AcsVline, AcsPlus, MemoryLock, MemoryUnlock, BoxChars1 };
+
+            static char const * const StringNames[];
+        };
+
+        typedef boost::int16_t number_t;
+        typedef char const* string_t;
+
+        ///////////////////////////////////////////////////////////////////////////
+        
+        Terminfo();
+        explicit Terminfo(std::string const & term);
+        void load(std::string const & term);
+        
+        bool getFlag(properties::Boolean p) const;
+        number_t getNumber(properties::Numeric p) const;
+        string_t getString(properties::String p) const;
+
+        void dump(std::ostream & os) const;
+
+        struct InvalidTerminfoException : public senf::Exception
+        { InvalidTerminfoException() : senf::Exception("Unreadable terminfo file") {} };
+
+    private:
+        typedef std::vector<bool> BoolVec;
+        typedef std::vector<number_t> NumberVec;
+        typedef std::vector<string_t> StringVec;
+        typedef std::vector<char> StringPool;
+
+        std::string findTerminfo(std::string const & name);
+        void load(std::istream & is);
+
+        std::string name_;
+        BoolVec booleans_;
+        NumberVec numbers_;
+        StringVec strings_;
+        StringPool stringPool_;
+    };
+
+
+    class KeyParser
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        enum KeyCode {
+            Space = ' ', Tab = '\t', First = 0xE000, Esc = First, Backspace, Backtab, Begin, CATab,
+            CTab, Cancel, Center, Clear, ClearToEOL, ClearToEOS, Close, Command, Copy, Create,
+            Delete, DeleteLine, Down, DownLeft, DownRight, End, Enter, Exit, F0, F1, F2, F3, F4, F5,
+            F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23,
+            F24, F25, F26, F27, F28, F29, F30, F31, F32, F33, F34, F35, F36, F37, F38, F39, F40,
+            F41, F42, F43, F44, F45, F46, F47, F48, F49, F50, F51, F52, F53, F54, F55, F56, F57,
+            F58, F59, F60, F61, F62, F63, Find, Help, Home, Insert, InsertLine, Left, Mark, Message,
+            Mouse, Move, Next, Open, Options, PageDown, PageUp, Previous, Print, Redo, Reference,
+            Refresh, Replace, Restart, Resume, Right, Save, Select, ShiftBegin, ShiftCancel,
+            ShiftCommand, ShiftCopy, ShiftCreate, ShiftDelete, ShiftDeleteLine, ShiftEnd,
+            ShiftClearToEOL, ShiftExit, ShiftFind, ShiftHelp, ShiftHome, ShiftInsert, ShiftLeft,
+            ShiftMessage, ShiftMove, ShiftNext, ShiftOptions, ShiftPrevious, ShiftPrint, ShiftRedo,
+            ShiftReplace, ShiftResume, ShiftRight, ShiftSave, ShiftSuspend, ShiftTab, ShiftUndo,
+            Suspend, Undo, Up, UpLeft, UpRight, Incomplete = 0xE0FF };
+
+        static char const * const KeyNames[];
+
+        typedef wchar_t keycode_t;
+        typedef std::string::size_type size_type;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        KeyParser();
+        explicit KeyParser(Terminfo const & ti);
+        void load(Terminfo const & ti);
+
+        std::pair<keycode_t, size_type> lookup(std::string const & key) const;
+        static std::string describe(keycode_t key);
+
+        void dump(std::ostream & os) const;
+
+    private:
+        typedef std::map<std::string, KeyCode> Keytable;
+
+        Keytable table_;
+    };
+        
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Terminfo.cci"
+//#include "Terminfo.ct"
+//#include "Terminfo.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:
diff --git a/Utils/Termlib/Terminfo.test.cc b/Utils/Termlib/Terminfo.test.cc
new file mode 100644 (file)
index 0000000..8ef55b3
--- /dev/null
@@ -0,0 +1,91 @@
+// $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 Terminfo.test unit tests */
+
+//#include "Terminfo.test.hh"
+//#include "Terminfo.test.ih"
+
+// Custom includes
+#include "Terminfo.hh"
+
+#include "../../Utils/auto_unit_test.hh"
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    typedef std::pair<senf::term::KeyParser::keycode_t, senf::term::KeyParser::size_type> Pair;
+}
+
+namespace std {
+
+    std::ostream & operator<<(std::ostream & os, Pair const & pair)
+    {
+        os << '(' << pair.first << ',' << pair.second << ')';
+        return os;
+    }
+}
+
+BOOST_AUTO_UNIT_TEST(terminfo)
+{
+    senf::term::Terminfo ifo ("vt220");
+    senf::term::KeyParser kp (ifo);
+
+    //ifo.dump(std::cout);
+    //kp.dump(std::cout);
+
+    BOOST_CHECK_EQUAL( kp.lookup("\e[5\x7e"), 
+                       Pair(senf::term::KeyParser::PageUp, 4u) );
+    BOOST_CHECK_EQUAL( kp.lookup("\e"),
+                       Pair(senf::term::KeyParser::Incomplete, 1u) );
+    BOOST_CHECK_EQUAL( kp.lookup("\e["),
+                       Pair(senf::term::KeyParser::Incomplete, 2u) );
+    BOOST_CHECK_EQUAL( kp.lookup("\e[A"),
+                       Pair(senf::term::KeyParser::Up, 3u) );
+    BOOST_CHECK_EQUAL( kp.lookup("\e[\e"),
+                       Pair(senf::term::KeyParser::keycode_t('\e'), 1u) );
+    BOOST_CHECK_EQUAL( kp.lookup("a\e[Ab"),
+                       Pair(senf::term::KeyParser::keycode_t('a'), 1u) );
+    BOOST_CHECK_EQUAL( kp.lookup("\e[Ab"),
+                       Pair(senf::term::KeyParser::Up, 3u) );
+    BOOST_CHECK_EQUAL( kp.lookup("b"),
+                       Pair(senf::term::KeyParser::keycode_t('b'), 1u) );
+    BOOST_CHECK_EQUAL( kp.lookup(""),
+                       Pair(senf::term::KeyParser::keycode_t('\0'), 0u) );
+}
+
+///////////////////////////////cc.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:
similarity index 88%
rename from Utils/Console/Telnet.test.cc
rename to Utils/Termlib/main.test.cc
index 124897d..c6b4f24 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2008 
+// Copyright (C) 2006
 // Fraunhofer Institute for Open Communication Systems (FOKUS)
 // Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-/** \file
-    \brief Telnet.test unit tests */
+// Definition of non-inline non-template functions
 
-//#include "Telnet.test.hh"
-//#include "Telnet.test.ih"
+//#include "test.hh"
+//#include "test.ih"
 
 // Custom includes
-#include "Telnet.hh"
-
+#define BOOST_AUTO_TEST_MAIN
 #include "../../Utils/auto_unit_test.hh"
 #include <boost/test/test_tools.hpp>
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-BOOST_AUTO_UNIT_TEST(telnet)
-{}
 
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
@@ -45,9 +41,9 @@ BOOST_AUTO_UNIT_TEST(telnet)
 // 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"
+// comment-column: 40
 // End:
similarity index 81%
rename from Utils/Console/telnetServer.cc
rename to Utils/Termlib/telnetServer.cc
index 95f290c..da4c15a 100644 (file)
@@ -28,7 +28,7 @@
 
 // Custom includes
 #include <boost/bind.hpp>
-#include "Telnet.hh"
+#include "TelnetTerminal.hh"
 #include "../../Scheduler/Scheduler.hh"
 #include "../Logger.hh"
 #include "../../Socket/Protocols/INet.hh"
 
 namespace {
 
-    class MyTelnet 
-        : public virtual senf::console::detail::BaseTelnetProtocol,
-          public senf::console::detail::telnethandler::TerminalType,
-          public senf::console::detail::telnethandler::NAWS
+    class MyTelnet : public senf::term::TelnetTerminal
     {
     public:
-        explicit MyTelnet(Handle handle) : senf::console::detail::BaseTelnetProtocol(handle) 
-            {
-                requestPeerOption(senf::console::detail::telnetopt::SUPPRESS_GO_AHEAD);
-                requestLocalOption(senf::console::detail::telnetopt::SUPPRESS_GO_AHEAD);
-                requestLocalOption(senf::console::detail::telnetopt::ECHO);
-            }
+        explicit MyTelnet(Handle handle) : senf::term::BaseTelnetProtocol(handle) {}
         
     private:
-        virtual void v_charReceived(char c)
+        virtual void v_keyReceived(keycode_t key)
             {
-                SENF_LOG(("Char: " << c));
+                SENF_LOG(("Key " << senf::term::KeyParser::describe(key)));
             }
 
         virtual void v_eof()
@@ -66,6 +58,7 @@ namespace {
 
         virtual void v_setupComplete()
             {
+                TelnetTerminal::v_setupComplete();
                 SENF_LOG(("Terminal type is '" << terminalType() << "', window size is "
                           << width() << "x" << height()));
             }
index 9f08553..3cf9b73 100644 (file)
@@ -33,7 +33,7 @@
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-prefix_ void senf::detail::HexDumper::operator()(unsigned ch)
+prefix_ void senf::detail::HexDumper::operator()(unsigned char ch)
 {
     if ((offset_ % block_size_) == 0) {
         if (!ascii_.empty()) {
@@ -48,7 +48,7 @@ prefix_ void senf::detail::HexDumper::operator()(unsigned ch)
         ascii_ += ' ';
     }
     os_ << ' ' << std::hex << std::setw(2) << std::setfill('0')
-           << ch;
+        << unsigned(ch);
     ascii_ += (ch >= ' ' && ch < 126) ? ch : '.';
     ++ offset_;
 }
index c03f51b..0acf34a 100644 (file)
@@ -45,7 +45,7 @@ namespace detail {
         HexDumper(std::ostream & os, unsigned block_size);
         ~HexDumper();
 
-        void operator()(unsigned ch);
+        void operator()(unsigned char ch);
 
     private:
         std::ostream & os_;